From 7006ddd2ade0341f5505e0d0a32b9e6fdf3184dd Mon Sep 17 00:00:00 2001
From: Andrew Riedi <andrewriedi@gmail.com>
Date: Sun, 15 Feb 2009 14:07:08 -0800
Subject: [PATCH] user32: Create and use 'struct cursor' where possible.

This allows .ani cursors to be implemented completely.  Also, the cursor and
icon functions are implicitly converted out of 16-bit.
---
 dlls/user32/cursoricon.c   |  202 ++++++++++++++++++++++++++------------------
 dlls/user32/display.c      |    2 +-
 dlls/user32/driver.c       |    6 +-
 dlls/user32/user_private.h |    5 +-
 dlls/winex11.drv/mouse.c   |   24 +++---
 dlls/winex11.drv/x11drv.h  |    5 +-
 include/wine/winuser16.h   |    6 ++
 7 files changed, 147 insertions(+), 103 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index fda7c51..d414bf0 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -139,7 +139,7 @@ struct cursor_map_entry
     HCURSOR             cursor;
     HCURSOR16           cursor16;
     /* Cache the cursor data since most calls to wineserver are unneeded. */
-    CURSORICONINFO     *data;
+    struct cursor      *data;
 };
 
 static struct rb_tree global_cursor_map;
