/*
 * X11 mouse driver
 *
 * Copyright 1998 Ulrich Weigand
 * Copyright 2007 Henri Verbeet
 *
 * 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 "wine/port.h"

#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <stdarg.h>
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
#include <X11/extensions/XInput2.h>
#endif

#ifdef SONAME_LIBXCURSOR
# include <X11/Xcursor/Xcursor.h>
static void *xcursor_handle;
# define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(XcursorImageCreate);
MAKE_FUNCPTR(XcursorImageDestroy);
MAKE_FUNCPTR(XcursorImageLoadCursor);
MAKE_FUNCPTR(XcursorImagesCreate);
MAKE_FUNCPTR(XcursorImagesDestroy);
MAKE_FUNCPTR(XcursorImagesLoadCursor);
MAKE_FUNCPTR(XcursorLibraryLoadCursor);
# undef MAKE_FUNCPTR
#endif /* SONAME_LIBXCURSOR */

#define NONAMELESSUNION
#define OEMRESOURCE
#include "windef.h"
#include "winbase.h"
#include "winreg.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(cursor);

/**********************************************************************/

#ifndef Button6Mask
#define Button6Mask (1<<13)
#endif
#ifndef Button7Mask
#define Button7Mask (1<<14)
#endif

#define NB_BUTTONS   9     /* Windows can handle 5 buttons and the wheel too */

static const UINT button_down_flags[NB_BUTTONS] =
{
    MOUSEEVENTF_LEFTDOWN,
    MOUSEEVENTF_MIDDLEDOWN,
    MOUSEEVENTF_RIGHTDOWN,
    MOUSEEVENTF_WHEEL,
    MOUSEEVENTF_WHEEL,
    MOUSEEVENTF_XDOWN,  /* FIXME: horizontal wheel */
    MOUSEEVENTF_XDOWN,
    MOUSEEVENTF_XDOWN,
    MOUSEEVENTF_XDOWN
};

static const UINT button_up_flags[NB_BUTTONS] =
{
    MOUSEEVENTF_LEFTUP,
    MOUSEEVENTF_MIDDLEUP,
    MOUSEEVENTF_RIGHTUP,
    0,
    0,
    MOUSEEVENTF_XUP,
    MOUSEEVENTF_XUP,
    MOUSEEVENTF_XUP,
    MOUSEEVENTF_XUP
};

static const UINT button_down_data[NB_BUTTONS] =
{
    0,
    0,
    0,
    WHEEL_DELTA,
    -WHEEL_DELTA,
    XBUTTON1,
    XBUTTON2,
    XBUTTON1,
    XBUTTON2
};

static const UINT button_up_data[NB_BUTTONS] =
{
    0,
    0,
    0,
    0,
    0,
    XBUTTON1,
    XBUTTON2,
    XBUTTON1,
    XBUTTON2
};

XContext cursor_context = 0;

static HWND cursor_window;
static HCURSOR last_cursor;
static DWORD last_cursor_change;
static RECT clip_rect;
static Cursor create_cursor( HANDLE handle );

#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
static BOOL xinput2_available;
static BOOL broken_rawevents;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(XIFreeDeviceInfo);
MAKE_FUNCPTR(XIQueryDevice);
MAKE_FUNCPTR(XIQueryVersion);
MAKE_FUNCPTR(XISelectEvents);
#undef MAKE_FUNCPTR
#endif

/***********************************************************************
 *		X11DRV_Xcursor_Init
 *
 * Load the Xcursor library for use.
 */
void X11DRV_Xcursor_Init(void)
{
#ifdef SONAME_LIBXCURSOR
    xcursor_handle = wine_dlopen(SONAME_LIBXCURSOR, RTLD_NOW, NULL, 0);
    if (!xcursor_handle)  /* wine_dlopen failed. */
    {
        WARN("Xcursor failed to load.  Using fallback code.\n");
        return;
    }
#define LOAD_FUNCPTR(f) \
        p##f = wine_dlsym(xcursor_handle, #f, NULL, 0)

    LOAD_FUNCPTR(XcursorImageCreate);
    LOAD_FUNCPTR(XcursorImageDestroy);
    LOAD_FUNCPTR(XcursorImageLoadCursor);
    LOAD_FUNCPTR(XcursorImagesCreate);
    LOAD_FUNCPTR(XcursorImagesDestroy);
    LOAD_FUNCPTR(XcursorImagesLoadCursor);
    LOAD_FUNCPTR(XcursorLibraryLoadCursor);
#undef LOAD_FUNCPTR
#endif /* SONAME_LIBXCURSOR */
}


/***********************************************************************
 *		get_empty_cursor
 */
static Cursor get_empty_cursor(void)
{
    static Cursor cursor;
    static const char data[] = { 0 };

    if (!cursor)
    {
        XColor bg;
        Pixmap pixmap;

        bg.red = bg.green = bg.blue = 0x0000;
        pixmap = XCreateBitmapFromData( gdi_display, root_window, data, 1, 1 );
        if (pixmap)
        {
            Cursor new = XCreatePixmapCursor( gdi_display, pixmap, pixmap, &bg, &bg, 0, 0 );
            if (InterlockedCompareExchangePointer( (void **)&cursor, (void *)new, 0 ))
                XFreeCursor( gdi_display, new );
            XFreePixmap( gdi_display, pixmap );
        }
    }
    return cursor;
}

/***********************************************************************
 *		set_window_cursor
 */
void set_window_cursor( Window window, HCURSOR handle )
{
    Cursor cursor, prev;

    if (!handle) cursor = get_empty_cursor();
    else if (XFindContext( gdi_display, (XID)handle, cursor_context, (char **)&cursor ))
    {
        /* try to create it */
        if (!(cursor = create_cursor( handle ))) return;

        XLockDisplay( gdi_display );
        if (!XFindContext( gdi_display, (XID)handle, cursor_context, (char **)&prev ))
        {
            /* someone else was here first */
            XFreeCursor( gdi_display, cursor );
            cursor = prev;
        }
        else
        {
            XSaveContext( gdi_display, (XID)handle, cursor_context, (char *)cursor );
            TRACE( "cursor %p created %lx\n", handle, cursor );
        }
        XUnlockDisplay( gdi_display );
    }

    XDefineCursor( gdi_display, window, cursor );
    /* make the change take effect immediately */
    XFlush( gdi_display );
}

/***********************************************************************
 *              sync_window_cursor
 */
void sync_window_cursor( Window window )
{
    HCURSOR cursor;

    SERVER_START_REQ( set_cursor )
    {
        req->flags = 0;
        wine_server_call( req );
        cursor = reply->prev_count >= 0 ? wine_server_ptr_handle( reply->prev_handle ) : 0;
    }
    SERVER_END_REQ;

    set_window_cursor( window, cursor );
}

/***********************************************************************
 *              enable_xinput2
 */
