/*
 * MACDRV mouse driver
 *
 * Copyright 1998 Ulrich Weigand
 * Copyright 2007 Henri Verbeet
 * 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"
#define OEMRESOURCE
#include "winuser.h"
#include "winreg.h"
#include "wine/server.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(cursor);


static CRITICAL_SECTION cursor_cache_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &cursor_cache_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": cursor_cache_section") }
};
static CRITICAL_SECTION cursor_cache_section = { &critsect_debug, -1, 0, 0, 0, 0 };

static CFMutableDictionaryRef cursor_cache;


struct system_cursors
{
    WORD id;
    CFStringRef name;
};

static const struct system_cursors user32_cursors[] =
{
    { OCR_NORMAL,      CFSTR("arrowCursor") },
    { OCR_IBEAM,       CFSTR("IBeamCursor") },
    { OCR_CROSS,       CFSTR("crosshairCursor") },
    { OCR_SIZEWE,      CFSTR("resizeLeftRightCursor") },
    { OCR_SIZENS,      CFSTR("resizeUpDownCursor") },
    { OCR_NO,          CFSTR("operationNotAllowedCursor") },
    { OCR_HAND,        CFSTR("pointingHandCursor") },
    { 0 }
};

static const struct system_cursors comctl32_cursors[] =
{
    { 102, CFSTR("closedHandCursor") },
    { 104, CFSTR("dragCopyCursor") },
    { 105, CFSTR("arrowCursor") },
    { 106, CFSTR("resizeLeftRightCursor") },
    { 107, CFSTR("resizeLeftRightCursor") },
    { 108, CFSTR("pointingHandCursor") },
    { 135, CFSTR("resizeUpDownCursor") },
    { 0 }
};

static const struct system_cursors ole32_cursors[] =
{
    { 1, CFSTR("operationNotAllowedCursor") },
    { 2, CFSTR("closedHandCursor") },
    { 3, CFSTR("dragCopyCursor") },
    { 4, CFSTR("dragLinkCursor") },
    { 0 }
};

static const struct system_cursors riched20_cursors[] =
{
    { 105, CFSTR("pointingHandCursor") },
    { 109, CFSTR("dragCopyCursor") },
    { 110, CFSTR("closedHandCursor") },
    { 111, CFSTR("operationNotAllowedCursor") },
    { 0 }
};

static const struct
{
    const struct system_cursors *cursors;
    WCHAR name[16];
} module_cursors[] =
{
    { user32_cursors, {'u','s','e','r','3','2','.','d','l','l',0} },
    { comctl32_cursors, {'c','o','m','c','t','l','3','2','.','d','l','l',0} },
    { ole32_cursors, {'o','l','e','3','2','.','d','l','l',0} },
    { riched20_cursors, {'r','i','c','h','e','d','2','0','.','d','l','l',0} }
};

/* The names of NSCursor class methods which return cursor objects. */
static const CFStringRef cocoa_cursor_names[] =
{
    CFSTR("arrowCursor"),
    CFSTR("closedHandCursor"),
    CFSTR("contextualMenuCursor"),
    CFSTR("crosshairCursor"),
    CFSTR("disappearingItemCursor"),
    CFSTR("dragCopyCursor"),
    CFSTR("dragLinkCursor"),
    CFSTR("IBeamCursor"),
    CFSTR("IBeamCursorForVerticalLayout"),
    CFSTR("openHandCursor"),
    CFSTR("operationNotAllowedCursor"),
    CFSTR("pointingHandCursor"),
    CFSTR("resizeDownCursor"),
    CFSTR("resizeLeftCursor"),
    CFSTR("resizeLeftRightCursor"),
    CFSTR("resizeRightCursor"),
    CFSTR("resizeUpCursor"),
    CFSTR("resizeUpDownCursor"),
};


/***********************************************************************
 *              send_mouse_input
 *
 * Update the various window states on a mouse event.
 */
