/*
 * Mac clipboard driver
 *
 * Copyright 1994 Martin Ayotte
 *           1996 Alex Korobka
 *           1999 Noel Borthwick
 *           2003 Ulrich Czekalla for CodeWeavers
 * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
 *
 * 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
 */

#include "config.h"

#include "macdrv.h"
#include "winuser.h"
#include "shellapi.h"
#include "shlobj.h"
#include "wine/list.h"
#include "wine/server.h"
#include "wine/unicode.h"


WINE_DEFAULT_DEBUG_CHANNEL(clipboard);


/**************************************************************************
 *              Types
 **************************************************************************/

typedef HANDLE (*DRVIMPORTFUNC)(CFDataRef data);
typedef CFDataRef (*DRVEXPORTFUNC)(HANDLE data);

typedef struct _WINE_CLIPFORMAT
{
    struct list             entry;
    UINT                    format_id;
    CFStringRef             type;
    DRVIMPORTFUNC           import_func;
    DRVEXPORTFUNC           export_func;
    BOOL                    synthesized;
    struct _WINE_CLIPFORMAT *natural_format;
} WINE_CLIPFORMAT;


/**************************************************************************
 *              Constants
 **************************************************************************/

#define CLIPBOARD_UPDATE_DELAY 2000   /* delay between checks of the Mac pasteboard */


/**************************************************************************
 *              Forward Function Declarations
 **************************************************************************/

static HANDLE import_clipboard_data(CFDataRef data);
static HANDLE import_bmp_to_bitmap(CFDataRef data);
static HANDLE import_bmp_to_dib(CFDataRef data);
static HANDLE import_enhmetafile(CFDataRef data);
static HANDLE import_html(CFDataRef data);
static HANDLE import_metafilepict(CFDataRef data);
static HANDLE import_nsfilenames_to_hdrop(CFDataRef data);
static HANDLE import_utf8_to_text(CFDataRef data);
static HANDLE import_utf8_to_unicodetext(CFDataRef data);
static HANDLE import_utf16_to_unicodetext(CFDataRef data);

static CFDataRef export_clipboard_data(HANDLE data);
static CFDataRef export_bitmap_to_bmp(HANDLE data);
static CFDataRef export_dib_to_bmp(HANDLE data);
static CFDataRef export_enhmetafile(HANDLE data);
static CFDataRef export_hdrop_to_filenames(HANDLE data);
static CFDataRef export_html(HANDLE data);
static CFDataRef export_metafilepict(HANDLE data);
static CFDataRef export_text_to_utf8(HANDLE data);
static CFDataRef export_unicodetext_to_utf8(HANDLE data);
static CFDataRef export_unicodetext_to_utf16(HANDLE data);


/**************************************************************************
 *              Static Variables
 **************************************************************************/

/* Clipboard formats */
static struct list format_list = LIST_INIT(format_list);

/*  There are two naming schemes involved and we want to have a mapping between
    them.  There are Win32 clipboard format names and there are Mac pasteboard
    types.

    The Win32 standard clipboard formats don't have names, but they are associated
    with Mac pasteboard types through the following tables, which are used to
    initialize the format_list.  Where possible, the standard clipboard formats
    are mapped to predefined pasteboard type UTIs.  Otherwise, we create Wine-
    specific types of the form "org.winehq.builtin.<format>", where <format> is
    the name of the symbolic constant for the format minus "CF_" and lowercased.
    E.g. CF_BITMAP -> org.winehq.builtin.bitmap.

    Win32 clipboard formats which originate in a Windows program may be registered
    with an arbitrary name.  We construct a Mac pasteboard type from these by
    prepending "org.winehq.registered." to the registered name.

    Likewise, Mac pasteboard types which originate in other apps may have
    arbitrary type strings.  We ignore these.

    Summary:
    Win32 clipboard format names:
        <none>                              standard clipboard format; maps via
                                            format_list to either a predefined Mac UTI
                                            or org.winehq.builtin.<format>.
        <other>                             name registered within Win32 land; maps to
                                            org.winehq.registered.<other>
    Mac pasteboard type names:
        org.winehq.builtin.<format ID>      representation of Win32 standard clipboard
                                            format for which there was no corresponding
                                            predefined Mac UTI; maps via format_list
        org.winehq.registered.<format name> representation of Win32 registered
                                            clipboard format name; maps to <format name>
        <other>                             Mac pasteboard type originating with system
                                            or other apps; either maps via format_list
                                            to a standard clipboard format or ignored
*/

static const struct
{
    UINT          id;
    CFStringRef   type;
    DRVIMPORTFUNC import;
    DRVEXPORTFUNC export;
    BOOL          synthesized;
} builtin_format_ids[] =
{
    { CF_BITMAP,            CFSTR("org.winehq.builtin.bitmap"),             import_bmp_to_bitmap,           export_bitmap_to_bmp,       FALSE },
    { CF_DIBV5,             CFSTR("org.winehq.builtin.dibv5"),              import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_DIF,               CFSTR("org.winehq.builtin.dif"),                import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_ENHMETAFILE,       CFSTR("org.winehq.builtin.enhmetafile"),        import_enhmetafile,             export_enhmetafile,         FALSE },
    { CF_LOCALE,            CFSTR("org.winehq.builtin.locale"),             import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_METAFILEPICT,      CFSTR("org.winehq.builtin.metafilepict"),       import_metafilepict,            export_metafilepict,        FALSE },
    { CF_OEMTEXT,           CFSTR("org.winehq.builtin.oemtext"),            import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_PALETTE,           CFSTR("org.winehq.builtin.palette"),            import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_PENDATA,           CFSTR("org.winehq.builtin.pendata"),            import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_RIFF,              CFSTR("org.winehq.builtin.riff"),               import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_SYLK,              CFSTR("org.winehq.builtin.sylk"),               import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_TEXT,              CFSTR("org.winehq.builtin.text"),               import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_TIFF,              CFSTR("public.tiff"),                           import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_WAVE,              CFSTR("com.microsoft.waveform-audio"),          import_clipboard_data,          export_clipboard_data,      FALSE },

    { CF_DIB,               CFSTR("org.winehq.builtin.dib"),                import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_DIB,               CFSTR("com.microsoft.bmp"),                     import_bmp_to_dib,              export_dib_to_bmp,          TRUE },

    { CF_HDROP,             CFSTR("org.winehq.builtin.hdrop"),              import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_HDROP,             CFSTR("NSFilenamesPboardType"),                 import_nsfilenames_to_hdrop,    export_hdrop_to_filenames,  TRUE },

    { CF_UNICODETEXT,       CFSTR("org.winehq.builtin.unicodetext"),        import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_UNICODETEXT,       CFSTR("public.utf16-plain-text"),               import_utf16_to_unicodetext,    export_unicodetext_to_utf16,TRUE },
    { CF_UNICODETEXT,       CFSTR("public.utf8-plain-text"),                import_utf8_to_unicodetext,     export_unicodetext_to_utf8, TRUE },
};

static const WCHAR wszRichTextFormat[] = {'R','i','c','h',' ','T','e','x','t',' ','F','o','r','m','a','t',0};
static const WCHAR wszGIF[] = {'G','I','F',0};
static const WCHAR wszJFIF[] = {'J','F','I','F',0};
static const WCHAR wszPNG[] = {'P','N','G',0};
static const WCHAR wszHTMLFormat[] = {'H','T','M','L',' ','F','o','r','m','a','t',0};
static const struct
{
    LPCWSTR       name;
    CFStringRef   type;
    DRVIMPORTFUNC import;
    DRVEXPORTFUNC export;
    BOOL          synthesized;
} builtin_format_names[] =
{
    { wszRichTextFormat,    CFSTR("public.rtf"),                            import_clipboard_data,          export_clipboard_data },
    { wszGIF,               CFSTR("com.compuserve.gif"),                    import_clipboard_data,          export_clipboard_data },
    { wszJFIF,              CFSTR("public.jpeg"),                           import_clipboard_data,          export_clipboard_data },
    { wszPNG,               CFSTR("public.png"),                            import_clipboard_data,          export_clipboard_data },
    { wszHTMLFormat,        NULL,                                           import_clipboard_data,          export_clipboard_data },
    { wszHTMLFormat,        CFSTR("public.html"),                           import_html,                    export_html,            TRUE },
    { CFSTR_SHELLURLW,      CFSTR("public.url"),                            import_utf8_to_text,            export_text_to_utf8 },
};