@@ -180,7 +180,7 @@ void CURSORICON_init(void)
 }
 
 static void add_cursor_entry(HCURSOR16 cursor16, HCURSOR cursor,
-    CURSORICONINFO *data)
+    struct cursor *data)
 {
     struct cursor_map_entry *map_entry;
 
@@ -256,12 +256,12 @@ HCURSOR get_cursor_handle(HCURSOR16 cursor16)
 
 static int get_bitmap_width_bytes(int width, int bpp);
 
-static HCURSOR create_cursor(HINSTANCE16 instance16,
-    CURSORICONINFO *cursor_data, data_size_t cursor_size)
+static HCURSOR create_cursor(HINSTANCE16 instance16, struct cursor *cursor_data,
+    data_size_t cursor_size)
 {
     HCURSOR cursor = 0;
     HCURSOR16 cursor16 = 0;
-    CURSORICONINFO *info16;
+    CURSORICONINFO *info, *info16;
     SIZE_T size;
 
     SERVER_START_REQ(create_cursor)
@@ -274,8 +274,9 @@ static HCURSOR create_cursor(HINSTANCE16 instance16,
     SERVER_END_REQ;
 
     /* Calculate 16-bit cursor size. */
-    size = sizeof(CURSORICONINFO) + cursor_data->nHeight
-        * (get_bitmap_width_bytes(cursor_data->nWidth, 1) + cursor_data->nWidthBytes);
+    info = (CURSORICONINFO *) (cursor_data + 1);
+    size = sizeof(CURSORICONINFO) + info->nHeight
+        * (get_bitmap_width_bytes(info->nWidth, 1) + info->nWidthBytes);
 
     /* Make 16-bit cursor. */
     instance16 = GetExePtr(instance16);  /* Make it a module handle. */
@@ -283,7 +284,7 @@ static HCURSOR create_cursor(HINSTANCE16 instance16,
     FarSetOwner16(cursor16, instance16);
 
     info16 = GlobalLock16(cursor16);
-    memcpy(info16, cursor_data, size);
+    memcpy(info16, info, size);
 
     GlobalUnlock16(cursor16);
 
@@ -311,11 +312,11 @@ static HCURSOR16 destroy_cursor(HCURSOR cursor)
     return GlobalFree16(cursor16);
 }
 
-static CURSORICONINFO *get_cursor_object(HCURSOR hCursor)
+static struct cursor *get_cursor_object(HCURSOR hCursor)
 {
     struct cursor_map_entry *map_entry = NULL;
     data_size_t guess_size, cursor_size = 0;
-    CURSORICONINFO *cursor = NULL;
+    struct cursor *cursor = NULL;
 
     if (hCursor)
     {
@@ -411,7 +412,7 @@ void CURSORICON_refresh_cursor16(HCURSOR16 cursor16)
         return;
 
     /* Make room for new 32-bit cursor copy, if needed. */
-    size = GlobalSize16(cursor16);
+    size = sizeof(struct cursor) + GlobalSize16(cursor16);
     if (!map_entry->data
         || HeapSize(GetProcessHeap(), 0, map_entry->data) < size)
     {
@@ -420,9 +421,13 @@ void CURSORICON_refresh_cursor16(HCURSOR16 cursor16)
         map_entry->data = HeapAlloc(GetProcessHeap(), 0, size);
     }
 
+    /* Set up struct cursor. */
+    map_entry->data->num_frames = 1;
+    map_entry->data->delay = 0;
+
     /* Copy 16-bit cursor into a 32-bit cursor. */
     info16 = GlobalLock16(cursor16);
-    memcpy(map_entry->data, info16, size);
+    memcpy(map_entry->data + 1, info16, size - sizeof(struct cursor));
     GlobalUnlock16(cursor16);
 }
 
@@ -964,7 +969,7 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
 					   UINT cFlag )
 {
     HICON cursor = 0;
-    CURSORICONINFO *info;
+    struct cursor *cursor_data;
     static HDC hdcMem;
     int sizeAnd, sizeXor;
     HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
@@ -1120,10 +1125,15 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
     sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
     sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
 
-    info = HeapAlloc(GetProcessHeap(), 0,
-        sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
-    if (info)
+    cursor_data = HeapAlloc(GetProcessHeap(), 0,
+        sizeof(struct cursor) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
+    if (cursor_data)
     {
+        CURSORICONINFO *info = (CURSORICONINFO *) (cursor_data + 1);
+
+        cursor_data->num_frames = 1;
+        cursor_data->delay = 0;
+
         info->ptHotSpot.x   = hotspot.x;
         info->ptHotSpot.y   = hotspot.y;
         info->nWidth        = bmpXor.bmWidth;
@@ -1137,8 +1147,8 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
         GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
 
         /* Make 32-bit cursor. */
-        cursor = create_cursor(0, info,
-            sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
+        cursor = create_cursor(0, cursor_data,
+            sizeof(struct cursor) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
     }
 
     DeleteObject( hAndBits );
@@ -1524,7 +1534,7 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
  */
 static HICON CURSORICON_Copy(HINSTANCE16 hInst16, HICON hIcon)
 {
-    CURSORICONINFO *ptrOld, *ptrNew;
+    struct cursor *ptrOld, *ptrNew;
     SIZE_T size;
     HICON cursor;
 
@@ -1792,6 +1802,7 @@ HGLOBAL16 WINAPI CreateCursorIconIndirect16(HINSTANCE16 hInstance,
 {
     HCURSOR cursor;
     CURSORICONINFO *ptr;
+    struct cursor *cursor_data;
     int sizeAnd, sizeXor;
     SIZE_T size;
 
@@ -1802,17 +1813,21 @@ HGLOBAL16 WINAPI CreateCursorIconIndirect16(HINSTANCE16 hInstance,
         info->bBitsPerPixel);
     sizeXor = info->nHeight * info->nWidthBytes;
     sizeAnd = info->nHeight * get_bitmap_width_bytes(info->nWidth, 1);
-    size = sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
+    size = sizeof(struct cursor) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
 
-    ptr = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!ptr)
+    cursor_data = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!cursor_data)
         return 0;
 
+    cursor_data->num_frames = 1;
+    cursor_data->delay = 0;
+
+    ptr = (CURSORICONINFO *) (cursor_data + 1);
     memcpy(ptr, info, sizeof(*info));
     memcpy(ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd);
     memcpy(ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor);
 
-    cursor = create_cursor(hInstance, ptr, size);
+    cursor = create_cursor(hInstance, cursor_data, size);
 
     return get_cursor_handle16(cursor);
 }
@@ -1911,37 +1926,44 @@ BOOL WINAPI DestroyCursor( HCURSOR hCursor )
  */
 BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
 {
-    CURSORICONINFO *ptr;
+    struct cursor *cursor_data;
+    CURSORICONINFO *info;
     HDC hMemDC;
     HBITMAP hXorBits, hAndBits;
     COLORREF oldFg, oldBg;
 
     TRACE("%p, (%d,%d), %p\n", hdc, x, y, hIcon);
 
-    if (!(ptr = GlobalLock16(get_cursor_handle16(hIcon)))) return FALSE;
+    cursor_data = get_cursor_object(hIcon);
+    if (!cursor_data)
+        return FALSE;
+
+    info = (CURSORICONINFO *) (cursor_data + 1);
+
     if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE;
-    hAndBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1,
-                               (char *)(ptr+1) );
-    hXorBits = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes,
-                               ptr->bBitsPerPixel, (char *)(ptr + 1)
-                        + ptr->nHeight * get_bitmap_width_bytes(ptr->nWidth,1) );
+    hAndBits = CreateBitmap(info->nWidth, info->nHeight, 1, 1,
+        (char *)(info + 1));
+    hXorBits = CreateBitmap(info->nWidth, info->nHeight, info->bPlanes,
+        info->bBitsPerPixel, (char *)(info + 1) + info->nHeight
+        * get_bitmap_width_bytes(info->nWidth, 1));
     oldFg = SetTextColor( hdc, RGB(0,0,0) );
     oldBg = SetBkColor( hdc, RGB(255,255,255) );
 
     if (hXorBits && hAndBits)
     {
         HBITMAP hBitTemp = SelectObject( hMemDC, hAndBits );
-        BitBlt( hdc, x, y, ptr->nWidth, ptr->nHeight, hMemDC, 0, 0, SRCAND );
+        BitBlt(hdc, x, y, info->nWidth, info->nHeight, hMemDC, 0, 0, SRCAND);
         SelectObject( hMemDC, hXorBits );
-        BitBlt(hdc, x, y, ptr->nWidth, ptr->nHeight, hMemDC, 0, 0,SRCINVERT);
+        BitBlt(hdc, x, y, info->nWidth, info->nHeight, hMemDC, 0, 0, SRCINVERT);
         SelectObject( hMemDC, hBitTemp );
     }
     DeleteDC( hMemDC );
     if (hXorBits) DeleteObject( hXorBits );
     if (hAndBits) DeleteObject( hAndBits );
-    GlobalUnlock16(get_cursor_handle16(hIcon));
+
     SetTextColor( hdc, oldFg );
     SetBkColor( hdc, oldBg );
+
     return TRUE;
 }
 
@@ -2238,39 +2260,40 @@ HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name)
  */
 BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
 {
-    CURSORICONINFO *ciconinfo;
+    struct cursor *cursor_data;
+    CURSORICONINFO *info;
     INT height;
 
-    ciconinfo = GlobalLock16(get_cursor_handle16(hIcon));
-    if (!ciconinfo)
+    cursor_data = get_cursor_object(hIcon);
+    if (!cursor_data)
         return FALSE;
 
-    TRACE("%p => %dx%d, %d bpp\n", hIcon,
-          ciconinfo->nWidth, ciconinfo->nHeight, ciconinfo->bBitsPerPixel);
+    info = (CURSORICONINFO *) (cursor_data + 1);
+
+    TRACE("%p => %dx%d, %d bpp\n", hIcon, info->nWidth, info->nHeight,
+        info->bBitsPerPixel);
 
-    if ( (ciconinfo->ptHotSpot.x == ICON_HOTSPOT) &&
-         (ciconinfo->ptHotSpot.y == ICON_HOTSPOT) )
+    if ((info->ptHotSpot.x == ICON_HOTSPOT)
+        && (info->ptHotSpot.y == ICON_HOTSPOT))
     {
-      iconinfo->fIcon    = TRUE;
-      iconinfo->xHotspot = ciconinfo->nWidth / 2;
-      iconinfo->yHotspot = ciconinfo->nHeight / 2;
+        iconinfo->fIcon    = TRUE;
+        iconinfo->xHotspot = info->nWidth / 2;
+        iconinfo->yHotspot = info->nHeight / 2;
     }
     else
     {
-      iconinfo->fIcon    = FALSE;
-      iconinfo->xHotspot = ciconinfo->ptHotSpot.x;
-      iconinfo->yHotspot = ciconinfo->ptHotSpot.y;
+        iconinfo->fIcon    = FALSE;
+        iconinfo->xHotspot = info->ptHotSpot.x;
+        iconinfo->yHotspot = info->ptHotSpot.y;
     }
 
-    height = ciconinfo->nHeight;
+    height = info->nHeight;
 
-    if (ciconinfo->bBitsPerPixel > 1)
+    if (info->bBitsPerPixel > 1)
     {
-        iconinfo->hbmColor = CreateBitmap( ciconinfo->nWidth, ciconinfo->nHeight,
-                                ciconinfo->bPlanes, ciconinfo->bBitsPerPixel,
-                                (char *)(ciconinfo + 1)
-                                + ciconinfo->nHeight *
-                                get_bitmap_width_bytes (ciconinfo->nWidth,1) );
+        iconinfo->hbmColor = CreateBitmap(info->nWidth, info->nHeight,
+            info->bPlanes, info->bBitsPerPixel, (char *)(info + 1)
+            + info->nHeight * get_bitmap_width_bytes(info->nWidth, 1));
     }
     else
     {
@@ -2278,10 +2301,8 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
         height *= 2;
     }
 
-    iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, height,
-                                1, 1, (char *)(ciconinfo + 1));
-
-    GlobalUnlock16(get_cursor_handle16(hIcon));
+    iconinfo->hbmMask = CreateBitmap(info->nWidth, height, 1, 1,
+        (char *)(info + 1));
 
     return TRUE;
 }
@@ -2291,7 +2312,7 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
  */
 HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 {
-    CURSORICONINFO *info;
+    struct cursor *cursor_data;
     DIBSECTION bmpXor;
     BITMAP bmpAnd;
     HCURSOR cursor = 0;
@@ -2324,10 +2345,15 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 
     sizeAnd = bmpAnd.bmHeight * get_bitmap_width_bytes(bmpAnd.bmWidth, 1);
 
-    size = sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
-    info = HeapAlloc(GetProcessHeap(), 0, size);
-    if (info)
+    size = sizeof(struct cursor) + sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
+    cursor_data = HeapAlloc(GetProcessHeap(), 0, size);
+    if (cursor_data)
     {
+        CURSORICONINFO *info = (CURSORICONINFO *) (cursor_data + 1);
+
+        cursor_data->num_frames = 1;
+        cursor_data->delay = 0;
+
         /* If we are creating an icon, the hotspot is unused */
         if (iconinfo->fIcon)
         {
@@ -2435,7 +2461,7 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
                                dst_bits, &bminfo, DIB_RGB_COLORS );
             }
         }
-        cursor = create_cursor(0, info, size);
+        cursor = create_cursor(0, cursor_data, size);
     }
 
     return cursor;
@@ -2466,12 +2492,18 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
                             INT cxWidth, INT cyWidth, UINT istep,
                             HBRUSH hbr, UINT flags )
 {
-    CURSORICONINFO *ptr = GlobalLock16(get_cursor_handle16(hIcon));
+    struct cursor *cursor_data;
+    CURSORICONINFO *info;
     HDC hDC_off = 0, hMemDC;
     BOOL result = FALSE, DoOffscreen;
     HBITMAP hB_off = 0, hOld = 0;
 
-    if (!ptr) return FALSE;
+    cursor_data = get_cursor_object(hIcon);
+    if (!cursor_data)
+        return FALSE;
+
+    info = (CURSORICONINFO *) (cursor_data + 1);
+
     TRACE_(icon)("(hdc=%p,pos=%d.%d,hicon=%p,extend=%d.%d,istep=%d,br=%p,flags=0x%08x)\n",
                  hdc,x0,y0,hIcon,cxWidth,cyWidth,istep,hbr,flags );
 
@@ -2492,14 +2524,14 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
         if (flags & DI_DEFAULTSIZE)
             cxWidth = GetSystemMetrics (SM_CXICON);
         else
-            cxWidth = ptr->nWidth;
+            cxWidth = info->nWidth;
     }
     if (cyWidth == 0)
     {
         if (flags & DI_DEFAULTSIZE)
             cyWidth = GetSystemMetrics (SM_CYICON);
         else
-            cyWidth = ptr->nHeight;
+            cyWidth = info->nHeight;
     }
 
     DoOffscreen = (GetObjectType( hbr ) == OBJ_BRUSH);
@@ -2528,13 +2560,11 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
 
         nStretchMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS);
 
-        hXorBits = CreateBitmap ( ptr->nWidth, ptr->nHeight,
-                                  ptr->bPlanes, ptr->bBitsPerPixel,
-                                  (char *)(ptr + 1)
-                                  + ptr->nHeight *
-                                  get_bitmap_width_bytes(ptr->nWidth,1) );
-        hAndBits = CreateBitmap ( ptr->nWidth, ptr->nHeight,
-                                  1, 1, (char *)(ptr+1) );
+        hXorBits = CreateBitmap(info->nWidth, info->nHeight, info->bPlanes,
+            info->bBitsPerPixel, (char *)(info + 1) + info->nHeight *
+            get_bitmap_width_bytes(info->nWidth,1));
+        hAndBits = CreateBitmap(info->nWidth, info->nHeight, 1, 1,
+            (char *)(info + 1) );
         oldFg = SetTextColor( hdc, RGB(0,0,0) );
         oldBg = SetBkColor( hdc, RGB(255,255,255) );
 
@@ -2544,21 +2574,29 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
             if (flags & DI_MASK)
             {
                 if (DoOffscreen)
-                    StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth,
-                                hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND);
+                {
+                    StretchBlt(hDC_off, 0, 0, cxWidth, cyWidth, hMemDC, 0, 0,
+                        info->nWidth, info->nHeight, SRCAND);
+                }
                 else
-                    StretchBlt (hdc, x0, y0, cxWidth, cyWidth,
-                                hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND);
+                {
+                    StretchBlt(hdc, x0, y0, cxWidth, cyWidth, hMemDC, 0, 0,
+                        info->nWidth, info->nHeight, SRCAND);
+                }
             }
             SelectObject( hMemDC, hXorBits );
             if (flags & DI_IMAGE)
             {
                 if (DoOffscreen)
-                    StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth,
-                                hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCPAINT);
+                {
+                    StretchBlt(hDC_off, 0, 0, cxWidth, cyWidth, hMemDC, 0, 0,
+                        info->nWidth, info->nHeight, SRCPAINT);
+                }
                 else
