From af9364cadfaa4c658d0836152b295fb2ab5ba84b Mon Sep 17 00:00:00 2001
From: Andrew Riedi <andrewriedi@gmail.com>
Date: Sun, 8 Feb 2009 13:42:51 -0800
Subject: [PATCH] user32: Generate the 16-bit cursor in create_cursor().

---
 dlls/user32/cursoricon.c |  123 ++++++++++++++++++++++++---------------------
 1 files changed, 66 insertions(+), 57 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index cf08121..fda7c51 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -254,10 +254,15 @@ HCURSOR get_cursor_handle(HCURSOR16 cursor16)
     return 0;
 }
 
-static HCURSOR create_cursor(HCURSOR16 cursor16, CURSORICONINFO *cursor_data,
-    data_size_t cursor_size)
+static int get_bitmap_width_bytes(int width, int bpp);
+
+static HCURSOR create_cursor(HINSTANCE16 instance16,
+    CURSORICONINFO *cursor_data, data_size_t cursor_size)
 {
     HCURSOR cursor = 0;
+    HCURSOR16 cursor16 = 0;
+    CURSORICONINFO *info16;
+    SIZE_T size;
 
     SERVER_START_REQ(create_cursor)
     {
@@ -268,9 +273,21 @@ static HCURSOR create_cursor(HCURSOR16 cursor16, CURSORICONINFO *cursor_data,
     }
     SERVER_END_REQ;
 
-    /* FIXME: Make all calls to create_cursor() use HeapAlloc() for the
-     * cursor_data.  Once this is done, NULL can be changed to cursor_data. */
-    add_cursor_entry(cursor16, cursor, NULL);
+    /* Calculate 16-bit cursor size. */
+    size = sizeof(CURSORICONINFO) + cursor_data->nHeight
+        * (get_bitmap_width_bytes(cursor_data->nWidth, 1) + cursor_data->nWidthBytes);
+
+    /* Make 16-bit cursor. */
+    instance16 = GetExePtr(instance16);  /* Make it a module handle. */
+    cursor16 = GlobalAlloc16(GMEM_MOVEABLE, size);
+    FarSetOwner16(cursor16, instance16);
+
+    info16 = GlobalLock16(cursor16);
+    memcpy(info16, cursor_data, size);
+
+    GlobalUnlock16(cursor16);
+
+    add_cursor_entry(cursor16, cursor, cursor_data);
 
     return cursor;
 }
@@ -946,8 +963,8 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
 					   INT width, INT height,
 					   UINT cFlag )
 {
-    HGLOBAL16 hObj;
     HICON cursor = 0;
+    CURSORICONINFO *info;
     static HDC hdcMem;
     int sizeAnd, sizeXor;
     HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
@@ -1103,13 +1120,10 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
     sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
     sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
 
-    hObj = GlobalAlloc16( GMEM_MOVEABLE,
-                     sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
-    if (hObj)
+    info = HeapAlloc(GetProcessHeap(), 0,
+        sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
+    if (info)
     {
-        CURSORICONINFO *info;
-
-        info = GlobalLock16( hObj );
         info->ptHotSpot.x   = hotspot.x;
         info->ptHotSpot.y   = hotspot.y;
         info->nWidth        = bmpXor.bmWidth;
@@ -1123,9 +1137,8 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
         GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
 
         /* Make 32-bit cursor. */
-        cursor = create_cursor(hObj, info, GlobalSize16(hObj));
-
-        GlobalUnlock16( hObj );
+        cursor = create_cursor(0, info,
+            sizeof(CURSORICONINFO) + sizeXor + sizeAnd);
     }
 
     DeleteObject( hAndBits );
@@ -1509,26 +1522,24 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
  *
  * Make a copy of a cursor or icon.
  */
-static HICON CURSORICON_Copy( HINSTANCE16 hInst16, HICON hIcon )
+static HICON CURSORICON_Copy(HINSTANCE16 hInst16, HICON hIcon)
 {
     CURSORICONINFO *ptrOld, *ptrNew;
-    int size;
-    HICON16 hOld = get_cursor_handle16(hIcon);
-    HICON16 hNew;
+    SIZE_T size;
     HICON cursor;
 
-    if (!(ptrOld = GlobalLock16( hOld ))) return 0;
-    if (hInst16 && !(hInst16 = GetExePtr( hInst16 ))) return 0;
-    size = GlobalSize16( hOld );
-    hNew = GlobalAlloc16( GMEM_MOVEABLE, size );
-    FarSetOwner16( hNew, hInst16 );
-    ptrNew = GlobalLock16( hNew );
-    memcpy( ptrNew, ptrOld, size );
+    ptrOld = get_cursor_object(hIcon);
+    if (!ptrOld)
+        return 0;
+    if (hInst16 && !GetExePtr(hInst16))
+        return 0;
 
-    cursor = create_cursor(hNew, ptrNew, size);
+    size = HeapSize(GetProcessHeap(), 0, ptrOld);
 
-    GlobalUnlock16( hOld );
-    GlobalUnlock16( hNew );
+    ptrNew = HeapAlloc(GetProcessHeap(), 0, size);
+    memcpy(ptrNew, ptrOld, size);
+
+    cursor = create_cursor(hInst16, ptrNew, size);
 
     return cursor;
 }
@@ -1776,31 +1787,32 @@ HICON WINAPI CreateIcon(
 /***********************************************************************
  *		CreateCursorIconIndirect (USER.408)
  */
-HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
-                                           CURSORICONINFO *info,
-                                           LPCVOID lpANDbits,
-                                           LPCVOID lpXORbits )
+HGLOBAL16 WINAPI CreateCursorIconIndirect16(HINSTANCE16 hInstance,
+    CURSORICONINFO *info, LPCVOID lpANDbits, LPCVOID lpXORbits)
 {
-    HGLOBAL16 handle;
     HCURSOR cursor;
     CURSORICONINFO *ptr;
     int sizeAnd, sizeXor;
+    SIZE_T size;
 
-    hInstance = GetExePtr( hInstance );  /* Make it a module handle */
-    if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
-    info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
+    if (!lpXORbits || !lpANDbits || info->bPlanes != 1)
+        return 0;
+
+    info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,
+        info->bBitsPerPixel);
     sizeXor = info->nHeight * info->nWidthBytes;
-    sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
-    if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
-                                  sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
+    sizeAnd = info->nHeight * get_bitmap_width_bytes(info->nWidth, 1);
+    size = sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
+
+    ptr = HeapAlloc(GetProcessHeap(), 0, size);
+    if (!ptr)
         return 0;
-    FarSetOwner16( handle, hInstance );
-    ptr = GlobalLock16( handle );
-    memcpy( ptr, info, sizeof(*info) );
-    memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
-    memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
-    cursor = create_cursor(handle, ptr, GlobalSize16(handle));
-    GlobalUnlock16( handle );
+
+    memcpy(ptr, info, sizeof(*info));
+    memcpy(ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd);
+    memcpy(ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor);
+
+    cursor = create_cursor(hInstance, ptr, size);
 
     return get_cursor_handle16(cursor);
 }
@@ -2279,11 +2291,12 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
  */
 HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 {
+    CURSORICONINFO *info;
     DIBSECTION bmpXor;
     BITMAP bmpAnd;
-    HICON16 hObj;
     HCURSOR cursor = 0;
     int xor_objsize = 0, sizeXor = 0, sizeAnd, planes, bpp;
+    SIZE_T size;
 
     TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
            iconinfo->hbmColor, iconinfo->hbmMask,
@@ -2311,14 +2324,10 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 
     sizeAnd = bmpAnd.bmHeight * get_bitmap_width_bytes(bmpAnd.bmWidth, 1);
 
-    hObj = GlobalAlloc16( GMEM_MOVEABLE,
-                          sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
-    if (hObj)
+    size = sizeof(CURSORICONINFO) + sizeXor + sizeAnd;
+    info = HeapAlloc(GetProcessHeap(), 0, size);
+    if (info)
     {
-        CURSORICONINFO *info;
-
-        info = GlobalLock16( hObj );
-
         /* If we are creating an icon, the hotspot is unused */
         if (iconinfo->fIcon)
         {
@@ -2426,9 +2435,9 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
                                dst_bits, &bminfo, DIB_RGB_COLORS );
             }
         }
-        cursor = create_cursor(hObj, info, GlobalSize16(hObj));
-        GlobalUnlock16( hObj );
+        cursor = create_cursor(0, info, size);
     }
+
     return cursor;
 }
 
-- 
1.5.6.3