static void enable_xinput2(void)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
    struct x11drv_thread_data *data = x11drv_thread_data();
    XIEventMask mask;
    XIDeviceInfo *devices;
    unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
    int i, j, count;

    if (!xinput2_available) return;

    if (data->xi2_state == xi_unknown)
    {
        int major = 2, minor = 0;
        if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
        else
        {
            data->xi2_state = xi_unavailable;
            WARN( "X Input 2 not available\n" );
        }
    }
    if (data->xi2_state == xi_unavailable) return;

    if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
    data->xi2_devices = devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
    for (i = 0; i < data->xi2_device_count; ++i)
    {
        if (devices[i].use != XIMasterPointer) continue;
        for (j = count = 0; j < devices[i].num_classes; j++)
        {
            XIValuatorClassInfo *class = (XIValuatorClassInfo *)devices[i].classes[j];

            if (devices[i].classes[j]->type != XIValuatorClass) continue;
            TRACE( "Device %u (%s) num %u %f,%f res %u mode %u label %s\n",
                   devices[i].deviceid, debugstr_a(devices[i].name),
                   class->number, class->min, class->max, class->resolution, class->mode,
                   XGetAtomName( data->display, class->label ));
            if (class->label == x11drv_atom( Rel_X ) || class->label == x11drv_atom( Rel_Y )) count++;
            /* workaround for drivers that don't provide labels */
            if (!class->label && class->number <= 1 && class->mode == XIModeRelative) count++;
        }
        if (count < 2) continue;
        TRACE( "Using %u (%s) as core pointer\n",
               devices[i].deviceid, debugstr_a(devices[i].name) );
        data->xi2_core_pointer = devices[i].deviceid;
        break;
    }

    mask.mask     = mask_bits;
    mask.mask_len = sizeof(mask_bits);
    memset( mask_bits, 0, sizeof(mask_bits) );
    XISetMask( mask_bits, XI_RawMotion );
    XISetMask( mask_bits, XI_ButtonPress );

    for (i = 0; i < data->xi2_device_count; ++i)
    {
        if (devices[i].use == XISlavePointer && devices[i].attachment == data->xi2_core_pointer)
        {
            TRACE( "Device %u (%s) is attached to the core pointer\n",
                   devices[i].deviceid, debugstr_a(devices[i].name) );
            mask.deviceid = devices[i].deviceid;
            pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
            data->xi2_state = xi_enabled;
        }
    }
#endif
}

/***********************************************************************
 *              disable_xinput2
 */
static void disable_xinput2(void)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
    struct x11drv_thread_data *data = x11drv_thread_data();
    XIDeviceInfo *devices = data->xi2_devices;
    XIEventMask mask;
    int i;

    if (data->xi2_state != xi_enabled) return;

    TRACE( "disabling\n" );
    data->xi2_state = xi_disabled;

    mask.mask = NULL;
    mask.mask_len = 0;

    for (i = 0; i < data->xi2_device_count; ++i)
    {
        if (devices[i].use == XISlavePointer && devices[i].attachment == data->xi2_core_pointer)
        {
            mask.deviceid = devices[i].deviceid;
            pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
        }
    }
    pXIFreeDeviceInfo( devices );
    data->xi2_devices = NULL;
    data->xi2_device_count = 0;
#endif
}


/***********************************************************************
 *		grab_clipping_window
 *
 * Start a pointer grab on the clip window.
 */
static BOOL grab_clipping_window( const RECT *clip )
{
    static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
    struct x11drv_thread_data *data = x11drv_thread_data();
    Window clip_window;
    HWND msg_hwnd = 0;
    POINT pos;

    if (GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId())
        return TRUE;  /* don't clip in the desktop process */

    if (!data) return FALSE;
    if (!(clip_window = init_clip_window())) return TRUE;

    if (!(msg_hwnd = CreateWindowW( messageW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0,
                                    GetModuleHandleW(0), NULL )))
        return TRUE;

    /* enable XInput2 unless we are already clipping */
    if (!data->clip_hwnd) enable_xinput2();

    if (data->xi2_state != xi_enabled)
    {
        WARN( "XInput2 not supported, refusing to clip to %s\n", wine_dbgstr_rect(clip) );
        DestroyWindow( msg_hwnd );
        ClipCursor( NULL );
        return TRUE;
    }

    TRACE( "clipping to %s win %lx\n", wine_dbgstr_rect(clip), clip_window );

    if (!data->clip_hwnd) XUnmapWindow( data->display, clip_window );
    pos = virtual_screen_to_root( clip->left, clip->top );
    XMoveResizeWindow( data->display, clip_window, pos.x, pos.y,
                       max( 1, clip->right - clip->left ), max( 1, clip->bottom - clip->top ) );
    XMapWindow( data->display, clip_window );

    /* if the rectangle is shrinking we may get a pointer warp */
    if (!data->clip_hwnd || clip->left > clip_rect.left || clip->top > clip_rect.top ||
        clip->right < clip_rect.right || clip->bottom < clip_rect.bottom)
        data->warp_serial = NextRequest( data->display );

    if (!XGrabPointer( data->display, clip_window, False,
                       PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                       GrabModeAsync, GrabModeAsync, clip_window, None, CurrentTime ))
        clipping_cursor = TRUE;

    if (!clipping_cursor)
    {
        disable_xinput2();
        DestroyWindow( msg_hwnd );
        return FALSE;
    }
    clip_rect = *clip;
    if (!data->clip_hwnd) sync_window_cursor( clip_window );
    InterlockedExchangePointer( (void **)&cursor_window, msg_hwnd );
    data->clip_hwnd = msg_hwnd;
    SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, (LPARAM)msg_hwnd );
    return TRUE;
}

/***********************************************************************
 *		ungrab_clipping_window
 *
 * Release the pointer grab on the clip window.
 */
void ungrab_clipping_window(void)
{
    Display *display = thread_init_display();
    Window clip_window = init_clip_window();

    if (!clip_window) return;

    TRACE( "no longer clipping\n" );
    XUnmapWindow( display, clip_window );
    clipping_cursor = FALSE;
    SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, 0 );
}

/***********************************************************************
 *		reset_clipping_window
 *
 * Forcibly reset the window clipping on external events.
 */
void reset_clipping_window(void)
{
    ungrab_clipping_window();
    ClipCursor( NULL );  /* make sure the clip rectangle is reset too */
}

/***********************************************************************
 *             clip_cursor_notify
 *
 * Notification function called upon receiving a WM_X11DRV_CLIP_CURSOR.
 */
LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
{
    struct x11drv_thread_data *data = x11drv_thread_data();

    if (hwnd == GetDesktopWindow())  /* change the clip window stored in the desktop process */
    {
        static HWND clip_hwnd;

        HWND prev = clip_hwnd;
        clip_hwnd = new_clip_hwnd;
        if (prev || new_clip_hwnd) TRACE( "clip hwnd changed from %p to %p\n", prev, new_clip_hwnd );
        if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, 0, 0 );
    }
    else if (hwnd == data->clip_hwnd)  /* this is a notification that clipping has been reset */
    {
        TRACE( "clip hwnd reset from %p\n", hwnd );
        data->clip_hwnd = 0;
        data->clip_reset = GetTickCount();
        disable_xinput2();
        DestroyWindow( hwnd );
    }
    else if (hwnd == GetForegroundWindow())  /* request to clip */
    {
        RECT clip, virtual_rect = get_virtual_screen_rect();

        GetClipCursor( &clip );
        if (clip.left > virtual_rect.left || clip.right < virtual_rect.right ||
            clip.top > virtual_rect.top   || clip.bottom < virtual_rect.bottom)
            return grab_clipping_window( &clip );
    }
    return 0;
}

/***********************************************************************
 *		clip_fullscreen_window
 *
 * Turn on clipping if the active window is fullscreen.
 */
BOOL clip_fullscreen_window( HWND hwnd, BOOL reset )
{
    struct x11drv_win_data *data;
    struct x11drv_thread_data *thread_data;
    RECT rect;
    DWORD style;
    BOOL fullscreen;

    if (hwnd == GetDesktopWindow()) return FALSE;
    style = GetWindowLongW( hwnd, GWL_STYLE );
    if (!(style & WS_VISIBLE)) return FALSE;
    if ((style & (WS_POPUP | WS_CHILD)) == WS_CHILD) return FALSE;
    /* maximized windows don't count as full screen */
    if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) return FALSE;
    if (!(data = get_win_data( hwnd ))) return FALSE;
    fullscreen = is_window_rect_fullscreen( &data->whole_rect );
    release_win_data( data );
    if (!fullscreen) return FALSE;
    if (!(thread_data = x11drv_thread_data())) return FALSE;
    if (GetTickCount() - thread_data->clip_reset < 1000) return FALSE;
    if (!reset && clipping_cursor && thread_data->clip_hwnd) return FALSE;  /* already clipping */
    rect = get_primary_monitor_rect();
    if (!grab_fullscreen)
    {
        RECT virtual_rect = get_virtual_screen_rect();
        if (!EqualRect( &rect, &virtual_rect )) return FALSE;
        if (root_window != DefaultRootWindow( gdi_display )) return FALSE;
    }
    TRACE( "win %p clipping fullscreen\n", hwnd );
    return grab_clipping_window( &rect );
}

/***********************************************************************
 *		send_mouse_input
 *
 * Update the various window states on a mouse event.
 */
static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input )
{
    struct x11drv_win_data *data;
    POINT pt;

    input->type = INPUT_MOUSE;

    if (!hwnd)
    {
        struct x11drv_thread_data *thread_data = x11drv_thread_data();
        HWND clip_hwnd = thread_data->clip_hwnd;

        if (!clip_hwnd) return;
        if (thread_data->clip_window != window) return;
        if (InterlockedExchangePointer( (void **)&cursor_window, clip_hwnd ) != clip_hwnd ||
            input->u.mi.time - last_cursor_change > 100)
        {
            sync_window_cursor( window );
            last_cursor_change = input->u.mi.time;
        }
        input->u.mi.dx += clip_rect.left;
        input->u.mi.dy += clip_rect.top;
        __wine_send_input( hwnd, input );
        return;
    }

    if (window != root_window)
    {
        pt.x = input->u.mi.dx;
        pt.y = input->u.mi.dy;
    }
    else pt = root_to_virtual_screen( input->u.mi.dx, input->u.mi.dy );

    if (!(data = get_win_data( hwnd ))) return;

    if (window == data->whole_window)
    {
        pt.x += data->whole_rect.left - data->client_rect.left;
        pt.y += data->whole_rect.top - data->client_rect.top;
    }

    if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
        pt.x = data->client_rect.right - data->client_rect.left - 1 - pt.x;
    MapWindowPoints( hwnd, 0, &pt, 1 );

    if (InterlockedExchangePointer( (void **)&cursor_window, hwnd ) != hwnd ||
        input->u.mi.time - last_cursor_change > 100)
    {
        sync_window_cursor( data->whole_window );
        last_cursor_change = input->u.mi.time;
    }
    release_win_data( data );

    if (hwnd != GetDesktopWindow())
    {
        hwnd = GetAncestor( hwnd, GA_ROOT );
        if ((input->u.mi.dwFlags & (MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_RIGHTDOWN)) && hwnd == GetForegroundWindow())
            clip_fullscreen_window( hwnd, FALSE );
    }

    /* update the wine server Z-order */

    if (window != x11drv_thread_data()->grab_window &&
        /* ignore event if a button is pressed, since the mouse is then grabbed too */
        !(state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask|Button6Mask|Button7Mask)))
    {
        RECT rect;
        SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );

        SERVER_START_REQ( update_window_zorder )
        {
            req->window      = wine_server_user_handle( 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->u.mi.dx = pt.x;
    input->u.mi.dy = pt.y;
    __wine_send_input( hwnd, input );
}

#ifdef SONAME_LIBXCURSOR

/***********************************************************************
 *              create_xcursor_frame
 *
 * Use Xcursor to create a frame of an X cursor from a Windows one.
 */
static XcursorImage *create_xcursor_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 )
{
    XcursorImage *image, *ret = NULL;
    DWORD delay_jiffies, num_steps;
    int x, y, i;
    BOOL has_alpha = FALSE;
    XcursorPixel *ptr;

    image = pXcursorImageCreate( width, height );
    if (!image)
    {
        ERR("X11 failed to produce a cursor frame!\n");
        return NULL;
    }

    image->xhot = iinfo->xHotspot;
    image->yhot = iinfo->yHotspot;

    image->delay = 100; /* fallback delay, 100 ms */
    if (GetCursorFrameInfo(icon, 0x0 /* unknown parameter */, istep, &delay_jiffies, &num_steps) != 0)
        image->delay = (100 * delay_jiffies) / 6; /* convert jiffies (1/60s) to milliseconds */
    else
        WARN("Failed to retrieve animated cursor frame-rate for frame %d.\n", istep);

    /* draw the cursor frame to a temporary buffer then copy it into the XcursorImage */
    memset( color_bits, 0x00, color_size );
    SelectObject( hdc, hbmColor );
    if (!DrawIconEx( hdc, 0, 0, icon, width, height, istep, NULL, DI_NORMAL ))
    {
        TRACE("Could not draw frame %d (walk past end of frames).\n", istep);
        goto cleanup;
    }
    memcpy( image->pixels, color_bits, color_size );

    /* check if the cursor frame was drawn with an alpha channel */
    for (i = 0, ptr = image->pixels; i < width * height; i++, ptr++)
        if ((has_alpha = (*ptr & 0xff000000) != 0)) break;

    /* if no alpha channel was drawn then generate it from the mask */
    if (!has_alpha)
    {
        unsigned int width_bytes = (width + 31) / 32 * 4;

        /* draw the cursor mask to a temporary buffer */
        memset( mask_bits, 0xFF, mask_size );
        SelectObject( hdc, hbmMask );
        if (!DrawIconEx( hdc, 0, 0, icon, width, height, istep, NULL, DI_MASK ))
        {
            ERR("Failed to draw frame mask %d.\n", istep);
            goto cleanup;
        }
        /* use the buffer to directly modify the XcursorImage alpha channel */
        for (y = 0, ptr = image->pixels; y < height; y++)
            for (x = 0; x < width; x++, ptr++)
                if (!((mask_bits[y * width_bytes + x / 8] << (x % 8)) & 0x80))
                    *ptr |= 0xff000000;
    }
    ret = image;

cleanup:
    if (ret == NULL) pXcursorImageDestroy( image );
    return ret;
}