/* The prefix prepended to a Win32 clipboard format name to make a Mac pasteboard type. */
static const CFStringRef registered_name_type_prefix = CFSTR("org.winehq.registered.");

static DWORD clipboard_thread_id;
static HWND clipboard_hwnd;
static BOOL is_clipboard_owner;
static macdrv_window clipboard_cocoa_window;
static UINT rendered_formats;
static ULONG64 last_clipboard_update;
static DWORD last_get_seqno;
static WINE_CLIPFORMAT **current_mac_formats;
static unsigned int nb_current_mac_formats;
static WCHAR clipboard_pipe_name[256];


/**************************************************************************
 *              Internal Clipboard implementation methods
 **************************************************************************/

/*
 * format_list functions
 */

/**************************************************************************
 *              debugstr_format
 */
const char *debugstr_format(UINT id)
{
    WCHAR buffer[256];

    if (GetClipboardFormatNameW(id, buffer, 256))
        return wine_dbg_sprintf("0x%04x %s", id, debugstr_w(buffer));

    switch (id)
    {
#define BUILTIN(id) case id: return #id;
    BUILTIN(CF_TEXT)
    BUILTIN(CF_BITMAP)
    BUILTIN(CF_METAFILEPICT)
    BUILTIN(CF_SYLK)
    BUILTIN(CF_DIF)
    BUILTIN(CF_TIFF)
    BUILTIN(CF_OEMTEXT)
    BUILTIN(CF_DIB)
    BUILTIN(CF_PALETTE)
    BUILTIN(CF_PENDATA)
    BUILTIN(CF_RIFF)
    BUILTIN(CF_WAVE)
    BUILTIN(CF_UNICODETEXT)
    BUILTIN(CF_ENHMETAFILE)
    BUILTIN(CF_HDROP)
    BUILTIN(CF_LOCALE)
    BUILTIN(CF_DIBV5)
    BUILTIN(CF_OWNERDISPLAY)
    BUILTIN(CF_DSPTEXT)
    BUILTIN(CF_DSPBITMAP)
    BUILTIN(CF_DSPMETAFILEPICT)
    BUILTIN(CF_DSPENHMETAFILE)
#undef BUILTIN
    default: return wine_dbg_sprintf("0x%04x", id);
    }
}


/**************************************************************************
 *              insert_clipboard_format
 */
static WINE_CLIPFORMAT *insert_clipboard_format(UINT id, CFStringRef type)
{
    WINE_CLIPFORMAT *format;

    format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format));

    if (format == NULL)
    {
        WARN("No more memory for a new format!\n");
        return NULL;
    }
    format->format_id = id;
    format->import_func = import_clipboard_data;
    format->export_func = export_clipboard_data;
    format->synthesized = FALSE;
    format->natural_format = NULL;

    if (type)
        format->type = CFStringCreateCopy(NULL, type);
    else
    {
        WCHAR buffer[256];

        if (!GetClipboardFormatNameW(format->format_id, buffer, sizeof(buffer) / sizeof(buffer[0])))
        {
            WARN("failed to get name for format %s; error 0x%08x\n", debugstr_format(format->format_id), GetLastError());
            HeapFree(GetProcessHeap(), 0, format);
            return NULL;
        }

        format->type = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%S"),
                                                registered_name_type_prefix, buffer);
    }

    list_add_tail(&format_list, &format->entry);

    TRACE("Registering format %s type %s\n", debugstr_format(format->format_id),
          debugstr_cf(format->type));

    return format;
}


/**************************************************************************
 *              register_format
 *
 * Register a custom Mac clipboard format.
 */
static WINE_CLIPFORMAT* register_format(UINT id, CFStringRef type)
{
    WINE_CLIPFORMAT *format;

    /* walk format chain to see if it's already registered */
    LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
        if (format->format_id == id) return format;

    return insert_clipboard_format(id, type);
}


/**************************************************************************
 *              natural_format_for_format
 *
 * Find the "natural" format for this format_id (the one which isn't
 * synthesized from another type).
 */
static WINE_CLIPFORMAT* natural_format_for_format(UINT format_id)
{
    WINE_CLIPFORMAT *format;

    LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
        if (format->format_id == format_id && !format->synthesized) break;

    if (&format->entry == &format_list)
        format = NULL;

    TRACE("%s -> %p/%s\n", debugstr_format(format_id), format, debugstr_cf(format ? format->type : NULL));
    return format;
}


/**************************************************************************
 *              register_builtin_formats
 */
static void register_builtin_formats(void)
{
    UINT i;
    WINE_CLIPFORMAT *format;

    /* Register built-in formats */
    for (i = 0; i < sizeof(builtin_format_ids)/sizeof(builtin_format_ids[0]); i++)
    {
        if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break;
        format->format_id       = builtin_format_ids[i].id;
        format->type            = CFRetain(builtin_format_ids[i].type);
        format->import_func     = builtin_format_ids[i].import;
        format->export_func     = builtin_format_ids[i].export;
        format->synthesized     = builtin_format_ids[i].synthesized;
        format->natural_format  = NULL;
        list_add_tail(&format_list, &format->entry);
    }

    /* Register known mappings between Windows formats and Mac types */
    for (i = 0; i < sizeof(builtin_format_names)/sizeof(builtin_format_names[0]); i++)
    {
        if (!(format = HeapAlloc(GetProcessHeap(), 0, sizeof(*format)))) break;
        format->format_id       = RegisterClipboardFormatW(builtin_format_names[i].name);
        format->import_func     = builtin_format_names[i].import;
        format->export_func     = builtin_format_names[i].export;
        format->synthesized     = builtin_format_names[i].synthesized;
        format->natural_format  = NULL;

        if (builtin_format_names[i].type)
            format->type = CFRetain(builtin_format_names[i].type);
        else
        {
            format->type = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%S"),
                                                    registered_name_type_prefix, builtin_format_names[i].name);
        }

        list_add_tail(&format_list, &format->entry);
    }

    LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
    {
        if (format->synthesized)
            format->natural_format = natural_format_for_format(format->format_id);
    }
}


/**************************************************************************
 *              format_for_type
 */
static WINE_CLIPFORMAT* format_for_type(CFStringRef type)
{
    WINE_CLIPFORMAT *format;

    TRACE("type %s\n", debugstr_cf(type));

    if (list_empty(&format_list)) register_builtin_formats();

    LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
    {
        if (CFEqual(format->type, type))
            goto done;
    }

    format = NULL;
    if (CFStringHasPrefix(type, CFSTR("org.winehq.builtin.")))
    {
        ERR("Shouldn't happen. Built-in type %s should have matched something in format list.\n",
            debugstr_cf(type));
    }
    else if (CFStringHasPrefix(type, registered_name_type_prefix))
    {
        LPWSTR name;
        int len = CFStringGetLength(type) - CFStringGetLength(registered_name_type_prefix);

        name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
        CFStringGetCharacters(type, CFRangeMake(CFStringGetLength(registered_name_type_prefix), len),
                              (UniChar*)name);
        name[len] = 0;

        format = register_format(RegisterClipboardFormatW(name), type);
        if (!format)
            ERR("Failed to register format for type %s name %s\n", debugstr_cf(type), debugstr_w(name));

        HeapFree(GetProcessHeap(), 0, name);
    }

done:
    TRACE(" -> %p/%s\n", format, debugstr_format(format ? format->format_id : 0));
    return format;
}


/***********************************************************************
 *              bitmap_info_size
 *
 * Return the size of the bitmap info structure including color table.
 */
static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse)
{
    unsigned int colors, size, masks = 0;

    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
    {
        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER*)info;
        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
        return sizeof(BITMAPCOREHEADER) + colors *
             ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
    }
    else  /* assume BITMAPINFOHEADER */
    {
        colors = min(info->bmiHeader.biClrUsed, 256);
        if (!colors && (info->bmiHeader.biBitCount <= 8))
            colors = 1 << info->bmiHeader.biBitCount;
        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
        size = max(info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD));
        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
    }
}


/***********************************************************************
 *              create_dib_from_bitmap
 *
 * Allocates a packed DIB and copies the bitmap data into it.
 */