static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, int x, int y,
                             DWORD mouse_data, BOOL drag, unsigned long time)
{
    INPUT input;
    HWND top_level_hwnd;

    top_level_hwnd = GetAncestor(hwnd, GA_ROOT);

    if ((flags & MOUSEEVENTF_MOVE) && (flags & MOUSEEVENTF_ABSOLUTE) && !drag &&
        cocoa_window != macdrv_thread_data()->capture_window)
    {
        RECT rect;

        /* update the wine server Z-order */
        SetRect(&rect, x, y, x + 1, y + 1);
        MapWindowPoints(0, top_level_hwnd, (POINT *)&rect, 2);

        SERVER_START_REQ(update_window_zorder)
        {
            req->window      = wine_server_user_handle(top_level_hwnd);
            req->rect.left   = rect.left;
            req->rect.top    = rect.top;
            req->rect.right  = rect.right;
            req->rect.bottom = rect.bottom;
            wine_server_call(req);
        }
        SERVER_END_REQ;
    }

    input.type              = INPUT_MOUSE;
    input.mi.dx             = x;
    input.mi.dy             = y;
    input.mi.mouseData      = mouse_data;
    input.mi.dwFlags        = flags;
    input.mi.time           = time;
    input.mi.dwExtraInfo    = 0;

    __wine_send_input(top_level_hwnd, &input);
}


/***********************************************************************
 *              copy_system_cursor_name
 */
CFStringRef copy_system_cursor_name(ICONINFOEXW *info)
{
    static const WCHAR idW[] = {'%','h','u',0};
    const struct system_cursors *cursors;
    unsigned int i;
    CFStringRef cursor_name = NULL;
    HMODULE module;
    HKEY key;
    WCHAR *p, name[MAX_PATH * 2];

    TRACE("info->szModName %s info->szResName %s info->wResID %hu\n", debugstr_w(info->szModName),
          debugstr_w(info->szResName), info->wResID);

    if (!info->szModName[0]) return NULL;

    p = strrchrW(info->szModName, '\\');
    strcpyW(name, p ? p + 1 : info->szModName);
    p = name + strlenW(name);
    *p++ = ',';
    if (info->szResName[0]) strcpyW(p, info->szResName);
    else sprintfW(p, idW, info->wResID);

    /* @@ Wine registry key: HKCU\Software\Wine\Mac Driver\Cursors */
    if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Mac Driver\\Cursors", &key))
    {
        WCHAR value[64];
        DWORD size, ret;

        value[0] = 0;
        size = sizeof(value) / sizeof(WCHAR);
        ret = RegQueryValueExW(key, name, NULL, NULL, (BYTE *)value, &size);
        RegCloseKey(key);
        if (!ret)
        {
            if (!value[0])
            {
                TRACE("registry forces standard cursor for %s\n", debugstr_w(name));
                return NULL; /* force standard cursor */
            }

            cursor_name = CFStringCreateWithCharacters(NULL, value, strlenW(value));
            if (!cursor_name)
            {
                WARN("CFStringCreateWithCharacters failed for %s\n", debugstr_w(value));
                return NULL;
            }

            /* Make sure it's one of the appropriate NSCursor class methods. */
            for (i = 0; i < sizeof(cocoa_cursor_names) / sizeof(cocoa_cursor_names[0]); i++)
                if (CFEqual(cursor_name, cocoa_cursor_names[i]))
                    goto done;

            WARN("%s mapped to invalid Cocoa cursor name %s\n", debugstr_w(name), debugstr_w(value));
            CFRelease(cursor_name);
            return NULL;
        }
    }

    if (info->szResName[0]) goto done;  /* only integer resources are supported here */
    if (!(module = GetModuleHandleW(info->szModName))) goto done;

    for (i = 0; i < sizeof(module_cursors)/sizeof(module_cursors[0]); i++)
        if (GetModuleHandleW(module_cursors[i].name) == module) break;
    if (i == sizeof(module_cursors)/sizeof(module_cursors[0])) goto done;

    cursors = module_cursors[i].cursors;
    for (i = 0; cursors[i].id; i++)
        if (cursors[i].id == info->wResID)
        {
            cursor_name = CFRetain(cursors[i].name);
            break;
        }

done:
    if (cursor_name)
        TRACE("%s -> %s\n", debugstr_w(name), debugstr_cf(cursor_name));
    else
        WARN("no system cursor found for %s\n", debugstr_w(name));
    return cursor_name;
}

