/*
 * 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 struct
{
    HWND hwnd_owner;
    UINT flags;
} CLIPBOARDINFO, *LPCLIPBOARDINFO;

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
 **************************************************************************/


/**************************************************************************
 *              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_enhmetafile_to_metafilepict(CFDataRef data);
static HANDLE import_metafilepict(CFDataRef data);
static HANDLE import_metafilepict_to_enhmetafile(CFDataRef data);
static HANDLE import_nsfilenames_to_hdrop(CFDataRef data);
static HANDLE import_oemtext_to_text(CFDataRef data);
static HANDLE import_oemtext_to_unicodetext(CFDataRef data);
static HANDLE import_text_to_oemtext(CFDataRef data);
static HANDLE import_text_to_unicodetext(CFDataRef data);
static HANDLE import_unicodetext_to_oemtext(CFDataRef data);
static HANDLE import_unicodetext_to_text(CFDataRef data);
static HANDLE import_utf8_to_oemtext(CFDataRef data);
static HANDLE import_utf8_to_text(CFDataRef data);
static HANDLE import_utf8_to_unicodetext(CFDataRef data);
static HANDLE import_utf16_to_oemtext(CFDataRef data);
static HANDLE import_utf16_to_text(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_metafilepict(HANDLE data);
static CFDataRef export_oemtext_to_utf8(HANDLE data);
static CFDataRef export_oemtext_to_utf16(HANDLE data);
static CFDataRef export_text_to_utf8(HANDLE data);
static CFDataRef export_text_to_utf16(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_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_DSPBITMAP,         CFSTR("org.winehq.builtin.dspbitmap"),          import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_DSPENHMETAFILE,    CFSTR("org.winehq.builtin.dspenhmetafile"),     import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_DSPMETAFILEPICT,   CFSTR("org.winehq.builtin.dspmetafilepict"),    import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_DSPTEXT,           CFSTR("org.winehq.builtin.dsptext"),            import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_LOCALE,            CFSTR("org.winehq.builtin.locale"),             import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_OWNERDISPLAY,      CFSTR("org.winehq.builtin.ownerdisplay"),       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_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_UNICODETEXT,       CFSTR("org.winehq.builtin.unicodetext"),        import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_TEXT,              CFSTR("org.winehq.builtin.unicodetext"),        import_unicodetext_to_text,     NULL,                       TRUE },
    { CF_OEMTEXT,           CFSTR("org.winehq.builtin.unicodetext"),        import_unicodetext_to_oemtext,  NULL,                       TRUE },

    { CF_TEXT,              CFSTR("org.winehq.builtin.text"),               import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_OEMTEXT,           CFSTR("org.winehq.builtin.text"),               import_text_to_oemtext,         NULL,                       TRUE },
    { CF_UNICODETEXT,       CFSTR("org.winehq.builtin.text"),               import_text_to_unicodetext,     NULL,                       TRUE },

    { CF_OEMTEXT,           CFSTR("org.winehq.builtin.oemtext"),            import_clipboard_data,          export_clipboard_data,      FALSE },
    { CF_TEXT,              CFSTR("org.winehq.builtin.oemtext"),            import_oemtext_to_text,         NULL,                       TRUE },
    { CF_UNICODETEXT,       CFSTR("org.winehq.builtin.oemtext"),            import_oemtext_to_unicodetext,  NULL,                       TRUE },

    { CF_TEXT,              CFSTR("public.utf8-plain-text"),                import_utf8_to_text,            export_text_to_utf8,        TRUE },
    { CF_OEMTEXT,           CFSTR("public.utf8-plain-text"),                import_utf8_to_oemtext,         export_oemtext_to_utf8,     TRUE },
    { CF_UNICODETEXT,       CFSTR("public.utf8-plain-text"),                import_utf8_to_unicodetext,     export_unicodetext_to_utf8, TRUE },

    { CF_TEXT,              CFSTR("public.utf16-plain-text"),                import_utf16_to_text,          export_text_to_utf16,       TRUE },
    { CF_OEMTEXT,           CFSTR("public.utf16-plain-text"),                import_utf16_to_oemtext,       export_oemtext_to_utf16,    TRUE },
    { CF_UNICODETEXT,       CFSTR("public.utf16-plain-text"),                import_utf16_to_unicodetext,   export_unicodetext_to_utf16,TRUE },

    { 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_BITMAP,            CFSTR("org.winehq.builtin.bitmap"),             import_bmp_to_bitmap,           export_bitmap_to_bmp,       FALSE },
    { CF_BITMAP,            CFSTR("com.microsoft.bmp"),                     import_bmp_to_bitmap,           export_bitmap_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_ENHMETAFILE,       CFSTR("org.winehq.builtin.enhmetafile"),        import_enhmetafile,                 export_enhmetafile,     FALSE },
    { CF_METAFILEPICT,      CFSTR("org.winehq.builtin.enhmetafile"),        import_enhmetafile_to_metafilepict, NULL,                   TRUE },

    { CF_METAFILEPICT,      CFSTR("org.winehq.builtin.metafilepict"),       import_metafilepict,                export_metafilepict,    FALSE },
    { CF_ENHMETAFILE,       CFSTR("org.winehq.builtin.metafilepict"),       import_metafilepict_to_enhmetafile, NULL,                   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;
} 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,        CFSTR("public.html"),                           import_clipboard_data,          export_clipboard_data },
    { 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.");


/**************************************************************************
 *              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);
}


/**************************************************************************
 *              format_for_type
 */