static HGLOBAL create_dib_from_bitmap(HBITMAP bitmap)
{
    HANDLE ret = 0;
    BITMAPINFOHEADER header;
    HDC hdc = GetDC(0);
    DWORD header_size;
    BITMAPINFO *bmi;

    memset(&header, 0, sizeof(header));
    header.biSize = sizeof(header);
    if (!GetDIBits(hdc, bitmap, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS)) goto done;

    header_size = bitmap_info_size((BITMAPINFO *)&header, DIB_RGB_COLORS);
    if (!(ret = GlobalAlloc(GMEM_FIXED, header_size + header.biSizeImage))) goto done;
    bmi = (BITMAPINFO *)ret;
    memset(bmi, 0, header_size);
    memcpy(bmi, &header, header.biSize);
    GetDIBits(hdc, bitmap, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS);

done:
    ReleaseDC(0, hdc);
    return ret;
}


/**************************************************************************
 *              create_bitmap_from_dib
 *
 *  Given a packed DIB, creates a bitmap object from it.
 */
static HANDLE create_bitmap_from_dib(HANDLE dib)
{
    HANDLE ret = 0;
    BITMAPINFO *bmi;

    if (dib && (bmi = GlobalLock(dib)))
    {
        HDC hdc;
        unsigned int offset;

        hdc = GetDC(NULL);

        offset = bitmap_info_size(bmi, DIB_RGB_COLORS);

        ret = CreateDIBitmap(hdc, &bmi->bmiHeader, CBM_INIT, (LPBYTE)bmi + offset,
                             bmi, DIB_RGB_COLORS);

        GlobalUnlock(dib);
        ReleaseDC(NULL, hdc);
    }

    return ret;
}


/**************************************************************************
 *		get_html_description_field
 *
 *  Find the value of a field in an HTML Format description.
 */
static const char* get_html_description_field(const char* data, const char* keyword)
{
    const char* pos = data;

    while (pos && *pos && *pos != '<')
    {
        if (memcmp(pos, keyword, strlen(keyword)) == 0)
            return pos + strlen(keyword);

        pos = strchr(pos, '\n');
        if (pos) pos++;
    }

    return NULL;
}


/**************************************************************************
 *              import_clipboard_data
 *
 *  Generic import clipboard data routine.
 */
static HANDLE import_clipboard_data(CFDataRef data)
{
    HANDLE data_handle = NULL;

    size_t len = CFDataGetLength(data);
    if (len)
    {
        LPVOID p;

        /* Turn on the DDESHARE flag to enable shared 32 bit memory */
        data_handle = GlobalAlloc(GMEM_FIXED, len);
        if (!data_handle)
            return NULL;

        if ((p = GlobalLock(data_handle)))
        {
            memcpy(p, CFDataGetBytePtr(data), len);
            GlobalUnlock(data_handle);
        }
        else
        {
            GlobalFree(data_handle);
            data_handle = NULL;
        }
    }

    return data_handle;
}


/**************************************************************************
 *              import_bmp_to_bitmap
 *
 *  Import BMP data, converting to CF_BITMAP format.
 */
static HANDLE import_bmp_to_bitmap(CFDataRef data)
{
    HANDLE ret;
    HANDLE dib = import_bmp_to_dib(data);

    ret = create_bitmap_from_dib(dib);

    GlobalFree(dib);
    return ret;
}


/**************************************************************************
 *              import_bmp_to_dib
 *
 *  Import BMP data, converting to CF_DIB or CF_DIBV5 format.  This just
 *  entails stripping the BMP file format header.
 */
static HANDLE import_bmp_to_dib(CFDataRef data)
{
    HANDLE ret = 0;
    BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)CFDataGetBytePtr(data);
    CFIndex len = CFDataGetLength(data);

    if (len >= sizeof(*bfh) + sizeof(BITMAPCOREHEADER) &&
        bfh->bfType == 0x4d42 /* "BM" */)
    {
        BITMAPINFO *bmi = (BITMAPINFO*)(bfh + 1);
        BYTE* p;

        len -= sizeof(*bfh);
        ret = GlobalAlloc(GMEM_FIXED, len);
        if (!ret || !(p = GlobalLock(ret)))
        {
            GlobalFree(ret);
            return 0;
        }

        memcpy(p, bmi, len);
        GlobalUnlock(ret);
    }

    return ret;
}


/**************************************************************************
 *              import_enhmetafile
 *
 *  Import enhanced metafile data, converting it to CF_ENHMETAFILE.
 */
static HANDLE import_enhmetafile(CFDataRef data)
{
    HANDLE ret = 0;
    CFIndex len = CFDataGetLength(data);

    TRACE("data %s\n", debugstr_cf(data));

    if (len)
        ret = SetEnhMetaFileBits(len, (const BYTE*)CFDataGetBytePtr(data));

    return ret;
}


/**************************************************************************
 *              import_html
 *
 *  Import HTML data.
 */
static HANDLE import_html(CFDataRef data)
{
    static const char header[] =
        "Version:0.9\n"
        "StartHTML:0000000100\n"
        "EndHTML:%010lu\n"
        "StartFragment:%010lu\n"
        "EndFragment:%010lu\n"
        "<!--StartFragment-->";
    static const char trailer[] = "\n<!--EndFragment-->";
    HANDLE ret;
    SIZE_T len, total;
    size_t size = CFDataGetLength(data);

    len = strlen(header) + 12;  /* 3 * 4 extra chars for %010lu */
    total = len + size + sizeof(trailer);
    if ((ret = GlobalAlloc(GMEM_FIXED, total)))
    {
        char *p = ret;
        p += sprintf(p, header, total - 1, len, len + size + 1 /* include the final \n in the data */);
        CFDataGetBytes(data, CFRangeMake(0, size), (UInt8*)p);
        strcpy(p + size, trailer);
        TRACE("returning %s\n", debugstr_a(ret));
    }
    return ret;
}


/**************************************************************************
 *              import_metafilepict
 *
 *  Import metafile picture data, converting it to CF_METAFILEPICT.
 */
static HANDLE import_metafilepict(CFDataRef data)
{
    HANDLE ret = 0;
    CFIndex len = CFDataGetLength(data);
    METAFILEPICT *mfp;

    TRACE("data %s\n", debugstr_cf(data));

    if (len >= sizeof(*mfp) && (ret = GlobalAlloc(GMEM_FIXED, sizeof(*mfp))))
    {
        const BYTE *bytes = (const BYTE*)CFDataGetBytePtr(data);

        mfp = GlobalLock(ret);
        memcpy(mfp, bytes, sizeof(*mfp));
        mfp->hMF = SetMetaFileBitsEx(len - sizeof(*mfp), bytes + sizeof(*mfp));
        GlobalUnlock(ret);
    }

    return ret;
}


/**************************************************************************
 *              import_nsfilenames_to_hdrop
 *
 *  Import NSFilenamesPboardType data, converting the property-list-
 *  serialized array of path strings to CF_HDROP.
 */