/***********************************************************************
 *              create_xcursor_cursor
 *
 * Use Xcursor to create an X cursor from a Windows one.
 */
static Cursor create_xcursor_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;
    XcursorImages *images;
    XcursorImage **imgs;
    Cursor cursor = 0;

    /* Retrieve the number of frames to render */
    if (!GetCursorFrameInfo(icon, 0x0 /* unknown parameter */, 0, &delay_jiffies, &nFrames)) return 0;
    if (!(imgs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(XcursorImage*)*nFrames ))) return 0;

    /* 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)
    {
        ERR("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)
    {
        ERR("Failed to create DIB section for cursor mask data!\n");
        goto cleanup;
    }

    /* Create an XcursorImage for each frame of the cursor */
    for (i=0; i<nFrames; i++)
    {
        imgs[i] = create_xcursor_frame( hdc, iinfo, icon,
                                        hbmColor, color_bits, color_size,
                                        hbmMask, mask_bits, mask_size,
                                        width, height, i );
        if (!imgs[i]) goto cleanup;
    }

    /* Build an X cursor out of all of the frames */
    if (!(images = pXcursorImagesCreate( nFrames ))) goto cleanup;
    for (images->nimage = 0; images->nimage < nFrames; images->nimage++)
        images->images[images->nimage] = imgs[images->nimage];
    cursor = pXcursorImagesLoadCursor( gdi_display, images );
    pXcursorImagesDestroy( images ); /* Note: this frees each individual frame (calls XcursorImageDestroy) */
    HeapFree( GetProcessHeap(), 0, imgs );
    imgs = NULL;

cleanup:
    if (imgs)
    {
        /* Failed to produce a cursor, free previously allocated frames */
        for (i=0; i<nFrames && imgs[i]; i++)
            pXcursorImageDestroy( imgs[i] );
        HeapFree( GetProcessHeap(), 0, imgs );
    }
    /* Cleanup all of the resources used to obtain the frame data */
    if (hbmColor) DeleteObject( hbmColor );
    if (hbmMask) DeleteObject( hbmMask );
    HeapFree( GetProcessHeap(), 0, info );
    return cursor;
}

#endif /* SONAME_LIBXCURSOR */


struct system_cursors
{
    WORD id;
    const char *name;
};

static const struct system_cursors user32_cursors[] =
{
    { OCR_NORMAL,      "left_ptr" },
    { OCR_IBEAM,       "xterm" },
    { OCR_WAIT,        "watch" },
    { OCR_CROSS,       "cross" },
    { OCR_UP,          "center_ptr" },
    { OCR_SIZE,        "fleur" },
    { OCR_SIZEALL,     "fleur" },
    { OCR_ICON,        "icon" },
    { OCR_SIZENWSE,    "nwse-resize" },
    { OCR_SIZENESW,    "nesw-resize" },
    { OCR_SIZEWE,      "ew-resize" },
    { OCR_SIZENS,      "ns-resize" },
    { OCR_NO,          "not-allowed" },
    { OCR_HAND,        "hand2" },
    { OCR_APPSTARTING, "left_ptr_watch" },
    { OCR_HELP,        "question_arrow" },
    { 0 }
};

static const struct system_cursors comctl32_cursors[] =
{
    { 102, "move" },
    { 104, "copy" },
    { 105, "left_ptr" },
    { 106, "col-resize" },
    { 107, "col-resize" },
    { 108, "hand2" },
    { 135, "row-resize" },
    { 0 }
};

static const struct system_cursors ole32_cursors[] =
{
    { 1, "no-drop" },
    { 2, "move" },
    { 3, "copy" },
    { 4, "alias" },
    { 0 }
};

static const struct system_cursors riched20_cursors[] =
{
    { 105, "hand2" },
    { 107, "right_ptr" },
    { 109, "copy" },
    { 110, "move" },
    { 111, "no-drop" },
    { 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} }
};

struct cursor_font_fallback
{
    const char  *name;
    unsigned int shape;
};

static const struct cursor_font_fallback fallbacks[] =
{
    { "X_cursor",            XC_X_cursor },
    { "arrow",               XC_arrow },
    { "based_arrow_down",    XC_based_arrow_down },
    { "based_arrow_up",      XC_based_arrow_up },
    { "boat",                XC_boat },
    { "bogosity",            XC_bogosity },
    { "bottom_left_corner",  XC_bottom_left_corner },
    { "bottom_right_corner", XC_bottom_right_corner },
    { "bottom_side",         XC_bottom_side },
    { "bottom_tee",          XC_bottom_tee },
    { "box_spiral",          XC_box_spiral },
    { "center_ptr",          XC_center_ptr },
    { "circle",              XC_circle },
    { "clock",               XC_clock },
    { "coffee_mug",          XC_coffee_mug },
    { "col-resize",          XC_sb_h_double_arrow },
    { "cross",               XC_cross },
    { "cross_reverse",       XC_cross_reverse },
    { "crosshair",           XC_crosshair },
    { "diamond_cross",       XC_diamond_cross },
    { "dot",                 XC_dot },
    { "dotbox",              XC_dotbox },
    { "double_arrow",        XC_double_arrow },
    { "draft_large",         XC_draft_large },
    { "draft_small",         XC_draft_small },
    { "draped_box",          XC_draped_box },
    { "exchange",            XC_exchange },
    { "fleur",               XC_fleur },
    { "gobbler",             XC_gobbler },
    { "gumby",               XC_gumby },
    { "hand1",               XC_hand1 },
    { "hand2",               XC_hand2 },
    { "heart",               XC_heart },
    { "icon",                XC_icon },
    { "iron_cross",          XC_iron_cross },
    { "left_ptr",            XC_left_ptr },
    { "left_side",           XC_left_side },
    { "left_tee",            XC_left_tee },
    { "leftbutton",          XC_leftbutton },
    { "ll_angle",            XC_ll_angle },
    { "lr_angle",            XC_lr_angle },
    { "man",                 XC_man },
    { "middlebutton",        XC_middlebutton },
    { "mouse",               XC_mouse },
    { "pencil",              XC_pencil },
    { "pirate",              XC_pirate },
    { "plus",                XC_plus },
    { "question_arrow",      XC_question_arrow },
    { "right_ptr",           XC_right_ptr },
    { "right_side",          XC_right_side },
    { "right_tee",           XC_right_tee },
    { "rightbutton",         XC_rightbutton },
    { "row-resize",          XC_sb_v_double_arrow },
    { "rtl_logo",            XC_rtl_logo },
    { "sailboat",            XC_sailboat },
    { "sb_down_arrow",       XC_sb_down_arrow },
    { "sb_h_double_arrow",   XC_sb_h_double_arrow },
    { "sb_left_arrow",       XC_sb_left_arrow },
    { "sb_right_arrow",      XC_sb_right_arrow },
    { "sb_up_arrow",         XC_sb_up_arrow },
    { "sb_v_double_arrow",   XC_sb_v_double_arrow },
    { "shuttle",             XC_shuttle },
    { "sizing",              XC_sizing },
    { "spider",              XC_spider },
    { "spraycan",            XC_spraycan },
    { "star",                XC_star },
    { "target",              XC_target },
    { "tcross",              XC_tcross },
    { "top_left_arrow",      XC_top_left_arrow },
    { "top_left_corner",     XC_top_left_corner },
    { "top_right_corner",    XC_top_right_corner },
    { "top_side",            XC_top_side },
    { "top_tee",             XC_top_tee },
    { "trek",                XC_trek },
    { "ul_angle",            XC_ul_angle },
    { "umbrella",            XC_umbrella },
    { "ur_angle",            XC_ur_angle },
    { "watch",               XC_watch },
    { "xterm",               XC_xterm }
};