static WINE_CLIPFORMAT* format_for_type(WINE_CLIPFORMAT *current, CFStringRef type)
{
    struct list *ptr = current ? &current->entry : &format_list;
    WINE_CLIPFORMAT *format = NULL;

    TRACE("current %p/%s type %s\n", current, debugstr_format(current ? current->format_id : 0), debugstr_cf(type));

    while ((ptr = list_next(&format_list, ptr)))
    {
        format = LIST_ENTRY(ptr, WINE_CLIPFORMAT, entry);
        if (CFEqual(format->type, type))
            goto done;
    }

    format = NULL;
    if (!current)
    {
        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;
}


/**************************************************************************
 *              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;
}


/**************************************************************************
 *              convert_text
 *
 *  Convert string data between code pages or to/from wide characters.  The
 *  special value of (UINT)-1 for a code page indicates to use wide
 *  characters.
 */
static HANDLE convert_text(const void *src, int src_len, UINT src_cp, UINT dest_cp)
{
    HANDLE ret = NULL;
    const WCHAR *wstr;
    int wstr_len;
    HANDLE handle;
    char *p;

    if (src_cp == (UINT)-1)
    {
        wstr = src;
        wstr_len = src_len / sizeof(WCHAR);
    }
    else
    {
        WCHAR *temp;

        wstr_len = MultiByteToWideChar(src_cp, 0, src, src_len, NULL, 0);
        if (!src_len || ((const char*)src)[src_len - 1]) wstr_len += 1;
        temp = HeapAlloc(GetProcessHeap(), 0, wstr_len * sizeof(WCHAR));
        MultiByteToWideChar(src_cp, 0, src, src_len, temp, wstr_len);
        temp[wstr_len - 1] = 0;
        wstr = temp;
    }

    if (dest_cp == (UINT)-1)
    {
        handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wstr_len * sizeof(WCHAR));
        if (handle && (p = GlobalLock(handle)))
        {
            memcpy(p, wstr, wstr_len * sizeof(WCHAR));
            GlobalUnlock(handle);
            ret = handle;
        }
    }
    else
    {
        INT len;

        len = WideCharToMultiByte(dest_cp, 0, wstr, wstr_len, NULL, 0, NULL, NULL);
        if (!wstr_len || wstr[wstr_len - 1]) len += 1;
        handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len);

        if (handle && (p = GlobalLock(handle)))
        {
            WideCharToMultiByte(dest_cp, 0, wstr, wstr_len, p, len, NULL, NULL);
            p[len - 1] = 0;
            GlobalUnlock(handle);
            ret = handle;
        }
    }

    return ret;
}


/**************************************************************************
 *              convert_unicodetext_to_codepage
 */