static HANDLE import_nsfilenames_to_hdrop(CFDataRef data)
{
    HDROP hdrop = NULL;
    CFArrayRef names;
    CFIndex count, i;
    size_t len;
    char *buffer = NULL;
    WCHAR **paths = NULL;
    DROPFILES* dropfiles;
    UniChar* p;

    TRACE("data %s\n", debugstr_cf(data));

    names = (CFArrayRef)CFPropertyListCreateWithData(NULL, data, kCFPropertyListImmutable,
                                                     NULL, NULL);
    if (!names || CFGetTypeID(names) != CFArrayGetTypeID())
    {
        WARN("failed to interpret data as a CFArray\n");
        goto done;
    }

    count = CFArrayGetCount(names);

    len = 0;
    for (i = 0; i < count; i++)
    {
        CFIndex this_len;
        CFStringRef name = (CFStringRef)CFArrayGetValueAtIndex(names, i);
        TRACE("    %s\n", debugstr_cf(name));
        if (CFGetTypeID(name) != CFStringGetTypeID())
        {
            WARN("non-string in array\n");
            goto done;
        }

        this_len = CFStringGetMaximumSizeOfFileSystemRepresentation(name);
        if (this_len > len)
            len = this_len;
    }

    buffer = HeapAlloc(GetProcessHeap(), 0, len);
    if (!buffer)
    {
        WARN("failed to allocate buffer for file-system representations\n");
        goto done;
    }

    paths = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(paths[0]));
    if (!paths)
    {
        WARN("failed to allocate array of DOS paths\n");
        goto done;
    }

    for (i = 0; i < count; i++)
    {
        CFStringRef name = (CFStringRef)CFArrayGetValueAtIndex(names, i);
        if (!CFStringGetFileSystemRepresentation(name, buffer, len))
        {
            WARN("failed to get file-system representation for %s\n", debugstr_cf(name));
            goto done;
        }
        paths[i] = wine_get_dos_file_name(buffer);
        if (!paths[i])
        {
            WARN("failed to get DOS path for %s\n", debugstr_a(buffer));
            goto done;
        }
    }

    len = 1; /* for the terminating null */
    for (i = 0; i < count; i++)
        len += strlenW(paths[i]) + 1;

    hdrop = GlobalAlloc(GMEM_FIXED, sizeof(*dropfiles) + len * sizeof(WCHAR));
    if (!hdrop || !(dropfiles = GlobalLock(hdrop)))
    {
        WARN("failed to allocate HDROP\n");
        GlobalFree(hdrop);
        hdrop = NULL;
        goto done;
    }

    dropfiles->pFiles   = sizeof(*dropfiles);
    dropfiles->pt.x     = 0;
    dropfiles->pt.y     = 0;
    dropfiles->fNC      = FALSE;
    dropfiles->fWide    = TRUE;

    p = (WCHAR*)(dropfiles + 1);
    for (i = 0; i < count; i++)
    {
        strcpyW(p, paths[i]);
        p += strlenW(p) + 1;
    }
    *p = 0;

    GlobalUnlock(hdrop);

done:
    if (paths)
    {
        for (i = 0; i < count; i++)
            HeapFree(GetProcessHeap(), 0, paths[i]);
        HeapFree(GetProcessHeap(), 0, paths);
    }
    HeapFree(GetProcessHeap(), 0, buffer);
    if (names) CFRelease(names);
    return hdrop;
}


/**************************************************************************
 *              import_utf8_to_text
 *
 *  Import a UTF-8 string, converting the string to CF_TEXT.
 */
static HANDLE import_utf8_to_text(CFDataRef data)
{
    HANDLE ret = NULL;
    HANDLE unicode_handle = import_utf8_to_unicodetext(data);
    LPWSTR unicode_string = GlobalLock(unicode_handle);

    if (unicode_string)
    {
        int unicode_len;
        HANDLE handle;
        char *p;
        INT len;

        unicode_len = GlobalSize(unicode_handle) / sizeof(WCHAR);

        len = WideCharToMultiByte(CP_ACP, 0, unicode_string, unicode_len, NULL, 0, NULL, NULL);
        if (!unicode_len || unicode_string[unicode_len - 1]) len += 1;
        handle = GlobalAlloc(GMEM_FIXED, len);

        if (handle && (p = GlobalLock(handle)))
        {
            WideCharToMultiByte(CP_ACP, 0, unicode_string, unicode_len, p, len, NULL, NULL);
            p[len - 1] = 0;
            GlobalUnlock(handle);
            ret = handle;
        }
        GlobalUnlock(unicode_handle);
    }

    GlobalFree(unicode_handle);
    return ret;
}


/**************************************************************************
 *              import_utf8_to_unicodetext
 *
 *  Import a UTF-8 string, converting the string to CF_UNICODETEXT.
 */
static HANDLE import_utf8_to_unicodetext(CFDataRef data)
{
    const BYTE *src;
    unsigned long src_len;
    unsigned long new_lines = 0;
    LPSTR dst;
    unsigned long i, j;
    HANDLE unicode_handle = NULL;

    src = CFDataGetBytePtr(data);
    src_len = CFDataGetLength(data);
    for (i = 0; i < src_len; i++)
    {
        if (src[i] == '\n')
            new_lines++;
    }

    if ((dst = HeapAlloc(GetProcessHeap(), 0, src_len + new_lines + 1)))
    {
        UINT count;

        for (i = 0, j = 0; i < src_len; i++)
        {
            if (src[i] == '\n')
                dst[j++] = '\r';

            dst[j++] = src[i];
        }
        dst[j] = 0;

        count = MultiByteToWideChar(CP_UTF8, 0, dst, -1, NULL, 0);
        unicode_handle = GlobalAlloc(GMEM_FIXED, count * sizeof(WCHAR));

        if (unicode_handle)
        {
            WCHAR *textW = GlobalLock(unicode_handle);
            MultiByteToWideChar(CP_UTF8, 0, dst, -1, textW, count);
            GlobalUnlock(unicode_handle);
        }

        HeapFree(GetProcessHeap(), 0, dst);
    }

    return unicode_handle;
}


/**************************************************************************
 *              import_utf16_to_unicodetext
 *
 *  Import a UTF-8 string, converting the string to CF_UNICODETEXT.
 */
static HANDLE import_utf16_to_unicodetext(CFDataRef data)
{
    const WCHAR *src;
    unsigned long src_len;
    unsigned long new_lines = 0;
    LPWSTR dst;
    unsigned long i, j;
    HANDLE unicode_handle;

    src = (const WCHAR *)CFDataGetBytePtr(data);
    src_len = CFDataGetLength(data) / sizeof(WCHAR);
    for (i = 0; i < src_len; i++)
    {
        if (src[i] == '\n')
            new_lines++;
        else if (src[i] == '\r' && (i + 1 >= src_len || src[i + 1] != '\n'))
            new_lines++;
    }

    if ((unicode_handle = GlobalAlloc(GMEM_FIXED, (src_len + new_lines + 1) * sizeof(WCHAR))))
    {
        dst = GlobalLock(unicode_handle);

        for (i = 0, j = 0; i < src_len; i++)
        {
            if (src[i] == '\n')
                dst[j++] = '\r';

            dst[j++] = src[i];

            if (src[i] == '\r' && (i + 1 >= src_len || src[i + 1] != '\n'))
                dst[j++] = '\n';
        }
        dst[j] = 0;

        GlobalUnlock(unicode_handle);
    }

    return unicode_handle;
}


/**************************************************************************
 *              export_clipboard_data
 *
 *  Generic export clipboard data routine.
 */
static CFDataRef export_clipboard_data(HANDLE data)
{
    CFDataRef ret;
    UINT len;
    LPVOID src;

    len = GlobalSize(data);
    src = GlobalLock(data);
    if (!src) return NULL;

    ret = CFDataCreate(NULL, src, len);
    GlobalUnlock(data);

    return ret;
}


/**************************************************************************
 *              export_bitmap_to_bmp
 *
 *  Export CF_BITMAP to BMP file format.
 */
static CFDataRef export_bitmap_to_bmp(HANDLE data)
{
    CFDataRef ret = NULL;
    HGLOBAL dib;

    dib = create_dib_from_bitmap(data);
    if (dib)
    {
        ret = export_dib_to_bmp(dib);
        GlobalFree(dib);
    }

    return ret;
}


/**************************************************************************
 *              export_dib_to_bmp
 *
 *  Export CF_DIB or CF_DIBV5 to BMP file format.  This just entails
 *  prepending a BMP file format header to the data.
 */
static CFDataRef export_dib_to_bmp(HANDLE data)
{
    CFMutableDataRef ret = NULL;
    BYTE *dibdata;
    CFIndex len;
    BITMAPFILEHEADER bfh;

    dibdata = GlobalLock(data);
    if (!dibdata)
        return NULL;

    len = sizeof(bfh) + GlobalSize(data);
    ret = CFDataCreateMutable(NULL, len);
    if (ret)
    {
        bfh.bfType = 0x4d42; /* "BM" */
        bfh.bfSize = len;
        bfh.bfReserved1 = 0;
        bfh.bfReserved2 = 0;
        bfh.bfOffBits = sizeof(bfh) + bitmap_info_size((BITMAPINFO*)dibdata, DIB_RGB_COLORS);
        CFDataAppendBytes(ret, (UInt8*)&bfh, sizeof(bfh));

        /* rest of bitmap is the same as the packed dib */
        CFDataAppendBytes(ret, (UInt8*)dibdata, len - sizeof(bfh));
    }

    GlobalUnlock(data);

    return ret;
}