-                    StretchBlt (hdc, x0, y0, cxWidth, cyWidth,
-                                hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCPAINT);
+                {
+                    StretchBlt(hdc, x0, y0, cxWidth, cyWidth, hMemDC, 0, 0,
+                        info->nWidth, info->nHeight, SRCPAINT);
+                }
             }
             SelectObject( hMemDC, hBitTemp );
             result = TRUE;
@@ -2577,7 +2615,7 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon,
     if (hMemDC) DeleteDC( hMemDC );
     if (hDC_off) DeleteDC(hDC_off);
     if (hB_off) DeleteObject(hB_off);
-    GlobalUnlock16(get_cursor_handle16(hIcon));
+
     return result;
 }
 
diff --git a/dlls/user32/display.c b/dlls/user32/display.c
index 4288738..73006d0 100644
--- a/dlls/user32/display.c
+++ b/dlls/user32/display.c
@@ -50,7 +50,7 @@ WORD WINAPI DISPLAY_Inquire(LPCURSORINFO16 lpCursorInfo)
 /***********************************************************************
  *           SetCursor			(DISPLAY.102)
  */
-VOID WINAPI DISPLAY_SetCursor( struct tagCURSORICONINFO *lpCursor )
+VOID WINAPI DISPLAY_SetCursor( struct cursor *lpCursor )
 {
     USER_Driver->pSetCursor(lpCursor);
 }
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 6454f65..000ba6e 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -215,7 +215,7 @@ static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout )
     return -1;
 }
 