static HANDLE convert_unicodetext_to_codepage(HANDLE unicode_handle, UINT cp)
{
    LPWSTR unicode_string = GlobalLock(unicode_handle);
    HANDLE ret = NULL;

    if (unicode_string)
    {
        ret = convert_text(unicode_string, GlobalSize(unicode_handle), -1, cp);
        GlobalUnlock(unicode_handle);
    }

    return ret;
}


/***********************************************************************
 *              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 = info->bmiHeader.biClrUsed;
        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 hBmp)
{
    BITMAP bmp;
    HDC hdc;
    HGLOBAL hPackedDIB;
    LPBYTE pPackedDIB;
    LPBITMAPINFOHEADER pbmiHeader;
    unsigned int cDataSize, cPackedSize, OffsetBits;
    int nLinesCopied;

    if (!GetObjectW(hBmp, sizeof(bmp), &bmp)) return 0;

    /*
     * A packed DIB contains a BITMAPINFO structure followed immediately by
     * an optional color palette and the pixel data.
     */

    /* Calculate the size of the packed DIB */
    cDataSize = abs(bmp.bmHeight) * (((bmp.bmWidth * bmp.bmBitsPixel + 31) / 8) & ~3);
    cPackedSize = sizeof(BITMAPINFOHEADER)
                  + ((bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0)
                  + cDataSize;
    /* Get the offset to the bits */
    OffsetBits = cPackedSize - cDataSize;

    /* Allocate the packed DIB */
    TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
    hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cPackedSize);
    if (!hPackedDIB)
    {
        WARN("Could not allocate packed DIB!\n");
        return 0;
    }

    /* A packed DIB starts with a BITMAPINFOHEADER */
    pPackedDIB = GlobalLock(hPackedDIB);
    pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;

    /* Init the BITMAPINFOHEADER */
    pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
    pbmiHeader->biWidth = bmp.bmWidth;
    pbmiHeader->biHeight = bmp.bmHeight;
    pbmiHeader->biPlanes = 1;
    pbmiHeader->biBitCount = bmp.bmBitsPixel;
    pbmiHeader->biCompression = BI_RGB;
    pbmiHeader->biSizeImage = 0;
    pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
    pbmiHeader->biClrUsed = 0;
    pbmiHeader->biClrImportant = 0;

    /* Retrieve the DIB bits from the bitmap and fill in the
     * DIB color table if present */
    hdc = GetDC(0);
    nLinesCopied = GetDIBits(hdc,                       /* Handle to device context */
                             hBmp,                      /* Handle to bitmap */
                             0,                         /* First scan line to set in dest bitmap */
                             bmp.bmHeight,              /* Number of scan lines to copy */
                             pPackedDIB + OffsetBits,   /* [out] Address of array for bitmap bits */
                             (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
                             0);                        /* RGB or palette index */
    GlobalUnlock(hPackedDIB);
    ReleaseDC(0, hdc);

    /* Cleanup if GetDIBits failed */
    if (nLinesCopied != bmp.bmHeight)
    {
        TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
        GlobalFree(hPackedDIB);
        hPackedDIB = 0;
    }
    return hPackedDIB;
}


/**************************************************************************
 *              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_MOVEABLE | GMEM_DDESHARE, 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 = 0;
    HANDLE dib = import_bmp_to_dib(data);
    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);
    }

    GlobalFree(dib);
    return ret;
}


/**************************************************************************
 *              import_bmp_to_dib
 *
 *  Import BMP data, converting to CF_DIB 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_MOVEABLE | GMEM_DDESHARE, 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_enhmetafile_to_metafilepict
 *
 *  Import enhanced metafile data, converting it to CF_METAFILEPICT.
 */