/**************************************************************************
 *              export_enhmetafile
 *
 *  Export an enhanced metafile to data.
 */
static CFDataRef export_enhmetafile(HANDLE data)
{
    CFMutableDataRef ret = NULL;
    unsigned int size = GetEnhMetaFileBits(data, 0, NULL);

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

    ret = CFDataCreateMutable(NULL, size);
    if (ret)
    {
        CFDataSetLength(ret, size);
        GetEnhMetaFileBits(data, size, (BYTE*)CFDataGetMutableBytePtr(ret));
    }

    TRACE(" -> %s\n", debugstr_cf(ret));
    return ret;
}


/**************************************************************************
 *              export_hdrop_to_filenames
 *
 *  Export CF_HDROP to NSFilenamesPboardType data, which is a CFArray of
 *  CFStrings (holding Unix paths) which is serialized as a property list.
 */
static CFDataRef export_hdrop_to_filenames(HANDLE data)
{
    CFDataRef ret = NULL;
    DROPFILES *dropfiles;
    CFMutableArrayRef filenames = NULL;
    void *p;
    WCHAR *buffer = NULL;
    size_t buffer_len = 0;

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

    if (!(dropfiles = GlobalLock(data)))
    {
        WARN("failed to lock data %p\n", data);
        goto done;
    }

    filenames = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!filenames)
    {
        WARN("failed to create filenames array\n");
        goto done;
    }

    p = (char*)dropfiles + dropfiles->pFiles;
    while (dropfiles->fWide ? *(WCHAR*)p : *(char*)p)
    {
        char *unixname;
        CFStringRef filename;

        TRACE("    %s\n", dropfiles->fWide ? debugstr_w(p) : debugstr_a(p));

        if (dropfiles->fWide)
            unixname = wine_get_unix_file_name(p);
        else
        {
            int len = MultiByteToWideChar(CP_ACP, 0, p, -1, NULL, 0);
            if (len)
            {
                if (len > buffer_len)
                {
                    HeapFree(GetProcessHeap(), 0, buffer);
                    buffer_len = len * 2;
                    buffer = HeapAlloc(GetProcessHeap(), 0, buffer_len * sizeof(*buffer));
                }

                MultiByteToWideChar(CP_ACP, 0, p, -1, buffer, buffer_len);
                unixname = wine_get_unix_file_name(buffer);
            }
            else
                unixname = NULL;
        }
        if (!unixname)
        {
            WARN("failed to convert DOS path to Unix: %s\n",
                 dropfiles->fWide ? debugstr_w(p) : debugstr_a(p));
            goto done;
        }

        if (dropfiles->fWide)
            p = (WCHAR*)p + strlenW(p) + 1;
        else
            p = (char*)p + strlen(p) + 1;

        filename = CFStringCreateWithFileSystemRepresentation(NULL, unixname);
        HeapFree(GetProcessHeap(), 0, unixname);
        if (!filename)
        {
            WARN("failed to create CFString from Unix path %s\n", debugstr_a(unixname));
            goto done;
        }

        CFArrayAppendValue(filenames, filename);
        CFRelease(filename);
    }

    ret = CFPropertyListCreateData(NULL, filenames, kCFPropertyListXMLFormat_v1_0, 0, NULL);

done:
    HeapFree(GetProcessHeap(), 0, buffer);
    GlobalUnlock(data);
    if (filenames) CFRelease(filenames);
    TRACE(" -> %s\n", debugstr_cf(ret));
    return ret;
}


/**************************************************************************
 *              export_html
 *
 *  Export HTML Format to public.html data.
 *
 * FIXME: We should attempt to add an <a base> tag and convert windows paths.
 */
static CFDataRef export_html(HANDLE handle)
{
    CFDataRef ret;
    const char *data, *field_value;
    int fragmentstart, fragmentend;

    data = GlobalLock(handle);

    /* read the important fields */
    field_value = get_html_description_field(data, "StartFragment:");
    if (!field_value)
    {
        ERR("Couldn't find StartFragment value\n");
        goto failed;
    }
    fragmentstart = atoi(field_value);

    field_value = get_html_description_field(data, "EndFragment:");
    if (!field_value)
    {
        ERR("Couldn't find EndFragment value\n");
        goto failed;
    }
    fragmentend = atoi(field_value);

    /* export only the fragment */
    ret = CFDataCreate(NULL, (const UInt8*)&data[fragmentstart], fragmentend - fragmentstart);
    GlobalUnlock(handle);
    return ret;

failed:
    GlobalUnlock(handle);
    return NULL;
}


/**************************************************************************
 *              export_metafilepict
 *
 *  Export a metafile to data.
 */
static CFDataRef export_metafilepict(HANDLE data)
{
    CFMutableDataRef ret = NULL;
    METAFILEPICT *mfp = GlobalLock(data);
    unsigned int size = GetMetaFileBitsEx(mfp->hMF, 0, NULL);

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

    ret = CFDataCreateMutable(NULL, sizeof(*mfp) + size);
    if (ret)
    {
        CFDataAppendBytes(ret, (UInt8*)mfp, sizeof(*mfp));
        CFDataIncreaseLength(ret, size);
        GetMetaFileBitsEx(mfp->hMF, size, (BYTE*)CFDataGetMutableBytePtr(ret) + sizeof(*mfp));
    }

    GlobalUnlock(data);
    TRACE(" -> %s\n", debugstr_cf(ret));
    return ret;
}


/**************************************************************************
 *              export_text_to_utf8
 *
 *  Export CF_TEXT to UTF-8.
 */
static CFDataRef export_text_to_utf8(HANDLE data)
{
    CFDataRef ret = NULL;
    const char* str;

    if ((str = GlobalLock(data)))
    {
        int str_len = GlobalSize(data);
        int wstr_len;
        WCHAR *wstr;
        HANDLE unicode;
        char *p;

        wstr_len = MultiByteToWideChar(CP_ACP, 0, str, str_len, NULL, 0);
        if (!str_len || str[str_len - 1]) wstr_len += 1;
        wstr = HeapAlloc(GetProcessHeap(), 0, wstr_len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, str, str_len, wstr, wstr_len);
        wstr[wstr_len - 1] = 0;

        unicode = GlobalAlloc(GMEM_FIXED, wstr_len * sizeof(WCHAR));
        if (unicode && (p = GlobalLock(unicode)))
        {
            memcpy(p, wstr, wstr_len * sizeof(WCHAR));
            GlobalUnlock(unicode);
        }

        ret = export_unicodetext_to_utf8(unicode);

        GlobalFree(unicode);
        GlobalUnlock(data);
    }

    return ret;
}


/**************************************************************************
 *              export_unicodetext_to_utf8
 *
 *  Export CF_UNICODETEXT to UTF-8.
 */
static CFDataRef export_unicodetext_to_utf8(HANDLE data)
{
    CFMutableDataRef ret;
    LPVOID src;
    INT dst_len;

    src = GlobalLock(data);
    if (!src) return NULL;

    dst_len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
    if (dst_len) dst_len--; /* Leave off null terminator. */
    ret = CFDataCreateMutable(NULL, dst_len);
    if (ret)
    {
        LPSTR dst;
        int i, j;

        CFDataSetLength(ret, dst_len);
        dst = (LPSTR)CFDataGetMutableBytePtr(ret);
        WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, dst_len, NULL, NULL);

        /* Remove carriage returns */
        for (i = 0, j = 0; i < dst_len; i++)
        {
            if (dst[i] == '\r' &&
                (i + 1 >= dst_len || dst[i + 1] == '\n' || dst[i + 1] == '\0'))
                continue;
            dst[j++] = dst[i];
        }
        CFDataSetLength(ret, j);
    }
    GlobalUnlock(data);

    return ret;
}


/**************************************************************************
 *              export_unicodetext_to_utf16
 *
 *  Export CF_UNICODETEXT to UTF-16.
 */