static int fallback_cmp( const void *key, const void *member )
{
    const struct cursor_font_fallback *fallback = member;
    return strcmp( key, fallback->name );
}

static int find_fallback_shape( const char *name )
{
    struct cursor_font_fallback *fallback;

    if ((fallback = bsearch( name, fallbacks, sizeof(fallbacks) / sizeof(fallbacks[0]),
                             sizeof(*fallback), fallback_cmp )))
        return fallback->shape;
    return -1;
}

/***********************************************************************
 *		create_xcursor_system_cursor
 *
 * Create an X cursor for a system cursor.
 */
static Cursor create_xcursor_system_cursor( const ICONINFOEXW *info )
{
    static const WCHAR idW[] = {'%','h','u',0};
    const struct system_cursors *cursors;
    unsigned int i;
    Cursor cursor = 0;
    HMODULE module;
    HKEY key;
    WCHAR *p, name[MAX_PATH * 2], valueW[64];
    char valueA[64];
    DWORD size, ret;

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

    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 );
    valueA[0] = 0;

    /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver\Cursors */
    if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver\\Cursors", &key ))
    {
        size = sizeof(valueW) / sizeof(WCHAR);
        ret = RegQueryValueExW( key, name, NULL, NULL, (BYTE *)valueW, &size );
        RegCloseKey( key );
        if (!ret)
        {
            if (!valueW[0]) return 0; /* force standard cursor */
            if (!WideCharToMultiByte( CP_UNIXCP, 0, valueW, -1, valueA, sizeof(valueA), NULL, NULL ))
                valueA[0] = 0;
            goto done;
        }
    }

    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)
        {
            strcpy( valueA, cursors[i].name );
            break;
        }

done:
    if (valueA[0])
    {
#ifdef SONAME_LIBXCURSOR
        if (pXcursorLibraryLoadCursor) cursor = pXcursorLibraryLoadCursor( gdi_display, valueA );
#endif
        if (!cursor)
        {
            int shape = find_fallback_shape( valueA );
            if (shape != -1) cursor = XCreateFontCursor( gdi_display, shape );
        }
        if (!cursor) WARN( "no system cursor found for %s mapped to %s\n",
                           debugstr_w(name), debugstr_a(valueA) );
    }
    else WARN( "no system cursor found for %s\n", debugstr_w(name) );
    return cursor;
}


/***********************************************************************
 *		create_xlib_monochrome_cursor
 *
 * Create a monochrome X cursor from a Windows one.
 */