static HANDLE import_enhmetafile_to_metafilepict(CFDataRef data)
{
    HANDLE ret = 0, hmf;
    HANDLE hemf;
    METAFILEPICT *mfp;

    if ((hmf = GlobalAlloc(0, sizeof(*mfp))) && (hemf = import_enhmetafile(data)))
    {
        ENHMETAHEADER header;
        HDC hdc = CreateCompatibleDC(0);
        unsigned int size = GetWinMetaFileBits(hemf, 0, NULL, MM_ISOTROPIC, hdc);
        BYTE *bytes;

        bytes = HeapAlloc(GetProcessHeap(), 0, size);
        if (bytes && GetEnhMetaFileHeader(hemf, sizeof(header), &header) &&
            GetWinMetaFileBits(hemf, size, bytes, MM_ISOTROPIC, hdc))
        {
            mfp = GlobalLock(hmf);
            mfp->mm = MM_ISOTROPIC;
            mfp->xExt = header.rclFrame.right - header.rclFrame.left;
            mfp->yExt = header.rclFrame.bottom - header.rclFrame.top;
            mfp->hMF = SetMetaFileBitsEx(size, bytes);
            GlobalUnlock(hmf);

            ret = hmf;
        }

        if (hdc) DeleteDC(hdc);
        HeapFree(GetProcessHeap(), 0, bytes);
        DeleteEnhMetaFile(hemf);
    }

    if (!ret) GlobalFree(hmf);
    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(0, 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_metafilepict_to_enhmetafile
 *
 *  Import metafile picture data, converting it to CF_ENHMETAFILE.
 */
static HANDLE import_metafilepict_to_enhmetafile(CFDataRef data)
{
    HANDLE ret = 0;
    CFIndex len = CFDataGetLength(data);
    const METAFILEPICT *mfp;

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

    if (len >= sizeof(*mfp))
    {
        mfp = (const METAFILEPICT*)CFDataGetBytePtr(data);
        ret = SetWinMetaFileBits(len - sizeof(*mfp), (const BYTE*)(mfp + 1), NULL, mfp);
    }

    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_MOVEABLE | GMEM_DDESHARE, 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_oemtext_to_text
 *
 *  Import CF_OEMTEXT data, converting the string to CF_TEXT.
 */
static HANDLE import_oemtext_to_text(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_OEMCP, CP_ACP);
}


/**************************************************************************
 *              import_oemtext_to_unicodetext
 *
 *  Import CF_OEMTEXT data, converting the string to CF_UNICODETEXT.
 */
static HANDLE import_oemtext_to_unicodetext(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_OEMCP, -1);
}


/**************************************************************************
 *              import_text_to_oemtext
 *
 *  Import CF_TEXT data, converting the string to CF_OEMTEXT.
 */
static HANDLE import_text_to_oemtext(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_ACP, CP_OEMCP);
}


/**************************************************************************
 *              import_text_to_unicodetext
 *
 *  Import CF_TEXT data, converting the string to CF_UNICODETEXT.
 */
static HANDLE import_text_to_unicodetext(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), CP_ACP, -1);
}


/**************************************************************************
 *              import_unicodetext_to_oemtext
 *
 *  Import a CF_UNICODETEXT string, converting the string to CF_OEMTEXT.
 */
static HANDLE import_unicodetext_to_oemtext(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), -1, CP_OEMCP);
}


/**************************************************************************
 *              import_unicodetext_to_text
 *
 *  Import a CF_UNICODETEXT string, converting the string to CF_TEXT.
 */
static HANDLE import_unicodetext_to_text(CFDataRef data)
{
    return convert_text(CFDataGetBytePtr(data), CFDataGetLength(data), -1, CP_ACP);
}


/**************************************************************************
 *              import_utf8_to_oemtext
 *
 *  Import a UTF-8 string, converting the string to CF_OEMTEXT.
 */
static HANDLE import_utf8_to_oemtext(CFDataRef data)
{
    HANDLE unicode_handle = import_utf8_to_unicodetext(data);
    HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_OEMCP);

    GlobalFree(unicode_handle);
    return ret;
}


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

    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_MOVEABLE | GMEM_DDESHARE, 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_oemtext
 *
 *  Import a UTF-16 string, converting the string to CF_OEMTEXT.
 */
static HANDLE import_utf16_to_oemtext(CFDataRef data)
{
    HANDLE unicode_handle = import_utf16_to_unicodetext(data);
    HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_OEMCP);

    GlobalFree(unicode_handle);
    return ret;
}


/**************************************************************************
 *              import_utf16_to_text
 *
 *  Import a UTF-16 string, converting the string to CF_TEXT.
 */