/***********************************************************************
 *              create_monochrome_cursor
 */
CFArrayRef create_monochrome_cursor(HDC hdc, const ICONINFOEXW *icon, int width, int height)
{
    char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    unsigned int width_bytes = (width + 31) / 32 * 4;
    unsigned long *and_bits = NULL, *xor_bits;
    unsigned long *data_bits;
    int count, i;
    CGColorSpaceRef colorspace;
    CFMutableDataRef data;
    CGDataProviderRef provider;
    CGImageRef cgimage, cgmask, cgmasked;
    CGPoint hot_spot;
    CFDictionaryRef hot_spot_dict;
    const CFStringRef keys[] = { CFSTR("image"), CFSTR("hotSpot") };
    CFTypeRef values[sizeof(keys) / sizeof(keys[0])];
    CFDictionaryRef frame;
    CFArrayRef frames;

    TRACE("hdc %p icon->hbmMask %p icon->xHotspot %d icon->yHotspot %d width %d height %d\n",
          hdc, icon->hbmMask, icon->xHotspot, icon->yHotspot, width, height);

    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info->bmiHeader.biWidth = width;
    info->bmiHeader.biHeight = -height * 2;
    info->bmiHeader.biPlanes = 1;
    info->bmiHeader.biBitCount = 1;
    info->bmiHeader.biCompression = BI_RGB;
    info->bmiHeader.biSizeImage = width_bytes * height * 2;
    info->bmiHeader.biXPelsPerMeter = 0;
    info->bmiHeader.biYPelsPerMeter = 0;
    info->bmiHeader.biClrUsed = 0;
    info->bmiHeader.biClrImportant = 0;

    and_bits = HeapAlloc(GetProcessHeap(), 0, info->bmiHeader.biSizeImage);
    if (!and_bits)
    {
        WARN("failed to allocate and_bits\n");
        return NULL;
    }
    xor_bits = (unsigned long*)((char*)and_bits + info->bmiHeader.biSizeImage / 2);

    if (!GetDIBits(hdc, icon->hbmMask, 0, height * 2, and_bits, info, DIB_RGB_COLORS))
    {
        WARN("GetDIBits failed\n");
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    /* On Windows, the pixels of a monochrome cursor can have four effects:
       draw black, draw white, leave unchanged (transparent), or invert.  The Mac
       only supports the first three.  It can't do pixels which invert the
       background.  Since the background is usually white, I am arbitrarily
       mapping "invert" to "draw black".  This entails bitwise math between the
       cursor's AND mask and XOR mask:

            AND | XOR | Windows cursor pixel
            --------------------------------
             0  |  0  | black
             0  |  1  | white
             1  |  0  | transparent
             1  |  1  | invert

            AND | XOR | Mac image
            ---------------------
             0  |  0  | black (0)
             0  |  1  | white (1)
             1  |  0  | don't care
             1  |  1  | black (0)

            AND | XOR | Mac mask
            ---------------------------
             0  |  0  | paint (0)
             0  |  1  | paint (0)
             1  |  0  | don't paint (1)
             1  |  1  | paint (0)

       So, Mac image = AND ^ XOR and Mac mask = AND & ~XOR.
      */
    /* Create data for Mac image. */
    data = CFDataCreateMutable(NULL, info->bmiHeader.biSizeImage / 2);
    if (!data)
    {
        WARN("failed to create data\n");
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    /* image data = AND mask */
    CFDataAppendBytes(data, (UInt8*)and_bits, info->bmiHeader.biSizeImage / 2);
    /* image data ^= XOR mask */
    data_bits = (unsigned long*)CFDataGetMutableBytePtr(data);
    count = (info->bmiHeader.biSizeImage / 2) / sizeof(*data_bits);
    for (i = 0; i < count; i++)
        data_bits[i] ^= xor_bits[i];

    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
    if (!colorspace)
    {
        WARN("failed to create colorspace\n");
        CFRelease(data);
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    provider = CGDataProviderCreateWithCFData(data);
    CFRelease(data);
    if (!provider)
    {
        WARN("failed to create data provider\n");
        CGColorSpaceRelease(colorspace);
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    cgimage = CGImageCreate(width, height, 1, 1, width_bytes, colorspace,
                            kCGImageAlphaNone | kCGBitmapByteOrderDefault,
                            provider, NULL, FALSE, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorspace);
    if (!cgimage)
    {
        WARN("failed to create image\n");
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    /* Create data for mask. */
    data = CFDataCreateMutable(NULL, info->bmiHeader.biSizeImage / 2);
    if (!data)
    {
        WARN("failed to create data\n");
        CGImageRelease(cgimage);
        HeapFree(GetProcessHeap(), 0, and_bits);
        return NULL;
    }

    /* mask data = AND mask */
    CFDataAppendBytes(data, (UInt8*)and_bits, info->bmiHeader.biSizeImage / 2);
    /* mask data &= ~XOR mask */
    data_bits = (unsigned long*)CFDataGetMutableBytePtr(data);
    for (i = 0; i < count; i++)
        data_bits[i] &= ~xor_bits[i];
    HeapFree(GetProcessHeap(), 0, and_bits);

    provider = CGDataProviderCreateWithCFData(data);
    CFRelease(data);
    if (!provider)
    {
        WARN("failed to create data provider\n");
        CGImageRelease(cgimage);
        return NULL;
    }

    cgmask = CGImageMaskCreate(width, height, 1, 1, width_bytes, provider, NULL, FALSE);
    CGDataProviderRelease(provider);
    if (!cgmask)
    {
        WARN("failed to create mask image\n");
        CGImageRelease(cgimage);
        return NULL;
    }

    cgmasked = CGImageCreateWithMask(cgimage, cgmask);
    CGImageRelease(cgimage);
    CGImageRelease(cgmask);
    if (!cgmasked)
    {
        WARN("failed to create masked image\n");
        return NULL;
    }

    hot_spot = CGPointMake(icon->xHotspot, icon->yHotspot);
    hot_spot_dict = CGPointCreateDictionaryRepresentation(hot_spot);
    if (!hot_spot_dict)
    {
        WARN("failed to create hot spot dictionary\n");
        CGImageRelease(cgmasked);
        return NULL;
    }

    values[0] = cgmasked;
    values[1] = hot_spot_dict;
    frame = CFDictionaryCreate(NULL, (const void**)keys, values, sizeof(keys) / sizeof(keys[0]),
                               &kCFCopyStringDictionaryKeyCallBacks,
                               &kCFTypeDictionaryValueCallBacks);
    CFRelease(hot_spot_dict);
    CGImageRelease(cgmasked);
    if (!frame)
    {
        WARN("failed to create frame dictionary\n");
        return NULL;
    }

    frames = CFArrayCreate(NULL, (const void**)&frame, 1, &kCFTypeArrayCallBacks);
    CFRelease(frame);
    if (!frames)
    {
        WARN("failed to create frames array\n");
        return NULL;
    }

    return frames;
}


/***********************************************************************
 *              create_cursor_frame
 *
 * Create a frame dictionary for a cursor from a Windows icon.
 * Keys:
 *      "image"     a CGImage for the frame
 *      "duration"  a CFNumber for the frame duration in seconds
 *      "hotSpot"   a CFDictionary encoding a CGPoint for the hot spot
 */
static CFDictionaryRef create_cursor_frame(HDC hdc, const ICONINFOEXW *iinfo, HANDLE icon,
                                           HBITMAP hbmColor, unsigned char *color_bits, int color_size,
                                           HBITMAP hbmMask, unsigned char *mask_bits, int mask_size,
                                           int width, int height, int istep)
{
    DWORD delay_jiffies, num_steps;
    CFMutableDictionaryRef frame;
    CGPoint hot_spot;
    CFDictionaryRef hot_spot_dict;
    double duration;
    CFNumberRef duration_number;
    CGImageRef cgimage;

    TRACE("hdc %p iinfo->xHotspot %d iinfo->yHotspot %d icon %p hbmColor %p color_bits %p color_size %d"
          " hbmMask %p mask_bits %p mask_size %d width %d height %d istep %d\n",
          hdc, iinfo->xHotspot, iinfo->yHotspot, icon, hbmColor, color_bits, color_size,
          hbmMask, mask_bits, mask_size, width, height, istep);

    frame = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks);
    if (!frame)
    {
        WARN("failed to allocate dictionary for frame\n");
        return NULL;
    }

    hot_spot = CGPointMake(iinfo->xHotspot, iinfo->yHotspot);
    hot_spot_dict = CGPointCreateDictionaryRepresentation(hot_spot);
    if (!hot_spot_dict)
    {
        WARN("failed to create hot spot dictionary\n");
        CFRelease(frame);
        return NULL;
    }
    CFDictionarySetValue(frame, CFSTR("hotSpot"), hot_spot_dict);
    CFRelease(hot_spot_dict);

    if (GetCursorFrameInfo(icon, 0x0 /* unknown parameter */, istep, &delay_jiffies, &num_steps) != 0)
        duration = delay_jiffies / 60.0; /* convert jiffies (1/60s) to seconds */
    else
    {
        WARN("Failed to retrieve animated cursor frame-rate for frame %d.\n", istep);
        duration = 0.1; /* fallback delay, 100 ms */
    }
    duration_number = CFNumberCreate(NULL, kCFNumberDoubleType, &duration);
    if (!duration_number)
    {
        WARN("failed to create duration number\n");
        CFRelease(frame);
        return NULL;
    }
    CFDictionarySetValue(frame, CFSTR("duration"), duration_number);
    CFRelease(duration_number);

    cgimage = create_cgimage_from_icon_bitmaps(hdc, icon, hbmColor, color_bits, color_size,
                                               hbmMask, mask_bits, mask_size, width, height, istep);
    if (!cgimage)
    {
        CFRelease(frame);
        return NULL;
    }

    CFDictionarySetValue(frame, CFSTR("image"), cgimage);
    CGImageRelease(cgimage);

    return frame;
}


/***********************************************************************
 *              create_color_cursor
 *
 * Create an array of color cursor frames from a Windows cursor.  Each
 * frame is represented in the array by a dictionary.
 * Frame dictionary keys:
 *      "image"     a CGImage for the frame
 *      "duration"  a CFNumber for the frame duration in seconds
 *      "hotSpot"   a CFDictionary encoding a CGPoint for the hot spot
 */
static CFArrayRef create_color_cursor(HDC hdc, const ICONINFOEXW *iinfo, HANDLE icon, int width, int height)
{
    unsigned char *color_bits, *mask_bits;
    HBITMAP hbmColor = 0, hbmMask = 0;
    DWORD nFrames, delay_jiffies, i;
    int color_size, mask_size;
    BITMAPINFO *info = NULL;
    CFMutableArrayRef frames;

    TRACE("hdc %p iinfo %p icon %p width %d height %d\n", hdc, iinfo, icon, width, height);

    /* Retrieve the number of frames to render */
    if (!GetCursorFrameInfo(icon, 0x0 /* unknown parameter */, 0, &delay_jiffies, &nFrames))
    {
        WARN("GetCursorFrameInfo failed\n");
        return NULL;
    }
    if (!(frames = CFArrayCreateMutable(NULL, nFrames, &kCFTypeArrayCallBacks)))
    {
        WARN("failed to allocate frames array\n");
        return NULL;
    }

    /* Allocate all of the resources necessary to obtain a cursor frame */
    if (!(info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])))) goto cleanup;
    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info->bmiHeader.biWidth = width;
    info->bmiHeader.biHeight = -height;
    info->bmiHeader.biPlanes = 1;
    info->bmiHeader.biCompression = BI_RGB;
    info->bmiHeader.biXPelsPerMeter = 0;
    info->bmiHeader.biYPelsPerMeter = 0;
    info->bmiHeader.biClrUsed = 0;
    info->bmiHeader.biClrImportant = 0;
    info->bmiHeader.biBitCount = 32;
    color_size = width * height * 4;
    info->bmiHeader.biSizeImage = color_size;
    hbmColor = CreateDIBSection(hdc, info, DIB_RGB_COLORS, (VOID **) &color_bits, NULL, 0);
    if (!hbmColor)
    {
        WARN("failed to create DIB section for cursor color data\n");
        goto cleanup;
    }
    info->bmiHeader.biBitCount = 1;
    info->bmiColors[0].rgbRed      = 0;
    info->bmiColors[0].rgbGreen    = 0;
    info->bmiColors[0].rgbBlue     = 0;
    info->bmiColors[0].rgbReserved = 0;
    info->bmiColors[1].rgbRed      = 0xff;
    info->bmiColors[1].rgbGreen    = 0xff;
    info->bmiColors[1].rgbBlue     = 0xff;
    info->bmiColors[1].rgbReserved = 0;

    mask_size = ((width + 31) / 32 * 4) * height; /* width_bytes * height */
    info->bmiHeader.biSizeImage = mask_size;
    hbmMask = CreateDIBSection(hdc, info, DIB_RGB_COLORS, (VOID **) &mask_bits, NULL, 0);
    if (!hbmMask)
    {
        WARN("failed to create DIB section for cursor mask data\n");
        goto cleanup;
    }

    /* Create a CFDictionary for each frame of the cursor */
    for (i = 0; i < nFrames; i++)
    {
        CFDictionaryRef frame = create_cursor_frame(hdc, iinfo, icon,
                                                    hbmColor, color_bits, color_size,
                                                    hbmMask, mask_bits, mask_size,
                                                    width, height, i);
        if (!frame) goto cleanup;
        CFArrayAppendValue(frames, frame);
        CFRelease(frame);
    }

cleanup:
    if (CFArrayGetCount(frames) < nFrames)
    {
        CFRelease(frames);
        frames = NULL;
    }
    else
        TRACE("returning cursor with %d frames\n", nFrames);
    /* Cleanup all of the resources used to obtain the frame data */
    if (hbmColor) DeleteObject(hbmColor);
    if (hbmMask) DeleteObject(hbmMask);
    HeapFree(GetProcessHeap(), 0, info);
    return frames;
}


/***********************************************************************
 *              DestroyCursorIcon (MACDRV.@)
 */
void CDECL macdrv_DestroyCursorIcon(HCURSOR cursor)
{
    TRACE("cursor %p\n", cursor);

    EnterCriticalSection(&cursor_cache_section);
    if (cursor_cache)
        CFDictionaryRemoveValue(cursor_cache, cursor);
    LeaveCriticalSection(&cursor_cache_section);
}


/***********************************************************************
 *              ClipCursor (MACDRV.@)
 *
 * Set the cursor clipping rectangle.
 */
BOOL CDECL macdrv_ClipCursor(LPCRECT clip)
{
    CGRect rect;

    TRACE("%s\n", wine_dbgstr_rect(clip));

    if (clip)
    {
        rect = CGRectMake(clip->left, clip->top, max(1, clip->right - clip->left),
                          max(1, clip->bottom - clip->top));
    }
    else
        rect = CGRectInfinite;

    /* FIXME: This needs to be done not just in this process but in all of the
       ones for this WINEPREFIX.  Broadcast a message to do that. */

    return macdrv_clip_cursor(rect);
}


/***********************************************************************
 *              GetCursorPos (MACDRV.@)
 */
BOOL CDECL macdrv_GetCursorPos(LPPOINT pos)
{
    CGPoint pt;
    BOOL ret;

    ret = macdrv_get_cursor_position(&pt);
    if (ret)
    {
        TRACE("pointer at (%g,%g) server pos %d,%d\n", pt.x, pt.y, pos->x, pos->y);
        pos->x = pt.x;
        pos->y = pt.y;
    }
    return ret;
}


/***********************************************************************
 *              SetCapture (MACDRV.@)
 */
 void CDECL macdrv_SetCapture(HWND hwnd, UINT flags)
{
    struct macdrv_thread_data *thread_data = macdrv_thread_data();
    HWND top = GetAncestor(hwnd, GA_ROOT);
    macdrv_window cocoa_window = macdrv_get_cocoa_window(top, FALSE);

    TRACE("hwnd %p top %p/%p flags 0x%08x\n", hwnd, top, cocoa_window, flags);

    if (!thread_data) return;

    thread_data->capture_window = cocoa_window;
    macdrv_set_mouse_capture_window(cocoa_window);
}


/***********************************************************************
 *              SetCursor (MACDRV.@)
 */
void CDECL macdrv_SetCursor(HCURSOR cursor)
{
    CFStringRef cursor_name = NULL;
    CFArrayRef cursor_frames = NULL;

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

    if (cursor)
    {
        ICONINFOEXW info;

        EnterCriticalSection(&cursor_cache_section);
        if (cursor_cache)
        {
            CFTypeRef cached_cursor = CFDictionaryGetValue(cursor_cache, cursor);
            if (cached_cursor)
            {
                if (CFGetTypeID(cached_cursor) == CFStringGetTypeID())
                    cursor_name = CFRetain(cached_cursor);
                else
                    cursor_frames = CFRetain(cached_cursor);
            }
        }
        LeaveCriticalSection(&cursor_cache_section);
        if (cursor_name || cursor_frames)
            goto done;

        info.cbSize = sizeof(info);
        if (!GetIconInfoExW(cursor, &info))
        {
            WARN("GetIconInfoExW failed\n");
            return;
        }

        if ((cursor_name = copy_system_cursor_name(&info)))
        {
            DeleteObject(info.hbmColor);
            DeleteObject(info.hbmMask);
        }
        else
        {
            BITMAP bm;
            HDC hdc;

            GetObjectW(info.hbmMask, sizeof(bm), &bm);
            if (!info.hbmColor) bm.bmHeight = max(1, bm.bmHeight / 2);

            /* make sure hotspot is valid */
            if (info.xHotspot >= bm.bmWidth || info.yHotspot >= bm.bmHeight)
            {
                info.xHotspot = bm.bmWidth / 2;
                info.yHotspot = bm.bmHeight / 2;
            }

            hdc = CreateCompatibleDC(0);

            if (info.hbmColor)
            {
                cursor_frames = create_color_cursor(hdc, &info, cursor, bm.bmWidth, bm.bmHeight);
                DeleteObject(info.hbmColor);
            }
            else
                cursor_frames = create_monochrome_cursor(hdc, &info, bm.bmWidth, bm.bmHeight);

            DeleteObject(info.hbmMask);
            DeleteDC(hdc);
        }

        if (cursor_name || cursor_frames)
        {
            EnterCriticalSection(&cursor_cache_section);
            if (!cursor_cache)
                cursor_cache = CFDictionaryCreateMutable(NULL, 0, NULL,
                                                         &kCFTypeDictionaryValueCallBacks);
            CFDictionarySetValue(cursor_cache, cursor,
                                 cursor_name ? (CFTypeRef)cursor_name : (CFTypeRef)cursor_frames);
            LeaveCriticalSection(&cursor_cache_section);
        }
        else
            cursor_name = CFRetain(CFSTR("arrowCursor"));
    }

done:
    TRACE("setting cursor with cursor_name %s cursor_frames %p\n", debugstr_cf(cursor_name), cursor_frames);
    macdrv_set_cursor(cursor_name, cursor_frames);
    if (cursor_name) CFRelease(cursor_name);
    if (cursor_frames) CFRelease(cursor_frames);
}


/***********************************************************************
 *              SetCursorPos (MACDRV.@)
 */
BOOL CDECL macdrv_SetCursorPos(INT x, INT y)
{
    BOOL ret = macdrv_set_cursor_position(CGPointMake(x, y));
    if (ret)
        TRACE("warped to %d,%d\n", x, y);
    else
        ERR("failed to warp to %d,%d\n", x, y);
    return ret;
}


/***********************************************************************
 *              macdrv_mouse_button
 *
 * Handler for MOUSE_BUTTON events.
 */
void macdrv_mouse_button(HWND hwnd, const macdrv_event *event)
{
    UINT flags = 0;
    WORD data = 0;

    TRACE("win %p button %d %s at (%d,%d) time %lu (%lu ticks ago)\n", hwnd, event->mouse_button.button,
          (event->mouse_button.pressed ? "pressed" : "released"),
          event->mouse_button.x, event->mouse_button.y,
          event->mouse_button.time_ms, (GetTickCount() - event->mouse_button.time_ms));

    if (event->mouse_button.pressed)
    {
        switch (event->mouse_button.button)
        {
        case 0: flags |= MOUSEEVENTF_LEFTDOWN; break;
        case 1: flags |= MOUSEEVENTF_RIGHTDOWN; break;
        case 2: flags |= MOUSEEVENTF_MIDDLEDOWN; break;
        default:
            flags |= MOUSEEVENTF_XDOWN;
            data = 1 << (event->mouse_button.button - 3);
            break;
        }
    }
    else
    {
        switch (event->mouse_button.button)
        {
        case 0: flags |= MOUSEEVENTF_LEFTUP; break;
        case 1: flags |= MOUSEEVENTF_RIGHTUP; break;
        case 2: flags |= MOUSEEVENTF_MIDDLEUP; break;
        default:
            flags |= MOUSEEVENTF_XUP;
            data = 1 << (event->mouse_button.button - 3);
            break;
        }
    }

    send_mouse_input(hwnd, event->window, flags | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
                     event->mouse_button.x, event->mouse_button.y,
                     data, FALSE, event->mouse_button.time_ms);
}


/***********************************************************************
 *              macdrv_mouse_moved
 *
 * Handler for MOUSE_MOVED and MOUSE_MOVED_ABSOLUTE events.
 */
void macdrv_mouse_moved(HWND hwnd, const macdrv_event *event)
{
    UINT flags = MOUSEEVENTF_MOVE;

    TRACE("win %p/%p %s (%d,%d) drag %d time %lu (%lu ticks ago)\n", hwnd, event->window,
          (event->type == MOUSE_MOVED) ? "relative" : "absolute",
          event->mouse_moved.x, event->mouse_moved.y, event->mouse_moved.drag,
          event->mouse_moved.time_ms, (GetTickCount() - event->mouse_moved.time_ms));

    if (event->type == MOUSE_MOVED_ABSOLUTE)
        flags |= MOUSEEVENTF_ABSOLUTE;

    send_mouse_input(hwnd, event->window, flags, event->mouse_moved.x, event->mouse_moved.y,
                     0, event->mouse_moved.drag, event->mouse_moved.time_ms);
}


/***********************************************************************
 *              macdrv_mouse_scroll
 *
 * Handler for MOUSE_SCROLL events.
 */
void macdrv_mouse_scroll(HWND hwnd, const macdrv_event *event)
{
    TRACE("win %p/%p scroll (%d,%d) at (%d,%d) time %lu (%lu ticks ago)\n", hwnd,
          event->window, event->mouse_scroll.x_scroll, event->mouse_scroll.y_scroll,
          event->mouse_scroll.x, event->mouse_scroll.y,
          event->mouse_scroll.time_ms, (GetTickCount() - event->mouse_scroll.time_ms));

    if (event->mouse_scroll.y_scroll)
        send_mouse_input(hwnd, event->window, MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
                         event->mouse_scroll.x, event->mouse_scroll.y,
                         event->mouse_scroll.y_scroll, FALSE, event->mouse_scroll.time_ms);
    if (event->mouse_scroll.x_scroll)
        send_mouse_input(hwnd, event->window, MOUSEEVENTF_HWHEEL | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
                         event->mouse_scroll.x, event->mouse_scroll.y,
                         event->mouse_scroll.x_scroll, FALSE, event->mouse_scroll.time_ms);
}


/***********************************************************************
 *              macdrv_release_capture
 *
 * Handler for RELEASE_CAPTURE events.
 */
void macdrv_release_capture(HWND hwnd, const macdrv_event *event)
{
    struct macdrv_thread_data *thread_data = macdrv_thread_data();
    HWND capture = GetCapture();
    HWND capture_top = GetAncestor(capture, GA_ROOT);

    TRACE("win %p/%p thread_data->capture_window %p GetCapture() %p in %p\n", hwnd,
          event->window, thread_data->capture_window, capture, capture_top);

    if (event->window == thread_data->capture_window && hwnd == capture_top)
    {
        ReleaseCapture();
        if (!PostMessageW(capture, WM_CANCELMODE, 0, 0))
            WARN("failed to post WM_CANCELMODE; error 0x%08x\n", GetLastError());
    }
}