static CFDataRef export_unicodetext_to_utf16(HANDLE data)
{
    CFMutableDataRef ret;
    const WCHAR *src;
    INT src_len;

    src = GlobalLock(data);
    if (!src) return NULL;

    src_len = GlobalSize(data) / sizeof(WCHAR);
    if (src_len) src_len--; /* Leave off null terminator. */
    ret = CFDataCreateMutable(NULL, src_len * sizeof(WCHAR));
    if (ret)
    {
        LPWSTR dst;
        int i, j;

        CFDataSetLength(ret, src_len * sizeof(WCHAR));
        dst = (LPWSTR)CFDataGetMutableBytePtr(ret);

        /* Remove carriage returns */
        for (i = 0, j = 0; i < src_len; i++)
        {
            if (src[i] == '\r' &&
                (i + 1 >= src_len || src[i + 1] == '\n' || src[i + 1] == '\0'))
                continue;
            dst[j++] = src[i];
        }
        CFDataSetLength(ret, j * sizeof(WCHAR));
    }
    GlobalUnlock(data);

    return ret;
}


/**************************************************************************
 *              macdrv_get_pasteboard_data
 */
HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format)
{
    CFArrayRef types;
    CFIndex count;
    CFIndex i;
    CFStringRef type, best_type;
    WINE_CLIPFORMAT* best_format = NULL;
    HANDLE data = NULL;

    TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(desired_format));

    types = macdrv_copy_pasteboard_types(pasteboard);
    if (!types)
    {
        WARN("Failed to copy pasteboard types\n");
        return NULL;
    }

    count = CFArrayGetCount(types);
    TRACE("got %ld types\n", count);

    for (i = 0; (!best_format || best_format->synthesized) && i < count; i++)
    {
        WINE_CLIPFORMAT* format;

        type = CFArrayGetValueAtIndex(types, i);

        if ((format = format_for_type(type)))
        {
            TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));

            if (format->format_id == desired_format)
            {
                /* The best format is the matching one which is not synthesized.  Failing that,
                   the best format is the first matching synthesized format. */
                if (!format->synthesized || !best_format)
                {
                    best_type = type;
                    best_format = format;
                }
            }
        }
    }

    if (best_format)
    {
        CFDataRef pasteboard_data = macdrv_copy_pasteboard_data(pasteboard, best_type);

        TRACE("got pasteboard data for type %s: %s\n", debugstr_cf(best_type), debugstr_cf(pasteboard_data));

        if (pasteboard_data)
        {
            data = best_format->import_func(pasteboard_data);
            CFRelease(pasteboard_data);
        }
    }

    CFRelease(types);
    TRACE(" -> %p\n", data);
    return data;
}


/**************************************************************************
 *              macdrv_pasteboard_has_format
 */
BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format)
{
    CFArrayRef types;
    int count;
    UINT i;
    BOOL found = FALSE;

    TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(desired_format));

    types = macdrv_copy_pasteboard_types(pasteboard);
    if (!types)
    {
        WARN("Failed to copy pasteboard types\n");
        return FALSE;
    }

    count = CFArrayGetCount(types);
    TRACE("got %d types\n", count);

    for (i = 0; i < count; i++)
    {
        CFStringRef type = CFArrayGetValueAtIndex(types, i);
        WINE_CLIPFORMAT* format = format_for_type(type);

        if (format)
        {
            TRACE("for type %s got format %s\n", debugstr_cf(type), debugstr_format(format->format_id));

            if (format->format_id == desired_format)
            {
                found = TRUE;
                break;
            }
        }
    }

    CFRelease(types);
    TRACE(" -> %d\n", found);
    return found;
}


/**************************************************************************
 *              get_formats_for_pasteboard_types
 */
static WINE_CLIPFORMAT** get_formats_for_pasteboard_types(CFArrayRef types, UINT *num_formats)
{
    CFIndex count, i;
    CFMutableSetRef seen_formats;
    WINE_CLIPFORMAT** formats;
    UINT pos;

    count = CFArrayGetCount(types);
    TRACE("got %ld types\n", count);

    if (!count)
        return NULL;

    seen_formats = CFSetCreateMutable(NULL, count, NULL);
    if (!seen_formats)
    {
        WARN("Failed to allocate seen formats set\n");
        return NULL;
    }

    formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*formats));
    if (!formats)
    {
        WARN("Failed to allocate formats array\n");
        CFRelease(seen_formats);
        return NULL;
    }

    pos = 0;
    for (i = 0; i < count; i++)
    {
        CFStringRef type = CFArrayGetValueAtIndex(types, i);
        WINE_CLIPFORMAT* format = format_for_type(type);

        if (!format)
        {
            TRACE("ignoring type %s\n", debugstr_cf(type));
            continue;
        }

        if (!format->synthesized)
        {
            TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
            CFSetAddValue(seen_formats, (void*)format->format_id);
            formats[pos++] = format;
        }
        else if (format->natural_format &&
                 CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type))
        {
            TRACE("for type %s deferring synthesized formats because type %s is also present\n",
                  debugstr_cf(type), debugstr_cf(format->natural_format->type));
        }
        else if (CFSetContainsValue(seen_formats, (void*)format->format_id))
        {
            TRACE("for type %s got duplicate synthesized format %p/%s; skipping\n", debugstr_cf(type), format,
                  debugstr_format(format->format_id));
        }
        else
        {
            TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
            CFSetAddValue(seen_formats, (void*)format->format_id);
            formats[pos++] = format;
        }
    }

    /* Now go back through the types adding the synthesized formats that we deferred before. */
    for (i = 0; i < count; i++)
    {
        CFStringRef type = CFArrayGetValueAtIndex(types, i);
        WINE_CLIPFORMAT* format = format_for_type(type);

        if (!format) continue;
        if (!format->synthesized) continue;

        /* Don't duplicate a real value with a synthesized value. */
        if (CFSetContainsValue(seen_formats, (void*)format->format_id)) continue;

        TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
        CFSetAddValue(seen_formats, (void*)format->format_id);
        formats[pos++] = format;
    }

    CFRelease(seen_formats);

    if (!pos)
    {
        HeapFree(GetProcessHeap(), 0, formats);
        formats = NULL;
    }

    *num_formats = pos;
    return formats;
}


/**************************************************************************
 *              get_formats_for_pasteboard
 */
static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *num_formats)
{
    CFArrayRef types;
    WINE_CLIPFORMAT** formats;

    TRACE("pasteboard %s\n", debugstr_cf(pasteboard));

    types = macdrv_copy_pasteboard_types(pasteboard);
    if (!types)
    {
        WARN("Failed to copy pasteboard types\n");
        return NULL;
    }

    formats = get_formats_for_pasteboard_types(types, num_formats);
    CFRelease(types);
    return formats;
}


/**************************************************************************
 *              macdrv_get_pasteboard_formats
 */
UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats)
{
    WINE_CLIPFORMAT** formats;
    UINT count, i;
    UINT* format_ids;

    formats = get_formats_for_pasteboard(pasteboard, &count);
    if (!formats)
        return NULL;

    format_ids = HeapAlloc(GetProcessHeap(), 0, count);
    if (!format_ids)
    {
        WARN("Failed to allocate formats IDs array\n");
        HeapFree(GetProcessHeap(), 0, formats);
        return NULL;
    }

    for (i = 0; i < count; i++)
        format_ids[i] = formats[i]->format_id;

    HeapFree(GetProcessHeap(), 0, formats);

    *num_formats = count;
    return format_ids;
}


/**************************************************************************
 *              register_win32_formats
 *
 * Register Win32 clipboard formats the first time we encounter them.
 */
static void register_win32_formats(const UINT *ids, UINT size)
{
    unsigned int i;

    if (list_empty(&format_list)) register_builtin_formats();

    for (i = 0; i < size; i++)
        register_format(ids[i], NULL);
}


/***********************************************************************
 *              get_clipboard_formats
 *
 * Return a list of all formats currently available on the Win32 clipboard.
 * Helper for set_mac_pasteboard_types_from_win32_clipboard.
 */
static UINT *get_clipboard_formats(UINT *size)
{
    UINT *ids;

    *size = 256;
    for (;;)
    {
        if (!(ids = HeapAlloc(GetProcessHeap(), 0, *size * sizeof(*ids)))) return NULL;
        if (GetUpdatedClipboardFormats(ids, *size, size)) break;
        HeapFree(GetProcessHeap(), 0, ids);
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL;
    }
    register_win32_formats(ids, *size);
    return ids;
}


/**************************************************************************
 *              set_mac_pasteboard_types_from_win32_clipboard
 */