static Cursor create_xlib_monochrome_cursor( HDC hdc, const ICONINFOEXW *icon, int width, int height )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    const int and_y = 0;
    const int xor_y = height;
    unsigned int width_bytes = (width + 31) / 32 * 4;
    unsigned char *mask_bits = NULL;
    GC gc;
    XColor fg, bg;
    XVisualInfo vis = default_visual;
    Pixmap src_pixmap, bits_pixmap, mask_pixmap;
    struct gdi_image_bits bits;
    Cursor cursor = 0;

    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;

    if (!(mask_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
    if (!GetDIBits( hdc, icon->hbmMask, 0, height * 2, mask_bits, info, DIB_RGB_COLORS )) goto done;

    vis.depth = 1;
    bits.ptr = mask_bits;
    bits.free = NULL;
    bits.is_copy = TRUE;
    if (!(src_pixmap = create_pixmap_from_image( hdc, &vis, info, &bits, DIB_RGB_COLORS ))) goto done;

    bits_pixmap = XCreatePixmap( gdi_display, root_window, width, height, 1 );
    mask_pixmap = XCreatePixmap( gdi_display, root_window, width, height, 1 );
    gc = XCreateGC( gdi_display, src_pixmap, 0, NULL );
    XSetGraphicsExposures( gdi_display, gc, False );

    /* We have to do some magic here, as cursors are not fully
     * compatible between Windows and X11. Under X11, there are
     * only 3 possible color cursor: black, white and masked. So
     * we map the 4th Windows color (invert the bits on the screen)
     * to black and an additional white bit on another place
     * (+1,+1). This require some boolean arithmetic:
     *
     *         Windows          |          X11
     * And    Xor      Result   |   Bits     Mask     Result
     *  0      0     black      |    0        1     background
     *  0      1     white      |    1        1     foreground
     *  1      0     no change  |    X        0     no change
     *  1      1     inverted   |    0        1     background
     *
     * which gives:
     *  Bits = not 'And' and 'Xor' or 'And2' and 'Xor2'
     *  Mask = not 'And' or 'Xor' or 'And2' and 'Xor2'
     */
    XSetFunction( gdi_display, gc, GXcopy );
    XCopyArea( gdi_display, src_pixmap, bits_pixmap, gc, 0, and_y, width, height, 0, 0 );
    XCopyArea( gdi_display, src_pixmap, mask_pixmap, gc, 0, and_y, width, height, 0, 0 );
    XSetFunction( gdi_display, gc, GXandReverse );
    XCopyArea( gdi_display, src_pixmap, bits_pixmap, gc, 0, xor_y, width, height, 0, 0 );
    XSetFunction( gdi_display, gc, GXorReverse );
    XCopyArea( gdi_display, src_pixmap, mask_pixmap, gc, 0, xor_y, width, height, 0, 0 );
    /* additional white */
    XSetFunction( gdi_display, gc, GXand );
    XCopyArea( gdi_display, src_pixmap, src_pixmap,  gc, 0, xor_y, width, height, 0, and_y );
    XSetFunction( gdi_display, gc, GXor );
    XCopyArea( gdi_display, src_pixmap, mask_pixmap, gc, 0, and_y, width, height, 1, 1 );
    XCopyArea( gdi_display, src_pixmap, bits_pixmap, gc, 0, and_y, width, height, 1, 1 );
    XFreeGC( gdi_display, gc );

    fg.red = fg.green = fg.blue = 0xffff;
    bg.red = bg.green = bg.blue = 0;
    cursor = XCreatePixmapCursor( gdi_display, bits_pixmap, mask_pixmap,
                                  &fg, &bg, icon->xHotspot, icon->yHotspot );
    XFreePixmap( gdi_display, src_pixmap );
    XFreePixmap( gdi_display, bits_pixmap );
    XFreePixmap( gdi_display, mask_pixmap );

done:
    HeapFree( GetProcessHeap(), 0, mask_bits );
    return cursor;
}

/***********************************************************************
 *		create_xlib_color_cursor
 *
 * Create a color X cursor from a Windows one.
 */
static Cursor create_xlib_color_cursor( HDC hdc, const ICONINFOEXW *icon, int width, int height )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    XColor fg, bg;
    Cursor cursor = None;
    XVisualInfo vis = default_visual;
    Pixmap xor_pixmap, mask_pixmap;
    struct gdi_image_bits bits;
    unsigned int *color_bits = NULL, *ptr;
    unsigned char *mask_bits = NULL, *xor_bits = NULL;
    int i, x, y;
    BOOL has_alpha = FALSE;
    int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits;
    unsigned int width_bytes = (width + 31) / 32 * 4;

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

    if (!(mask_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
    if (!GetDIBits( hdc, icon->hbmMask, 0, height, mask_bits, info, DIB_RGB_COLORS )) goto done;

    info->bmiHeader.biBitCount = 32;
    info->bmiHeader.biSizeImage = width * height * 4;
    if (!(color_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
    if (!(xor_bits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, width_bytes * height ))) goto done;
    GetDIBits( hdc, icon->hbmColor, 0, height, color_bits, info, DIB_RGB_COLORS );

    /* compute fg/bg color and xor bitmap based on average of the color values */

    rfg = gfg = bfg = rbg = gbg = bbg = fgBits = 0;
    for (y = 0, ptr = color_bits; y < height; y++)
    {
        for (x = 0; x < width; x++, ptr++)
        {
            int red   = (*ptr >> 16) & 0xff;
            int green = (*ptr >> 8) & 0xff;
            int blue  = (*ptr >> 0) & 0xff;
            if (red + green + blue > 0x40)
            {
                rfg += red;
                gfg += green;
                bfg += blue;
                fgBits++;
                xor_bits[y * width_bytes + x / 8] |= 0x80 >> (x % 8);
            }
            else
            {
                rbg += red;
                gbg += green;
                bbg += blue;
            }
        }
    }
    if (fgBits)
    {
        fg.red   = rfg * 257 / fgBits;
        fg.green = gfg * 257 / fgBits;
        fg.blue  = bfg * 257 / fgBits;
    }
    else fg.red = fg.green = fg.blue = 0;
    bgBits = width * height - fgBits;
    if (bgBits)
    {
        bg.red   = rbg * 257 / bgBits;
        bg.green = gbg * 257 / bgBits;
        bg.blue  = bbg * 257 / bgBits;
    }
    else bg.red = bg.green = bg.blue = 0;

    info->bmiHeader.biBitCount = 1;
    info->bmiHeader.biClrUsed = 0;
    info->bmiHeader.biSizeImage = width_bytes * height;

    /* generate mask from the alpha channel if we have one */

    for (i = 0, ptr = color_bits; i < width * height; i++, ptr++)
        if ((has_alpha = (*ptr & 0xff000000) != 0)) break;

    if (has_alpha)
    {
        memset( mask_bits, 0, width_bytes * height );
        for (y = 0, ptr = color_bits; y < height; y++)
            for (x = 0; x < width; x++, ptr++)
                if ((*ptr >> 24) > 25) /* more than 10% alpha */
                    mask_bits[y * width_bytes + x / 8] |= 0x80 >> (x % 8);
    }
    else  /* invert the mask */
    {
        unsigned int j;

        ptr = (unsigned int *)mask_bits;
        for (j = 0; j < info->bmiHeader.biSizeImage / sizeof(*ptr); j++, ptr++) *ptr ^= ~0u;
    }

    vis.depth = 1;
    bits.ptr = xor_bits;
    bits.free = NULL;
    bits.is_copy = TRUE;
    if (!(xor_pixmap = create_pixmap_from_image( hdc, &vis, info, &bits, DIB_RGB_COLORS ))) goto done;

    bits.ptr = mask_bits;
    mask_pixmap = create_pixmap_from_image( hdc, &vis, info, &bits, DIB_RGB_COLORS );

    if (mask_pixmap)
    {
        cursor = XCreatePixmapCursor( gdi_display, xor_pixmap, mask_pixmap,
                                      &fg, &bg, icon->xHotspot, icon->yHotspot );
        XFreePixmap( gdi_display, mask_pixmap );
    }
    XFreePixmap( gdi_display, xor_pixmap );

done:
    HeapFree( GetProcessHeap(), 0, color_bits );
    HeapFree( GetProcessHeap(), 0, xor_bits );
    HeapFree( GetProcessHeap(), 0, mask_bits );
    return cursor;
}

/***********************************************************************
 *		create_cursor
 *
 * Create an X cursor from a Windows one.
 */
static Cursor create_cursor( HANDLE handle )
{
    Cursor cursor = 0;
    ICONINFOEXW info;
    BITMAP bm;
    HDC hdc;

    if (!handle) return get_empty_cursor();

    info.cbSize = sizeof(info);
    if (!GetIconInfoExW( handle, &info )) return 0;

    if (use_system_cursors && (cursor = create_xcursor_system_cursor( &info )))
    {
        DeleteObject( info.hbmColor );
        DeleteObject( info.hbmMask );
        return cursor;
    }

    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)
    {
#ifdef SONAME_LIBXCURSOR
        if (pXcursorImagesLoadCursor)
            cursor = create_xcursor_cursor( hdc, &info, handle, bm.bmWidth, bm.bmHeight );
#endif
        if (!cursor) cursor = create_xlib_color_cursor( hdc, &info, bm.bmWidth, bm.bmHeight );
        DeleteObject( info.hbmColor );
    }
    else
    {
        cursor = create_xlib_monochrome_cursor( hdc, &info, bm.bmWidth, bm.bmHeight );
    }

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

/***********************************************************************
 *		DestroyCursorIcon (X11DRV.@)
 */
void CDECL X11DRV_DestroyCursorIcon( HCURSOR handle )
{
    Cursor cursor;

    if (!XFindContext( gdi_display, (XID)handle, cursor_context, (char **)&cursor ))
    {
        TRACE( "%p xid %lx\n", handle, cursor );
        XFreeCursor( gdi_display, cursor );
        XDeleteContext( gdi_display, (XID)handle, cursor_context );
    }
}

/***********************************************************************
 *		SetCursor (X11DRV.@)
 */
void CDECL X11DRV_SetCursor( HCURSOR handle )
{
    if (InterlockedExchangePointer( (void **)&last_cursor, handle ) != handle ||
        GetTickCount() - last_cursor_change > 100)
    {
        last_cursor_change = GetTickCount();
        if (cursor_window) SendNotifyMessageW( cursor_window, WM_X11DRV_SET_CURSOR, 0, (LPARAM)handle );
    }
}

/***********************************************************************
 *		SetCursorPos (X11DRV.@)
 */
BOOL CDECL X11DRV_SetCursorPos( INT x, INT y )
{
    struct x11drv_thread_data *data = x11drv_init_thread_data();
    POINT pos = virtual_screen_to_root( x, y );

    XWarpPointer( data->display, root_window, root_window, 0, 0, 0, 0, pos.x, pos.y );
    data->warp_serial = NextRequest( data->display );
    XNoOp( data->display );
    XFlush( data->display ); /* avoids bad mouse lag in games that do their own mouse warping */
    TRACE( "warped to %d,%d serial %lu\n", x, y, data->warp_serial );
    return TRUE;
}

/***********************************************************************
 *		GetCursorPos (X11DRV.@)
 */
BOOL CDECL X11DRV_GetCursorPos(LPPOINT pos)
{
    Display *display = thread_init_display();
    Window root, child;
    int rootX, rootY, winX, winY;
    unsigned int xstate;
    BOOL ret;

    ret = XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &winX, &winY, &xstate );
    if (ret)
    {
        POINT old = *pos;
        *pos = root_to_virtual_screen( winX, winY );
        TRACE( "pointer at (%d,%d) server pos %d,%d\n", pos->x, pos->y, old.x, old.y );
    }
    return ret;
}

/***********************************************************************
 *		ClipCursor (X11DRV.@)
 */
BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
{
    RECT virtual_rect = get_virtual_screen_rect();

    if (!clip) clip = &virtual_rect;

    if (grab_pointer)
    {
        HWND foreground = GetForegroundWindow();

        /* we are clipping if the clip rectangle is smaller than the screen */
        if (clip->left > virtual_rect.left || clip->right < virtual_rect.right ||
            clip->top > virtual_rect.top || clip->bottom < virtual_rect.bottom)
        {
            DWORD tid, pid;

            /* forward request to the foreground window if it's in a different thread */
            tid = GetWindowThreadProcessId( foreground, &pid );
            if (tid && tid != GetCurrentThreadId() && pid == GetCurrentProcessId())
            {
                TRACE( "forwarding clip request to %p\n", foreground );
                SendNotifyMessageW( foreground, WM_X11DRV_CLIP_CURSOR, 0, 0 );
                return TRUE;
            }
            else if (grab_clipping_window( clip )) return TRUE;
        }
        else /* if currently clipping, check if we should switch to fullscreen clipping */
        {
            struct x11drv_thread_data *data = x11drv_thread_data();
            if (data && data->clip_hwnd)
            {
                if (EqualRect( clip, &clip_rect ) || clip_fullscreen_window( foreground, TRUE ))
                    return TRUE;
            }
        }
    }
    ungrab_clipping_window();
    return TRUE;
}

/***********************************************************************
 *           move_resize_window
 */
void move_resize_window( HWND hwnd, int dir )
{
    Display *display = thread_display();
    DWORD pt;
    POINT pos;
    int button = 0;
    XEvent xev;
    Window win, root, child;
    unsigned int xstate;

    if (!(win = X11DRV_get_whole_window( hwnd ))) return;

    pt = GetMessagePos();
    pos = virtual_screen_to_root( (short)LOWORD( pt ), (short)HIWORD( pt ) );

    if (GetKeyState( VK_LBUTTON ) & 0x8000) button = 1;
    else if (GetKeyState( VK_MBUTTON ) & 0x8000) button = 2;
    else if (GetKeyState( VK_RBUTTON ) & 0x8000) button = 3;

    TRACE( "hwnd %p/%lx, x %d, y %d, dir %d, button %d\n", hwnd, win, pos.x, pos.y, dir, button );

    xev.xclient.type = ClientMessage;
    xev.xclient.window = win;
    xev.xclient.message_type = x11drv_atom(_NET_WM_MOVERESIZE);
    xev.xclient.serial = 0;
    xev.xclient.display = display;
    xev.xclient.send_event = True;
    xev.xclient.format = 32;
    xev.xclient.data.l[0] = pos.x; /* x coord */
    xev.xclient.data.l[1] = pos.y; /* y coord */
    xev.xclient.data.l[2] = dir; /* direction */
    xev.xclient.data.l[3] = button; /* button */
    xev.xclient.data.l[4] = 0; /* unused */

    /* need to ungrab the pointer that may have been automatically grabbed
     * with a ButtonPress event */
    XUngrabPointer( display, CurrentTime );
    XSendEvent(display, root_window, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);

    /* try to detect the end of the size/move by polling for the mouse button to be released */
    /* (some apps don't like it if we return before the size/move is done) */

    if (!button) return;
    SendMessageW( hwnd, WM_ENTERSIZEMOVE, 0, 0 );

    for (;;)
    {
        MSG msg;
        INPUT input;
        int x, y, rootX, rootY;

        if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break;

        if (!(xstate & (Button1Mask << (button - 1))))
        {
            /* fake a button release event */
            pos = root_to_virtual_screen( x, y );
            input.type = INPUT_MOUSE;
            input.u.mi.dx          = pos.x;
            input.u.mi.dy          = pos.y;
            input.u.mi.mouseData   = button_up_data[button - 1];
            input.u.mi.dwFlags     = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
            input.u.mi.time        = GetTickCount();
            input.u.mi.dwExtraInfo = 0;
            __wine_send_input( hwnd, &input );
        }

        while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
        {
            if (!CallMsgFilterW( &msg, MSGF_SIZE ))
            {
                TranslateMessage( &msg );
                DispatchMessageW( &msg );
            }
        }

        if (!(xstate & (Button1Mask << (button - 1)))) break;
        MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
    }

    TRACE( "hwnd %p/%lx done\n", hwnd, win );
    SendMessageW( hwnd, WM_EXITSIZEMOVE, 0, 0 );
}


/***********************************************************************
 *           X11DRV_ButtonPress
 */
void X11DRV_ButtonPress( HWND hwnd, XEvent *xev )
{
    XButtonEvent *event = &xev->xbutton;
    int buttonNum = event->button - 1;
    INPUT input;

    if (buttonNum >= NB_BUTTONS) return;

    TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y );

    input.u.mi.dx          = event->x;
    input.u.mi.dy          = event->y;
    input.u.mi.mouseData   = button_down_data[buttonNum];
    input.u.mi.dwFlags     = button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
    input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
    input.u.mi.dwExtraInfo = 0;

    update_user_time( event->time );
    send_mouse_input( hwnd, event->window, event->state, &input );
}


/***********************************************************************
 *           X11DRV_ButtonRelease
 */
void X11DRV_ButtonRelease( HWND hwnd, XEvent *xev )
{
    XButtonEvent *event = &xev->xbutton;
    int buttonNum = event->button - 1;
    INPUT input;

    if (buttonNum >= NB_BUTTONS || !button_up_flags[buttonNum]) return;

    TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y );

    input.u.mi.dx          = event->x;
    input.u.mi.dy          = event->y;
    input.u.mi.mouseData   = button_up_data[buttonNum];
    input.u.mi.dwFlags     = button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
    input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
    input.u.mi.dwExtraInfo = 0;

    send_mouse_input( hwnd, event->window, event->state, &input );
}