static HANDLE import_utf16_to_text(CFDataRef data)
{
    HANDLE unicode_handle = import_utf16_to_unicodetext(data);
    HANDLE ret = convert_unicodetext_to_codepage(unicode_handle, CP_ACP);

    GlobalFree(unicode_handle);
    return ret;
}


/**************************************************************************
 *              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++;
    }

    if ((unicode_handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (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];
        }
        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_codepage_to_utf8
 *
 *  Export string data in a specified codepage to UTF-8.
 */
static CFDataRef export_codepage_to_utf8(HANDLE data, UINT cp)
{
    CFDataRef ret = NULL;
    const char* str;

    if ((str = GlobalLock(data)))
    {
        HANDLE unicode = convert_text(str, GlobalSize(data), cp, -1);

        ret = export_unicodetext_to_utf8(unicode);

        GlobalFree(unicode);
        GlobalUnlock(data);
    }

    return ret;
}


/**************************************************************************
 *              export_codepage_to_utf16
 *
 *  Export string data in a specified codepage to UTF-16.
 */
static CFDataRef export_codepage_to_utf16(HANDLE data, UINT cp)
{
    CFDataRef ret = NULL;
    const char* str;

    if ((str = GlobalLock(data)))
    {
        HANDLE unicode = convert_text(str, GlobalSize(data), cp, -1);

        ret = export_unicodetext_to_utf16(unicode);

        GlobalFree(unicode);
        GlobalUnlock(data);
    }

    return ret;
}


/**************************************************************************
 *              export_dib_to_bmp
 *
 *  Export CF_DIB 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_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_oemtext_to_utf8
 *
 *  Export CF_OEMTEXT to UTF-8.
 */
static CFDataRef export_oemtext_to_utf8(HANDLE data)
{
    return export_codepage_to_utf8(data, CP_OEMCP);
}


/**************************************************************************
 *              export_oemtext_to_utf16
 *
 *  Export CF_OEMTEXT to UTF-16.
 */
static CFDataRef export_oemtext_to_utf16(HANDLE data)
{
    return export_codepage_to_utf16(data, CP_OEMCP);
}


/**************************************************************************
 *              export_text_to_utf8
 *
 *  Export CF_TEXT to UTF-8.
 */
static CFDataRef export_text_to_utf8(HANDLE data)
{
    return export_codepage_to_utf8(data, CP_ACP);
}


/**************************************************************************
 *              export_text_to_utf16
 *
 *  Export CF_TEXT to UTF-16.
 */
static CFDataRef export_text_to_utf16(HANDLE data)
{
    return export_codepage_to_utf16(data, CP_ACP);
}


/**************************************************************************
 *              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;
}


/**************************************************************************
 *              get_clipboard_info
 */
static BOOL get_clipboard_info(LPCLIPBOARDINFO cbinfo)
{
    BOOL ret = FALSE;

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

        if (wine_server_call_err(req))
        {
            ERR("Failed to get clipboard owner.\n");
        }
        else
        {
            cbinfo->hwnd_owner = wine_server_ptr_handle(reply->old_owner);
            cbinfo->flags = reply->flags;

            ret = TRUE;
        }
    }
    SERVER_END_REQ;

    return ret;
}


/**************************************************************************
 *              release_ownership
 */