static void set_mac_pasteboard_types_from_win32_clipboard(void)
{
    WINE_CLIPFORMAT *format;
    UINT count, i, *formats;

    if (!(formats = get_clipboard_formats(&count))) return;

    macdrv_clear_pasteboard(clipboard_cocoa_window);

    for (i = 0; i < count; i++)
    {
        LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
        {
            if (format->format_id != formats[i]) continue;
            TRACE("%s -> %s\n", debugstr_format(format->format_id), debugstr_cf(format->type));
            macdrv_set_pasteboard_data(format->type, NULL, clipboard_cocoa_window);
        }
    }

    HeapFree(GetProcessHeap(), 0, formats);
    return;
}


/**************************************************************************
 *              set_win32_clipboard_formats_from_mac_pasteboard
 */
static void set_win32_clipboard_formats_from_mac_pasteboard(CFArrayRef types)
{
    WINE_CLIPFORMAT** formats;
    UINT count, i;

    formats = get_formats_for_pasteboard_types(types, &count);
    if (!formats)
        return;

    for (i = 0; i < count; i++)
    {
        TRACE("adding format %s\n", debugstr_format(formats[i]->format_id));
        SetClipboardData(formats[i]->format_id, 0);
    }

    HeapFree(GetProcessHeap(), 0, current_mac_formats);
    current_mac_formats = formats;
    nb_current_mac_formats = count;
}


/**************************************************************************
 *              render_format
 */
static void render_format(UINT id)
{
    unsigned int i;

    for (i = 0; i < nb_current_mac_formats; i++)
    {
        CFDataRef pasteboard_data;

        if (current_mac_formats[i]->format_id != id) continue;

        pasteboard_data = macdrv_copy_pasteboard_data(NULL, current_mac_formats[i]->type);
        if (pasteboard_data)
        {
            HANDLE handle = current_mac_formats[i]->import_func(pasteboard_data);
            CFRelease(pasteboard_data);
            if (handle)
            {
                SetClipboardData(id, handle);
                rendered_formats++;
            }
            break;
        }
    }
}


/**************************************************************************
 *              grab_win32_clipboard
 *
 * Grab the Win32 clipboard when a Mac app has taken ownership of the
 * pasteboard, and fill it with the pasteboard data types.
 */
static void grab_win32_clipboard(BOOL changed)
{
    static CFArrayRef last_types;
    CFArrayRef types;

    types = macdrv_copy_pasteboard_types(NULL);
    if (!types)
    {
        WARN("Failed to copy pasteboard types\n");
        return;
    }

    changed = (changed || rendered_formats || !last_types || !CFEqual(types, last_types));
    if (!changed)
    {
        CFRelease(types);
        return;
    }

    if (last_types) CFRelease(last_types);
    last_types = types; /* takes ownership */

    if (!OpenClipboard(clipboard_hwnd)) return;
    EmptyClipboard();
    is_clipboard_owner = TRUE;
    rendered_formats = 0;
    last_clipboard_update = GetTickCount64();
    set_win32_clipboard_formats_from_mac_pasteboard(types);
    CloseClipboard();
    SetTimer(clipboard_hwnd, 1, CLIPBOARD_UPDATE_DELAY, NULL);
}


/**************************************************************************
 *              update_clipboard
 *
 * Periodically update the clipboard while the clipboard is owned by a
 * Mac app.
 */
static void update_clipboard(void)
{
    static BOOL updating;

    TRACE("is_clipboard_owner %d last_clipboard_update %llu now %llu\n",
          is_clipboard_owner, last_clipboard_update, GetTickCount64());

    if (updating) return;
    updating = TRUE;

    if (is_clipboard_owner)
    {
        if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY)
            grab_win32_clipboard(FALSE);
    }
    else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
        grab_win32_clipboard(TRUE);

    updating = FALSE;
}


/**************************************************************************
 *              clipboard_wndproc
 *
 * Window procedure for the clipboard manager.
 */
static LRESULT CALLBACK clipboard_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
        case WM_NCCREATE:
            return TRUE;
        case WM_CLIPBOARDUPDATE:
            if (is_clipboard_owner) break;  /* ignore our own changes */
            if ((LONG)(GetClipboardSequenceNumber() - last_get_seqno) <= 0) break;
            set_mac_pasteboard_types_from_win32_clipboard();
            break;
        case WM_RENDERFORMAT:
            render_format(wp);
            break;
        case WM_TIMER:
            if (!is_clipboard_owner) break;
            grab_win32_clipboard(FALSE);
            break;
        case WM_DESTROYCLIPBOARD:
            TRACE("WM_DESTROYCLIPBOARD: lost ownership\n");
            is_clipboard_owner = FALSE;
            KillTimer(hwnd, 1);
            break;
    }
    return DefWindowProcW(hwnd, msg, wp, lp);
}


/**************************************************************************
 *              wait_clipboard_mutex
 *
 * Make sure that there's only one clipboard thread per window station.
 */
static BOOL wait_clipboard_mutex(void)
{
    static const WCHAR prefix[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'};
    WCHAR buffer[MAX_PATH + sizeof(prefix) / sizeof(WCHAR)];
    HANDLE mutex;

    memcpy(buffer, prefix, sizeof(prefix));
    if (!GetUserObjectInformationW(GetProcessWindowStation(), UOI_NAME,
                                   buffer + sizeof(prefix) / sizeof(WCHAR),
                                   sizeof(buffer) - sizeof(prefix), NULL))
    {
        ERR("failed to get winstation name\n");
        return FALSE;
    }
    mutex = CreateMutexW(NULL, TRUE, buffer);
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        TRACE("waiting for mutex %s\n", debugstr_w(buffer));
        WaitForSingleObject(mutex, INFINITE);
    }
    return TRUE;
}


/**************************************************************************
 *              init_pipe_name
 *
 * Init-once helper for get_pipe_name.
 */
static BOOL CALLBACK init_pipe_name(INIT_ONCE* once, void* param, void** context)
{
    static const WCHAR prefix[] = {'\\','\\','.','\\','p','i','p','e','\\','_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_'};

    memcpy(clipboard_pipe_name, prefix, sizeof(prefix));
    if (!GetUserObjectInformationW(GetProcessWindowStation(), UOI_NAME,
                                   clipboard_pipe_name + sizeof(prefix) / sizeof(WCHAR),
                                   sizeof(clipboard_pipe_name) - sizeof(prefix), NULL))
    {
        ERR("failed to get winstation name\n");
        return FALSE;
    }

    return TRUE;
}


/**************************************************************************
 *              get_pipe_name
 *
 * Get the name of the pipe used to communicate with the per-window-station
 * clipboard manager thread.
 */
static const WCHAR* get_pipe_name(void)
{
    static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
    InitOnceExecuteOnce(&once, init_pipe_name, NULL, NULL);
    return clipboard_pipe_name[0] ? clipboard_pipe_name : NULL;
}


/**************************************************************************
 *              clipboard_thread
 *
 * Thread running inside the desktop process to manage the clipboard
 */