/***********************************************************************
 *           X11DRV_MotionNotify
 */
void X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
{
    XMotionEvent *event = &xev->xmotion;
    INPUT input;

    TRACE( "hwnd %p/%lx pos %d,%d is_hint %d serial %lu\n",
           hwnd, event->window, event->x, event->y, event->is_hint, event->serial );

    input.u.mi.dx          = event->x;
    input.u.mi.dy          = event->y;
    input.u.mi.mouseData   = 0;
    input.u.mi.dwFlags     = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
    input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
    input.u.mi.dwExtraInfo = 0;

    if (!hwnd)
    {
        struct x11drv_thread_data *thread_data = x11drv_thread_data();
        if (thread_data->warp_serial)
        {
            if ((long)(event->serial - thread_data->warp_serial) < 0)
            {
                TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, event->serial );
                return;
            }
            thread_data->warp_serial = 0;  /* we caught up now */
        }
    }

    send_mouse_input( hwnd, event->window, event->state, &input );
}


/***********************************************************************
 *           X11DRV_EnterNotify
 */
void X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
{
    XCrossingEvent *event = &xev->xcrossing;
    INPUT input;

    TRACE( "hwnd %p/%lx pos %d,%d detail %d\n", hwnd, event->window, event->x, event->y, event->detail );

    if (event->detail == NotifyVirtual) return;
    if (event->window == x11drv_thread_data()->grab_window) return;

    /* simulate a mouse motion event */
    input.u.mi.dx          = event->x;
    input.u.mi.dy          = event->y;
    input.u.mi.mouseData   = 0;
    input.u.mi.dwFlags     = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
    input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
    input.u.mi.dwExtraInfo = 0;

    send_mouse_input( hwnd, event->window, event->state, &input );
}