static BOOL release_ownership(void)
{
    BOOL ret = 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
            ret = TRUE;
    }
    SERVER_END_REQ;

    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);

        format = NULL;
        while ((!best_format || best_format->synthesized) && (format = format_for_type(format, type)))
        {
            TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format ? format->format_id : 0));

            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; !found && i < count; i++)
    {
        CFStringRef type = CFArrayGetValueAtIndex(types, i);
        WINE_CLIPFORMAT* format;

        format = NULL;
        while (!found && (format = format_for_type(format, type)))
        {
            TRACE("for type %s got format %s\n", debugstr_cf(type), debugstr_format(format->format_id));

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

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


/**************************************************************************
 *              macdrv_copy_pasteboard_formats
 */
CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard)
{
    CFArrayRef types;
    CFIndex count;
    CFMutableArrayRef formats;
    CFIndex i;
    WINE_CLIPFORMAT* format;

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

    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);

    if (!count)
    {
        CFRelease(types);
        return NULL;
    }

    formats = CFArrayCreateMutable(NULL, 0, NULL);
    if (!formats)
    {
        WARN("Failed to allocate formats array\n");
        CFRelease(types);
        return NULL;
    }

    for (i = 0; i < count; i++)
    {
        CFStringRef type = CFArrayGetValueAtIndex(types, i);
        BOOL found = FALSE;

        format = NULL;
        while ((format = format_for_type(format, type)))
        {
            /* Suppose type is "public.utf8-plain-text".  format->format_id will be each of
               CF_TEXT, CF_OEMTEXT, and CF_UNICODETEXT in turn.  We want to look up the natural
               type for each of those IDs (e.g. CF_TEXT -> "org.winehq.builtin.text") and then see
               if that type is present in the pasteboard.  If it is, then we don't want to add the
               format to the list yet because it would be out of order.

               For example, if a Mac app put "public.utf8-plain-text" and "public.tiff" on the
               pasteboard, then we want the Win32 clipboard formats to be CF_TEXT, CF_OEMTEXT, and
               CF_UNICODETEXT, and CF_TIFF, in that order.  All of the text formats belong before
               CF_TIFF because the Mac app expressed that text was "better" than the TIFF.  In
               this case, as soon as we encounter "public.utf8-plain-text" we should add all of
               the associated text format IDs.

               But if a Wine process put "org.winehq.builtin.unicodetext",
               "public.utf8-plain-text", "public.utf16-plain-text", and "public.tiff", then we
               want the clipboard formats to be CF_UNICODETEXT, CF_TIFF, CF_TEXT, and CF_OEMTEXT,
               in that order.  The Windows program presumably added CF_UNICODETEXT and CF_TIFF.
               We're synthesizing CF_TEXT and CF_OEMTEXT from CF_UNICODETEXT but we want them to
               come after the non-synthesized CF_TIFF.  In this case, we don't want to add the
               text formats upon encountering "public.utf8-plain-text",

               We tell the two cases apart by seeing that one of the natural types for the text
               formats (i.e. "org.winehq.builtin.unicodetext") is present on the pasteboard.
               "found" indicates that. */

            if (!format->synthesized)
            {
                TRACE("for type %s got primary format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
                CFArrayAppendValue(formats, (void*)format->format_id);
                found = TRUE;
            }
            else if (!found && 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));
                found = TRUE;
            }
        }

        if (!found)
        {
            while ((format = format_for_type(format, type)))
            {
                /* Don't override a real value with a synthesized value. */
                if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id))
                {
                    TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
                    CFArrayAppendValue(formats, (void*)format->format_id);
                }
            }
        }
    }

    /* 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);

        format = NULL;
        while ((format = format_for_type(format, type)))
        {
            if (format->synthesized)
            {
                /* Don't override a real value with a synthesized value. */
                if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id))
                {
                    TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
                    CFArrayAppendValue(formats, (void*)format->format_id);
                }
            }
        }
    }

    CFRelease(types);

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


/**************************************************************************
 *              check_clipboard_ownership
 */
static void check_clipboard_ownership(HWND *owner)
{
    CLIPBOARDINFO cbinfo;

    if (owner) *owner = NULL;

    /* If Wine thinks we're the clipboard owner but Mac OS X thinks we're not
       the pasteboard owner, update Wine. */
    if (get_clipboard_info(&cbinfo) && (cbinfo.flags & CB_PROCESS))
    {
        if (!(cbinfo.flags & CB_OPEN) && !macdrv_is_pasteboard_owner())
        {
            TRACE("Lost clipboard ownership\n");

            if (OpenClipboard(cbinfo.hwnd_owner))
            {
                /* Destroy private objects */
                SendMessageW(cbinfo.hwnd_owner, WM_DESTROYCLIPBOARD, 0, 0);

                /* Give up ownership of the windows clipboard */
                release_ownership();
                CloseClipboard();
            }
        }
        else if (owner)
            *owner = cbinfo.hwnd_owner;
    }
}


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


/**************************************************************************
 *              AcquireClipboard (MACDRV.@)
 */