-static void CDECL nulldrv_SetCursor( struct tagCURSORICONINFO *info )
+static void CDECL nulldrv_SetCursor( struct cursor *cursor )
 {
 }
 
@@ -556,9 +556,9 @@ static SHORT CDECL loaderdrv_VkKeyScanEx( WCHAR ch, HKL layout )
     return load_driver()->pVkKeyScanEx( ch, layout );
 }
 
-static void CDECL loaderdrv_SetCursor( struct tagCURSORICONINFO *info )
+static void CDECL loaderdrv_SetCursor( struct cursor *cursor )
 {
-    load_driver()->pSetCursor( info );
+    load_driver()->pSetCursor( cursor );
 }
 
 static BOOL CDECL loaderdrv_GetCursorPos( LPPOINT pt )
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 3e6a2a2..db1cc3c 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -30,6 +30,7 @@
 #include "winternl.h"
 #include "wine/windef16.h"
 #include "wine/winbase16.h"
+#include "wine/winuser16.h"
 
 extern WORD USER_HeapSel DECLSPEC_HIDDEN;
 
@@ -100,8 +101,6 @@ enum wine_internal_message
     WM_WINE_LAST_DRIVER_MSG = 0x80001fff
 };
 
-struct tagCURSORICONINFO;
-
 typedef struct tagUSER_DRIVER {
     /* keyboard functions */
     HKL    (CDECL *pActivateKeyboardLayout)(HKL, UINT);
@@ -117,7 +116,7 @@ typedef struct tagUSER_DRIVER {
     BOOL   (CDECL *pUnloadKeyboardLayout)(HKL);
     SHORT  (CDECL *pVkKeyScanEx)(WCHAR, HKL);
     /* mouse functions */
-    void   (CDECL *pSetCursor)(struct tagCURSORICONINFO *);
+    void   (CDECL *pSetCursor)(struct cursor *);
     BOOL   (CDECL *pGetCursorPos)(LPPOINT);
     BOOL   (CDECL *pSetCursorPos)(INT,INT);
     BOOL   (CDECL *pClipCursor)(LPCRECT);
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 5282412..29932f3 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -3,6 +3,7 @@
  *
  * Copyright 1998 Ulrich Weigand
  * Copyright 2007 Henri Verbeet
+ * Copyright 2009 Andrew Riedi
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -577,12 +578,14 @@ static XcursorImage *create_cursor_image( CURSORICONINFO *ptr )
  *
  * Use Xcursor to create an X cursor from a Windows one.
  */
-static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr )
+static Cursor create_xcursor_cursor(Display *display,
+    struct cursor *cursor_data)
 {
     Cursor cursor;
     XcursorImage *image;
+    CURSORICONINFO *ptr;
 
-    if (!ptr) /* Create an empty cursor */
+    if (!cursor_data || !cursor_data->num_frames) /* Create an empty cursor. */
     {
         image = pXcursorImageCreate( 1, 1 );
         image->xhot = 0;
@@ -594,6 +597,7 @@ static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr )
         return cursor;
     }
 
+    ptr = (CURSORICONINFO *) (cursor_data + 1);
     image = create_cursor_image( ptr );
     if (!image) return 0;
 
@@ -623,7 +627,7 @@ static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr )
  *
  * Create an X cursor from a Windows one.
  */