static DWORD WINAPI clipboard_thread(void *arg)
{
    static const WCHAR clipboard_classname[] = {'_','_','w','i','n','e','_','c','l','i','p','b','o','a','r','d','_','m','a','n','a','g','e','r',0};
    WNDCLASSW class;
    struct macdrv_window_features wf;
    const WCHAR* pipe_name;
    HANDLE pipe = NULL;
    HANDLE event = NULL;
    OVERLAPPED overlapped;
    BOOL need_connect = TRUE, pending = FALSE;
    MSG msg;

    if (!wait_clipboard_mutex()) return 0;

    memset(&class, 0, sizeof(class));
    class.lpfnWndProc   = clipboard_wndproc;
    class.lpszClassName = clipboard_classname;

    if (!RegisterClassW(&class) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
    {
        ERR("could not register clipboard window class err %u\n", GetLastError());
        return 0;
    }
    if (!(clipboard_hwnd = CreateWindowW(clipboard_classname, NULL, 0, 0, 0, 0, 0,
                                         HWND_MESSAGE, 0, 0, NULL)))
    {
        ERR("failed to create clipboard window err %u\n", GetLastError());
        return 0;
    }

    memset(&wf, 0, sizeof(wf));
    clipboard_cocoa_window = macdrv_create_cocoa_window(&wf, CGRectMake(100, 100, 100, 100), clipboard_hwnd,
                                                        macdrv_init_thread_data()->queue);
    if (!clipboard_cocoa_window)
    {
        ERR("failed to create clipboard Cocoa window\n");
        goto done;
    }

    pipe_name = get_pipe_name();
    if (!pipe_name)
    {
        ERR("failed to get pipe name\n");
        goto done;
    }

    pipe = CreateNamedPipeW(pipe_name, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
                            PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 1, 1, 0, NULL);
    if (!pipe)
    {
        ERR("failed to create named pipe: %u\n", GetLastError());
        goto done;
    }

    event = CreateEventW(NULL, TRUE, FALSE, NULL);
    if (!event)
    {
        ERR("failed to create event: %d\n", GetLastError());
        goto done;
    }

    clipboard_thread_id = GetCurrentThreadId();
    AddClipboardFormatListener(clipboard_hwnd);
    register_builtin_formats();
    grab_win32_clipboard(TRUE);

    TRACE("clipboard thread %04x running\n", GetCurrentThreadId());
    while (1)
    {
        DWORD result;

        if (need_connect)
        {
            pending = FALSE;
            memset(&overlapped, 0, sizeof(overlapped));
            overlapped.hEvent = event;
            if (ConnectNamedPipe(pipe, &overlapped))
            {
                ERR("asynchronous ConnectNamedPipe unexpectedly returned true: %d\n", GetLastError());
                ResetEvent(event);
            }
            else
            {
                result = GetLastError();
                switch (result)
                {
                    case ERROR_PIPE_CONNECTED:
                    case ERROR_NO_DATA:
                        SetEvent(event);
                        need_connect = FALSE;
                        break;
                    case ERROR_IO_PENDING:
                        need_connect = FALSE;
                        pending = TRUE;
                        break;
                    default:
                        ERR("failed to initiate pipe connection: %d\n", result);
                        break;
                }
            }
        }

        result = MsgWaitForMultipleObjectsEx(1, &event, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
        switch (result)
        {
            case WAIT_OBJECT_0:
            {
                DWORD written;

                if (pending && !GetOverlappedResult(pipe, &overlapped, &written, FALSE))
                    ERR("failed to connect pipe: %d\n", GetLastError());

                update_clipboard();
                DisconnectNamedPipe(pipe);
                need_connect = TRUE;
                break;
            }
            case WAIT_OBJECT_0 + 1:
                while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    if (msg.message == WM_QUIT)
                        goto done;
                    DispatchMessageW(&msg);
                }
                break;
            case WAIT_IO_COMPLETION:
                break;
            default:
                ERR("failed to wait for connection or input: %d\n", GetLastError());
                break;
        }
    }

done:
    if (event) CloseHandle(event);
    if (pipe) CloseHandle(pipe);
    macdrv_destroy_cocoa_window(clipboard_cocoa_window);
    DestroyWindow(clipboard_hwnd);
    return 0;
}


/**************************************************************************
 *              Mac User Driver Clipboard Exports
 **************************************************************************/


/**************************************************************************
 *              macdrv_UpdateClipboard
 */
void CDECL macdrv_UpdateClipboard(void)
{
    static ULONG last_update;
    ULONG now, end;
    const WCHAR* pipe_name;
    HANDLE pipe;
    BYTE dummy;
    DWORD count;
    OVERLAPPED overlapped = { 0 };
    BOOL canceled = FALSE;

    if (GetCurrentThreadId() == clipboard_thread_id) return;

    TRACE("\n");

    now = GetTickCount();
    if ((int)(now - last_update) <= CLIPBOARD_UPDATE_DELAY) return;
    last_update = now;

    if (!(pipe_name = get_pipe_name())) return;
    pipe = CreateFileW(pipe_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
    if (pipe == INVALID_HANDLE_VALUE)
    {
        WARN("failed to open pipe to clipboard manager: %d\n", GetLastError());
        return;
    }

    overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
    if (!overlapped.hEvent)
    {
        ERR("failed to create event: %d\n", GetLastError());
        goto done;
    }

    /* We expect the read to fail because the server just closes our connection.  This
       is just waiting for that close to happen. */
    if (ReadFile(pipe, &dummy, sizeof(dummy), NULL, &overlapped))
    {
        WARN("asynchronous ReadFile unexpectedly returned true: %d\n", GetLastError());
        goto done;
    }
    else
    {
        DWORD error = GetLastError();
        if (error == ERROR_PIPE_NOT_CONNECTED || error == ERROR_BROKEN_PIPE)
        {
            /* The server accepted, handled, and closed our connection before we
               attempted the read, which is fine. */
            goto done;
        }
        else if (error != ERROR_IO_PENDING)
        {
            ERR("failed to initiate read from pipe: %d\n", error);
            goto done;
        }
    }

    end = now + 500;
    while (1)
    {
        DWORD result, timeout;

        if (canceled)
            timeout = INFINITE;
        else
        {
            now = GetTickCount();
            timeout = end - now;
            if ((int)timeout < 0)
                timeout = 0;
        }

        result = MsgWaitForMultipleObjectsEx(1, &overlapped.hEvent, timeout, QS_SENDMESSAGE, MWMO_ALERTABLE);
        switch (result)
        {
            case WAIT_OBJECT_0:
            {
                if (GetOverlappedResult(pipe, &overlapped, &count, FALSE))
                    WARN("unexpectedly succeeded in reading from pipe\n");
                else
                {
                    result = GetLastError();
                    if (result != ERROR_BROKEN_PIPE && result != ERROR_OPERATION_ABORTED &&
                        result != ERROR_HANDLES_CLOSED)
                        WARN("failed to read from pipe: %d\n", result);
                }

                goto done;
            }
            case WAIT_OBJECT_0 + 1:
            {
                MSG msg;
                while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE))
                    DispatchMessageW(&msg);
                break;
            }
            case WAIT_IO_COMPLETION:
                break;
            case WAIT_TIMEOUT:
                WARN("timed out waiting for read\n");
                CancelIoEx(pipe, &overlapped);
                canceled = TRUE;
                break;
            default:
                if (canceled)
                {
                    ERR("failed to wait for cancel: %d\n", GetLastError());
                    goto done;
                }

                ERR("failed to wait for read: %d\n", GetLastError());
                CancelIoEx(pipe, &overlapped);
                canceled = TRUE;
                break;
        }
    }

done:
    if (overlapped.hEvent) CloseHandle(overlapped.hEvent);
    CloseHandle(pipe);
}


/**************************************************************************
 *              MACDRV Private Clipboard Exports
 **************************************************************************/


/**************************************************************************
 *              query_pasteboard_data
 */
BOOL query_pasteboard_data(HWND hwnd, CFStringRef type)
{
    WINE_CLIPFORMAT *format;
    BOOL ret = FALSE;
    HANDLE handle;

    TRACE("win %p/%p type %s\n", hwnd, clipboard_cocoa_window, debugstr_cf(type));

    format = format_for_type(type);
    if (!format) return FALSE;

    if (!OpenClipboard(clipboard_hwnd))
    {
        ERR("failed to open clipboard for %s\n", debugstr_cf(type));
        return FALSE;
    }

    if ((handle = GetClipboardData(format->format_id)))
    {
        CFDataRef data;

        TRACE("exporting %s %p\n", debugstr_format(format->format_id), handle);

        if ((data = format->export_func(handle)))
        {
            ret = macdrv_set_pasteboard_data(format->type, data, clipboard_cocoa_window);
            CFRelease(data);
        }
    }

    last_get_seqno = GetClipboardSequenceNumber();

    CloseClipboard();

    return ret;
}


/**************************************************************************
 *              macdrv_lost_pasteboard_ownership
 *
 * Handler for the LOST_PASTEBOARD_OWNERSHIP event.
 */
void macdrv_lost_pasteboard_ownership(HWND hwnd)
{
    TRACE("win %p\n", hwnd);
    if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
        grab_win32_clipboard(TRUE);
}


/**************************************************************************
 *              macdrv_init_clipboard
 */
void macdrv_init_clipboard(void)
{
    DWORD id;
    HANDLE handle = CreateThread(NULL, 0, clipboard_thread, NULL, 0, &id);

    if (handle) CloseHandle(handle);
    else ERR("failed to create clipboard thread\n");
}