int CDECL macdrv_AcquireClipboard(HWND hwnd)
{
    TRACE("hwnd %p\n", hwnd);
    check_clipboard_ownership(NULL);
    return 0;
}


/**************************************************************************
 *              CountClipboardFormats (MACDRV.@)
 */
INT CDECL macdrv_CountClipboardFormats(void)
{
    CFMutableSetRef seen_formats;
    CFArrayRef types;
    CFIndex count;
    CFIndex i;
    INT ret = 0;

    TRACE("()\n");
    check_clipboard_ownership(NULL);

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

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

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

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

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

            if (!CFSetContainsValue(seen_formats, (void*)format->format_id))
            {
                ret++;
                CFSetAddValue(seen_formats, (void*)format->format_id);
            }
        }
    }

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


/**************************************************************************
 *              EmptyClipboard (MACDRV.@)
 *
 * Empty cached clipboard data.
 */
void CDECL macdrv_EmptyClipboard(BOOL keepunowned)
{
    TRACE("keepunowned %d\n", keepunowned);
    macdrv_clear_pasteboard();
}


/**************************************************************************
 *              EndClipboardUpdate (MACDRV.@)
 */
void CDECL macdrv_EndClipboardUpdate(void)
{
    TRACE("()\n");
    check_clipboard_ownership(NULL);
}


/**************************************************************************
 *              EnumClipboardFormats (MACDRV.@)
 */
UINT CDECL macdrv_EnumClipboardFormats(UINT prev_format)
{
    CFArrayRef formats;
    CFIndex count;
    CFIndex i;
    UINT ret = 0;

    TRACE("prev_format %s\n", debugstr_format(prev_format));
    check_clipboard_ownership(NULL);

    formats = macdrv_copy_pasteboard_formats(NULL);
    if (formats)
    {
        count = CFArrayGetCount(formats);
        if (prev_format)
        {
            i = CFArrayGetFirstIndexOfValue(formats, CFRangeMake(0, count), (void*)prev_format);
            if (i != kCFNotFound)
                i++;
        }
        else
            i = 0;

        if (i != kCFNotFound && i < count)
            ret = (UINT)CFArrayGetValueAtIndex(formats, i);

        CFRelease(formats);
    }

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


/**************************************************************************
 *              GetClipboardData (MACDRV.@)
 */
HANDLE CDECL macdrv_GetClipboardData(UINT desired_format)
{
    check_clipboard_ownership(NULL);

    return macdrv_get_pasteboard_data(NULL, desired_format);
}


/**************************************************************************
 *              IsClipboardFormatAvailable (MACDRV.@)
 */
BOOL CDECL macdrv_IsClipboardFormatAvailable(UINT desired_format)
{
    check_clipboard_ownership(NULL);
    return macdrv_pasteboard_has_format(NULL, desired_format);
}


/**************************************************************************
 *              SetClipboardData (MACDRV.@)
 */
BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner)
{
    HWND hwnd_owner;
    macdrv_window window;
    WINE_CLIPFORMAT *format;
    CFDataRef cfdata = NULL;

    check_clipboard_ownership(&hwnd_owner);
    window = macdrv_get_cocoa_window(GetAncestor(hwnd_owner, GA_ROOT), FALSE);
    TRACE("format_id %s data %p owner %d hwnd_owner %p window %p)\n", debugstr_format(format_id), data, owner, hwnd_owner, window);

    format = natural_format_for_format(format_id);
    if (!format && !(format = insert_clipboard_format(format_id, NULL)))
    {
        WARN("Failed to register clipboard format %s\n", debugstr_format(format_id));
        return FALSE;
    }

    /* Export the data to the Mac pasteboard. */
    if (data)
    {
        if (!format->export_func || !(cfdata = format->export_func(data)))
        {
            WARN("Failed to export %s data to type %s\n", debugstr_format(format_id), debugstr_cf(format->type));
            return FALSE;
        }
    }

    if (macdrv_set_pasteboard_data(format->type, cfdata, window))
        TRACE("Set pasteboard data for type %s: %s\n", debugstr_cf(format->type), debugstr_cf(cfdata));
    else
    {
        WARN("Failed to set pasteboard data for type %s: %s\n", debugstr_cf(format->type), debugstr_cf(cfdata));
        if (cfdata) CFRelease(cfdata);
        return FALSE;
    }

    if (cfdata) CFRelease(cfdata);

    /* Find any other formats for this format_id (the exportable synthesized ones). */
    LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
    {
        if (format->format_id == format_id && format->synthesized && format->export_func)
        {
            /* We have a synthesized format for this format ID.  Add its type to the pasteboard. */
            TRACE("Synthesized from format %s: type %s\n", debugstr_format(format_id), debugstr_cf(format->type));

            if (data)
            {
                cfdata = format->export_func(data);
                if (!cfdata)
                {
                    WARN("Failed to export %s data to type %s\n", debugstr_format(format->format_id), debugstr_cf(format->type));
                    continue;
                }
            }
            else
                cfdata = NULL;

            if (macdrv_set_pasteboard_data(format->type, cfdata, window))
                TRACE("    ... set pasteboard data: %s\n", debugstr_cf(cfdata));
            else
                WARN("    ... failed to set pasteboard data: %s\n", debugstr_cf(cfdata));

            if (cfdata) CFRelease(cfdata);
        }
    }

    if (data)
    {
        /* FIXME: According to MSDN, the caller is entitled to lock and read from
           data until CloseClipboard is called.  So, we should defer this cleanup. */
        if ((format_id >= CF_GDIOBJFIRST && format_id <= CF_GDIOBJLAST) ||
            format_id == CF_BITMAP ||
            format_id == CF_DIB ||
            format_id == CF_PALETTE)
        {
            DeleteObject(data);
        }
        else if (format_id == CF_METAFILEPICT)
        {
            DeleteMetaFile(((METAFILEPICT *)GlobalLock(data))->hMF);
            GlobalFree(data);
        }
        else if (format_id == CF_ENHMETAFILE)
        {
            DeleteEnhMetaFile(data);
        }
        else if (format_id < CF_PRIVATEFIRST || CF_PRIVATELAST < format_id)
        {
            GlobalFree(data);
        }
    }

    return TRUE;
}


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


