[2/2] USER: Store some usefull data in cursor / icon handles

H. Verbeet hverbeet at gmail.com
Sun May 28 16:47:06 CDT 2006


This patch stores the hotspot, XOR bitmap and AND bitmap handle in the
cursor object. The memory block representation for 16-bit applications
is only built once asked for. Unfortunately there are still quite a
few 32-bit functions that use 16-bit functions internally.

Changelog:
  - Store some usefull data in cursor / icon handles
-------------- next part --------------
diff --git a/dlls/user/cursoricon.c b/dlls/user/cursoricon.c
index e1e952f..cfbdaef 100644
--- a/dlls/user/cursoricon.c
+++ b/dlls/user/cursoricon.c
@@ -203,8 +203,6 @@ static HCURSOR create_cursor_handle( cur
     }
     SERVER_END_REQ;
 
-    add_cursor16to32_entry( cursor->cursor16, handle );
-
     return handle;
 }
 
@@ -219,6 +217,8 @@ static HCURSOR16 destroy_cursor( HCURSOR
     }
     SERVER_END_REQ;
 
+    DeleteObject( cursor->and_handle );
+    DeleteObject( cursor->xor_handle );
     remove_cursor16to32_entry( cursor->cursor16 );
     return GlobalFree16( cursor->cursor16 );
 }
@@ -239,9 +239,37 @@ HCURSOR get_cursor_handle32( HCURSOR16 c
 
 HCURSOR16 get_cursor_handle16( HCURSOR handle )
 {
+    int and_size, xor_size;
+    BITMAP bm_and, bm_xor;
     cursor_object *cursor = get_cursor_object( handle );
 
     if (!cursor) return INVALID_HANDLE_VALUE16;
+    if (cursor->cursor16) return cursor->cursor16;
+
+    GetObjectW( cursor->and_handle, sizeof(bm_and), &bm_and );
+    GetObjectW( cursor->xor_handle, sizeof(bm_xor), &bm_xor );
+    and_size = bm_and.bmHeight * bm_and.bmWidthBytes;
+    xor_size = bm_xor.bmHeight * bm_xor.bmWidthBytes;
+
+    cursor->cursor16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(CURSORICONINFO) + and_size + xor_size );
+    if (cursor->cursor16)
+    {
+        CURSORICONINFO *info;
+
+        info = (CURSORICONINFO *)GlobalLock16( cursor->cursor16 );
+        info->ptHotSpot     = cursor->hotspot;
+        info->nWidth        = bm_xor.bmWidth;
+        info->nHeight       = bm_xor.bmHeight;
+        info->nWidthBytes   = bm_xor.bmWidthBytes;
+        info->bPlanes       = bm_xor.bmPlanes;
+        info->bBitsPerPixel = bm_xor.bmBitsPixel;
+
+        /* Transfer the bitmap bits to the CURSORICONINFO structure */
+        GetBitmapBits( cursor->and_handle, and_size, (char *)(info + 1) );
+        GetBitmapBits( cursor->xor_handle, xor_size, (char *)(info + 1) + and_size );
+        GlobalUnlock16( cursor->cursor16 );
+    }
+    add_cursor16to32_entry( cursor->cursor16, handle );
 
     return cursor->cursor16;
 }