-static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
+static Cursor create_cursor(Display *display, struct cursor *cursor_data)
 {
     Pixmap pixmapBits, pixmapMask, pixmapMaskInv = 0, pixmapAll;
     XColor fg, bg;
@@ -633,10 +637,11 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
     BOOL alpha_zero = TRUE;
 
 #ifdef SONAME_LIBXCURSOR
-    if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr );
+    if (pXcursorImageLoadCursor)
+        return create_xcursor_cursor(display, cursor_data);
 #endif
 
-    if (!ptr)  /* Create an empty cursor */
+    if (!cursor_data || !cursor_data->num_frames)  /* Create an empty cursor. */
     {
         static const char data[] = { 0 };
 
@@ -653,6 +658,7 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
     {
         XImage *image;
         GC gc;
+        CURSORICONINFO *ptr = (CURSORICONINFO *) (cursor_data + 1);
 
         TRACE("Bitmap %dx%d planes=%d bpp=%d bytesperline=%d\n",
             ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel,
@@ -947,16 +953,12 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
 /***********************************************************************
  *		SetCursor (X11DRV.@)
  */
-void CDECL X11DRV_SetCursor( CURSORICONINFO *lpCursor )
+void CDECL X11DRV_SetCursor(struct cursor *lpCursor)
 {
     struct x11drv_thread_data *data = x11drv_init_thread_data();
     Cursor cursor;
 
-    if (lpCursor)
-        TRACE("%ux%u, planes %u, bpp %u\n",
-              lpCursor->nWidth, lpCursor->nHeight, lpCursor->bPlanes, lpCursor->bBitsPerPixel);
-    else
-        TRACE("NULL\n");
+    TRACE("\n");
 
     /* set the same cursor for all top-level windows of the current thread */
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 7d0b2ba..45f6605 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -60,12 +60,11 @@ typedef int Status;
 #include "winuser.h"
 #include "ddrawi.h"
 #include "wine/list.h"
+#include "wine/winuser16.h"
 
 #define MAX_PIXELFORMATS 8
 #define MAX_DASHLEN 16
 
-struct tagCURSORICONINFO;
-
 extern void CDECL wine_tsx11_lock(void);
 extern void CDECL wine_tsx11_unlock(void);
 
@@ -737,7 +736,7 @@ extern int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow);
 extern void X11DRV_ResetSelectionOwner(void);
 extern void CDECL X11DRV_SetFocus( HWND hwnd );
 extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
-extern void CDECL X11DRV_SetCursor( struct tagCURSORICONINFO *lpCursor );
+extern void CDECL X11DRV_SetCursor( struct cursor *lpCursor );
 extern BOOL CDECL X11DRV_ClipCursor( LPCRECT clip );
 extern void X11DRV_InitKeyboard( Display *display );
 extern void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h
index 0a05bdd..ca78f56 100644
--- a/include/wine/winuser16.h
+++ b/include/wine/winuser16.h
@@ -158,6 +158,12 @@ typedef struct tagCURSORICONINFO
     BYTE    bBitsPerPixel;
 } CURSORICONINFO;
 
+struct cursor
+{
+    UINT num_frames;
+    UINT delay;
+};
+
 typedef struct {
 	BOOL16		fIcon;
 	WORD		xHotspot;
-- 
1.5.6.3