#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H

/***********************************************************************
 *           X11DRV_RawMotion
 */
static void X11DRV_RawMotion( XGenericEventCookie *xev )
{
    XIRawEvent *event = xev->data;
    const double *values = event->valuators.values;
    RECT virtual_rect;
    INPUT input;
    int i, j;
    double dx = 0, dy = 0;
    struct x11drv_thread_data *thread_data = x11drv_thread_data();
    XIDeviceInfo *devices = thread_data->xi2_devices;

    if (!event->valuators.mask_len) return;
    if (thread_data->xi2_state != xi_enabled) return;

    input.u.mi.mouseData   = 0;
    input.u.mi.dwFlags     = MOUSEEVENTF_MOVE;
    input.u.mi.time        = EVENT_x11_time_to_win32_time( event->time );
    input.u.mi.dwExtraInfo = 0;
    input.u.mi.dx          = 0;
    input.u.mi.dy          = 0;

    virtual_rect = get_virtual_screen_rect();
    for (i = 0; i < thread_data->xi2_device_count; ++i)
    {
        if (devices[i].deviceid != event->deviceid) continue;
        for (j = 0; j < devices[i].num_classes; j++)
        {
            XIValuatorClassInfo *class = (XIValuatorClassInfo *)devices[i].classes[j];

            if (devices[i].classes[j]->type != XIValuatorClass) continue;
            if (XIMaskIsSet( event->valuators.mask, class->number ))
            {
                double val = *values++;
                if (class->label == x11drv_atom( Rel_X ) ||
                    (!class->label && class->number == 0 && class->mode == XIModeRelative))
                {
                    input.u.mi.dx = dx = val;
                    if (class->min < class->max)
                        input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
                                            / (class->max - class->min);
                }
                else if (class->label == x11drv_atom( Rel_Y ) ||
                         (!class->label && class->number == 1 && class->mode == XIModeRelative))
                {
                    input.u.mi.dy = dy = val;
                    if (class->min < class->max)
                        input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
                                            / (class->max - class->min);
                }
            }
        }
        break;
    }

    if (broken_rawevents && thread_data->warp_serial)
    {
        if ((long)(xev->serial - thread_data->warp_serial) < 0)
        {
            TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
            return;
        }
        thread_data->warp_serial = 0;  /* we caught up now */
    }

    TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );

    input.type = INPUT_MOUSE;
    __wine_send_input( 0, &input );
}

#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */


/***********************************************************************
 *              X11DRV_XInput2_Init
 */
void X11DRV_XInput2_Init(void)
{
#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
    int event, error;
    void *libxi_handle = wine_dlopen( SONAME_LIBXI, RTLD_NOW, NULL, 0 );

    if (!libxi_handle)
    {
        WARN( "couldn't load %s\n", SONAME_LIBXI );
        return;
    }
#define LOAD_FUNCPTR(f) \
    if (!(p##f = wine_dlsym( libxi_handle, #f, NULL, 0))) \
    { \
        WARN("Failed to load %s.\n", #f); \
        return; \
    }

    LOAD_FUNCPTR(XIFreeDeviceInfo);
    LOAD_FUNCPTR(XIQueryDevice);
    LOAD_FUNCPTR(XIQueryVersion);
    LOAD_FUNCPTR(XISelectEvents);
#undef LOAD_FUNCPTR

    xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error );

    /* Until version 1.10.4 rawinput was broken in XOrg, see
     * https://bugs.freedesktop.org/show_bug.cgi?id=30068 */
    broken_rawevents  = strstr(XServerVendor( gdi_display ), "X.Org") &&
                        XVendorRelease( gdi_display ) < 11004000;

#else
    TRACE( "X Input 2 support not compiled in.\n" );
#endif
}


/***********************************************************************
 *           X11DRV_GenericEvent
 */
void X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
    XGenericEventCookie *event = &xev->xcookie;

    if (!event->data) return;
    if (event->extension != xinput2_opcode) return;

    switch (event->evtype)
    {
    case XI_RawMotion:
        X11DRV_RawMotion( event );
        break;

    default:
        TRACE( "Unhandled event %#x\n", event->evtype );
        break;
    }
#endif
}