@@ -790,12 +818,9 @@ HICON WINAPI CreateIconFromResourceEx( L
                                        INT width, INT height,
                                        UINT cFlag )
 {
-    HGLOBAL16 hObj;
     cursor_object *cursor;
     static HDC hdcMem;
-    int sizeAnd, sizeXor;
     HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */
-    BITMAP bmpXor, bmpAnd;
     POINT16 hotspot;
     BITMAPINFO *bmi;
     BOOL DoStretch;
@@ -957,39 +982,11 @@ HICON WINAPI CreateIconFromResourceEx( L
         return 0;
     }
 
-    /* Now create the CURSORICONINFO structure */
-    GetObjectA( hXorBits, sizeof(bmpXor), &bmpXor );
-    GetObjectA( hAndBits, sizeof(bmpAnd), &bmpAnd );
-    sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes;
-    sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
-
-    hObj = GlobalAlloc16( GMEM_MOVEABLE,
-                     sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
-    if (hObj)
-    {
-        CURSORICONINFO *info;
-
-        info = (CURSORICONINFO *)GlobalLock16( hObj );
-        info->ptHotSpot.x   = hotspot.x;
-        info->ptHotSpot.y   = hotspot.y;
-        info->nWidth        = bmpXor.bmWidth;
-        info->nHeight       = bmpXor.bmHeight;
-        info->nWidthBytes   = bmpXor.bmWidthBytes;
-        info->bPlanes       = bmpXor.bmPlanes;
-        info->bBitsPerPixel = bmpXor.bmBitsPixel;
-
-        /* Transfer the bitmap bits to the CURSORICONINFO structure */
-
-        GetBitmapBits( hAndBits, sizeAnd, (char *)(info + 1) );
-        GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
-        GlobalUnlock16( hObj );
-    }
-
-    DeleteObject( hAndBits );
-    DeleteObject( hXorBits );
-
     cursor = HeapAlloc( GetProcessHeap(), 0, sizeof(cursor_object) );
-    cursor->cursor16 = hObj;
+    cursor->hotspot = hotspot;
+    cursor->xor_handle = hXorBits;
+    cursor->and_handle = hAndBits;
+    cursor->cursor16 = 0;
     return create_cursor_handle( cursor );
 }
 
@@ -1128,24 +1125,13 @@ static HICON CURSORICON_Load(HINSTANCE h
  */
 static HICON CURSORICON_Copy( HINSTANCE16 hInst16, HICON hIcon )
 {
-    cursor_object *cursor;
-    char *ptrOld, *ptrNew;
-    int size;
-    HICON16 hOld = HICON_16(hIcon);
-    HICON16 hNew;
-
-    if (!(ptrOld = (char *)GlobalLock16( hOld ))) return 0;
-    if (hInst16 && !(hInst16 = GetExePtr( hInst16 ))) return 0;
-    size = GlobalSize16( hOld );
-    hNew = GlobalAlloc16( GMEM_MOVEABLE, size );
-    FarSetOwner16( hNew, hInst16 );
-    ptrNew = (char *)GlobalLock16( hNew );
-    memcpy( ptrNew, ptrOld, size );
-    GlobalUnlock16( hOld );
-    GlobalUnlock16( hNew );
+    cursor_object *old_cursor = get_cursor_object( hIcon );
+    cursor_object *cursor = HeapAlloc( GetProcessHeap(), 0, sizeof(cursor_object) );
+    cursor->hotspot = old_cursor->hotspot;
+    cursor->xor_handle = (HBITMAP)CopyImage( old_cursor->xor_handle, IMAGE_BITMAP, 0, 0, 0 );
+    cursor->and_handle = (HBITMAP)CopyImage( old_cursor->and_handle, IMAGE_BITMAP, 0, 0, 0 );
+    cursor->cursor16 = 0;
 
-    cursor = HeapAlloc( GetProcessHeap(), 0, sizeof(cursor_object) );
-    cursor->cursor16 = hNew;
     return create_cursor_handle( cursor );
 }
 
@@ -1930,63 +1916,20 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PIC
  */
 HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 {
-    cursor_object *cursor;
-    BITMAP bmpXor,bmpAnd;
-    HICON16 hObj;
-    int	sizeXor,sizeAnd;
-
-    if (iconinfo->hbmColor) GetObjectA( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
-    GetObjectA( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
-
-    sizeXor = iconinfo->hbmColor ? (bmpXor.bmHeight * bmpXor.bmWidthBytes) : 0;
-    sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes;
-
-    hObj = GlobalAlloc16( GMEM_MOVEABLE,
-                          sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
-    if (hObj)
+    cursor_object *cursor = HeapAlloc( GetProcessHeap(), 0, sizeof(cursor_object) );
+    /* If we are creating an icon, the hotspot is unused */
+    if (iconinfo->fIcon)
     {
-        CURSORICONINFO *info;
-
-        info = (CURSORICONINFO *)GlobalLock16( hObj );
-
-        /* If we are creating an icon, the hotspot is unused */
-        if (iconinfo->fIcon)
-        {
-            info->ptHotSpot.x   = ICON_HOTSPOT;
-            info->ptHotSpot.y   = ICON_HOTSPOT;
-        }
-        else
-        {
-            info->ptHotSpot.x   = iconinfo->xHotspot;
-            info->ptHotSpot.y   = iconinfo->yHotspot;
-        }
-
-        if (iconinfo->hbmColor)
-        {
-            info->nWidth        = bmpXor.bmWidth;
-            info->nHeight       = bmpXor.bmHeight;
-            info->nWidthBytes   = bmpXor.bmWidthBytes;
-            info->bPlanes       = bmpXor.bmPlanes;
-            info->bBitsPerPixel = bmpXor.bmBitsPixel;
-        }
-        else
-        {
-            info->nWidth        = bmpAnd.bmWidth;
-            info->nHeight       = bmpAnd.bmHeight / 2;
-            info->nWidthBytes   = bmpAnd.bmWidthBytes;
-            info->bPlanes       = bmpAnd.bmPlanes;
-            info->bBitsPerPixel = bmpAnd.bmBitsPixel;
-        }
-
-        /* Transfer the bitmap bits to the CURSORICONINFO structure */
-
-        GetBitmapBits( iconinfo->hbmMask, sizeAnd, (char*)(info + 1) );
-        if (iconinfo->hbmColor) GetBitmapBits( iconinfo->hbmColor, sizeXor, (char*)(info + 1) + sizeAnd );
-        GlobalUnlock16( hObj );
+        cursor->hotspot.x   = ICON_HOTSPOT;
+        cursor->hotspot.y   = ICON_HOTSPOT;
+    } else {
+        cursor->hotspot.x   = iconinfo->xHotspot;
+        cursor->hotspot.y   = iconinfo->yHotspot;
     }
+    cursor->xor_handle = (HBITMAP)CopyImage( iconinfo->hbmColor, IMAGE_BITMAP, 0, 0, 0 );
+    cursor->and_handle = (HBITMAP)CopyImage( iconinfo->hbmMask, IMAGE_BITMAP, 0, 0, 0 );
+    cursor->cursor16 = 0;
 
-    cursor = HeapAlloc( GetProcessHeap(), 0, sizeof(cursor_object) );
-    cursor->cursor16 = hObj;
     return create_cursor_handle( cursor );
 }
 
diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h
index b229e4e..971db5d 100644
--- a/include/wine/winuser16.h
+++ b/include/wine/winuser16.h
@@ -150,7 +150,10 @@ typedef struct
 
 typedef struct cursor_object
 {
-    HCURSOR16   cursor16;
+    POINT16         hotspot;
+    HBITMAP         xor_handle;
+    HBITMAP         and_handle;
+    HCURSOR16       cursor16;
 } cursor_object;
 
 typedef struct tagCURSORICONINFO






More information about the wine-patches mailing list