/**************************************************************************
 *              macdrv_clipboard_process_attach
 */
void macdrv_clipboard_process_attach(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);
    }

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

    /* 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->type            = CFRetain(builtin_format_names[i].type);
        format->import_func     = builtin_format_names[i].import;
        format->export_func     = builtin_format_names[i].export;
        format->synthesized     = FALSE;
        format->natural_format  = NULL;
        list_add_tail(&format_list, &format->entry);
    }
}


/**************************************************************************
 *              query_pasteboard_data
 */
BOOL query_pasteboard_data(HWND hwnd, CFStringRef type)
{
    BOOL ret = FALSE;
    CLIPBOARDINFO cbinfo;
    WINE_CLIPFORMAT* format;
    CFArrayRef types = NULL;
    CFRange range;

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

    if (get_clipboard_info(&cbinfo))
        hwnd = cbinfo.hwnd_owner;

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

        if (!format->synthesized)
        {
            TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd);
            SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0);
            ret = TRUE;
            goto done;
        }

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

            range = CFRangeMake(0, CFArrayGetCount(types));
        }

        /* The type maps to a synthesized format.  Now look up what type that format maps to natively
           (not synthesized).  For example, if type is "public.utf8-plain-text", then this format may
           have an ID of CF_TEXT.  From CF_TEXT, we want to find "org.winehq.builtin.text" to see if
           that type is present in the pasteboard.  If it is, then the app must have promised it and
           we can ask it to render it.  (If it had put it on the clipboard immediately, then the
           pasteboard would also have data for "public.utf8-plain-text" and we wouldn't be here.)  If
           "org.winehq.builtin.text" is not on the pasteboard, then one of the other text formats is
           presumably responsible for the promise that we're trying to satisfy, so we keep looking. */
        if (format->natural_format && CFArrayContainsValue(types, range, format->natural_format->type))
        {
            TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd);
            SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0);
            ret = TRUE;
            goto done;
        }
    }

done:
    if (types) CFRelease(types);

    return ret;
}
