From b63f004eaf5f4af3f995e17cd7270d8046d7782b Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Sat, 8 May 2010 15:31:59 -0600 Subject: user32/winex11: Use ICONINFO for storing icons and cursors. --- dlls/user32/cursoricon.c | 514 ++++++++++++++++++++++---------------------- dlls/user32/driver.c | 4 +- dlls/user32/user_private.h | 4 +- dlls/winex11.drv/mouse.c | 186 +++++++++------- 4 files changed, 364 insertions(+), 344 deletions(-) diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 856d900..bdaf187 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -22,24 +22,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* - * Theory: - * - * Cursors and icons are stored in a global heap block, with the - * following layout: - * - * CURSORICONINFO info; - * BYTE[] ANDbits; - * BYTE[] XORbits; - * - * The bits structures are in the format of a device-dependent bitmap. - * - * This layout is very sub-optimal, as the bitmap bits are stored in - * the X client instead of in the server like other bitmaps; however, - * some programs (notably Paint Brush) expect to be able to manipulate - * the bits directly :-( - */ - #include "config.h" #include "wine/port.h" @@ -135,18 +117,21 @@ struct cursoricon_object { struct user_object obj; /* object header */ ULONG_PTR param; /* opaque param used by 16-bit code */ - /* followed by cursor data in CURSORICONINFO format */ + ICONINFO icon; /* 32-bit cursor or icon */ }; -static HICON alloc_icon_handle( unsigned int size ) +static HICON alloc_icon_handle( ICONINFO iconinfo ) { - struct cursoricon_object *obj = HeapAlloc( GetProcessHeap(), 0, sizeof(*obj) + size ); + int alloc_size = sizeof(struct cursoricon_object); + struct cursoricon_object *obj = HeapAlloc( GetProcessHeap(), 0, alloc_size ); + if (!obj) return 0; obj->param = 0; + obj->icon = iconinfo; return alloc_user_handle( &obj->obj, USER_ICON ); } -static struct tagCURSORICONINFO *get_icon_ptr( HICON handle ) +static ICONINFO *get_icon_ptr( HICON handle ) { struct cursoricon_object *obj = get_user_handle_ptr( handle, USER_ICON ); if (obj == OBJ_OTHER_PROCESS) @@ -154,12 +139,12 @@ static struct tagCURSORICONINFO *get_icon_ptr( HICON handle ) WARN( "icon handle %p from other process\n", handle ); obj = NULL; } - return obj ? (struct tagCURSORICONINFO *)(obj + 1) : NULL; + return obj ? &(obj->icon) : NULL; } -static void release_icon_ptr( HICON handle, struct tagCURSORICONINFO *ptr ) +static void release_icon_ptr( HICON handle, ICONINFO *ptr ) { - release_user_handle_ptr( (struct cursoricon_object *)ptr - 1 ); + release_user_handle_ptr( (char*)ptr + sizeof(ICONINFO) - sizeof(struct cursoricon_object) ); } static BOOL free_icon_handle( HICON handle ) @@ -172,6 +157,8 @@ static BOOL free_icon_handle( HICON handle ) ULONG_PTR param = obj->param; HeapFree( GetProcessHeap(), 0, obj ); if (wow_handlers.free_icon_param && param) wow_handlers.free_icon_param( param ); + DeleteObject( obj->icon.hbmMask ); + DeleteObject( obj->icon.hbmColor ); USER_Driver->pDestroyCursorIcon( handle ); return TRUE; } @@ -512,12 +499,14 @@ static INT CURSORICON_DelSharedIcon( HICON hIcon ) */ BOOL get_icon_size( HICON handle, SIZE *size ) { - CURSORICONINFO *info; + ICONINFO *icon; + BITMAP bmpAnd; - if (!(info = get_icon_ptr( handle ))) return FALSE; - size->cx = info->nWidth; - size->cy = info->nHeight; - release_icon_ptr( handle, info ); + if (!(icon = get_icon_ptr( handle ))) return FALSE; + GetObjectW( icon->hbmMask, sizeof(bmpAnd), &bmpAnd ); + size->cx = bmpAnd.bmWidth; + size->cy = bmpAnd.bmHeight; + release_icon_ptr( handle, icon ); return TRUE; } @@ -748,9 +737,8 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, UINT cFlag ) { HICON hObj; - int sizeAnd, sizeXor; HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */ - BITMAP bmpXor, bmpAnd; + ICONINFO iconinfo; BOOL do_stretch; INT size; BITMAPINFO *pSrcInfo, *pDestInfo; @@ -916,35 +904,19 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, 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 = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd ); - if (hObj) + iconinfo.xHotspot = hotspot.x; + iconinfo.yHotspot = hotspot.y; + iconinfo.hbmMask = hAndBits; + iconinfo.hbmColor = hXorBits; + hObj = alloc_icon_handle( iconinfo ); + if (!hObj) { - CURSORICONINFO *info = get_icon_ptr( 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, info + 1 ); - GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd ); - release_icon_ptr( hObj, info ); - USER_Driver->pCreateCursorIcon( hObj, info ); + DeleteObject( hAndBits ); + DeleteObject( hXorBits ); } + else + USER_Driver->pCreateCursorIcon( hObj, &iconinfo ); - DeleteObject( hAndBits ); - DeleteObject( hXorBits ); return hObj; } @@ -1534,25 +1506,159 @@ HICON WINAPI CreateIcon( } +/********************************************************************** + * CURSORICON_GetXorBits + * + * Retreive the color data for a cursor or icon. + */ +static LONG CURSORICON_GetXorBits( ICONINFO *src, char *dst_bits ) +{ + INT xor_objsize = 0, dib_width, bitmap_width; + DIBSECTION bmpXor; + LONG ret = FALSE; + BITMAPINFO bmi; + + xor_objsize = GetObjectW( src->hbmColor, sizeof(bmpXor), &bmpXor ); + dib_width = get_dib_width_bytes( bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmBitsPixel ); + bitmap_width = get_bitmap_width_bytes( bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmBitsPixel ); + + if (xor_objsize == sizeof(BITMAP)) + return GetBitmapBits(src->hbmColor, bitmap_width * bmpXor.dsBm.bmHeight, dst_bits); + + memset(&bmi, 0, sizeof(BITMAPINFO)); + memcpy(&bmi.bmiHeader, &bmpXor.dsBmih, sizeof(BITMAPINFOHEADER)); + bmi.bmiHeader.biHeight = -bmpXor.dsBm.bmHeight; /* swap lines when creating DIB */ + if (dib_width != bitmap_width) /* need to fixup alignment */ + { + char *src_bits = HeapAlloc( GetProcessHeap(), 0, bmpXor.dsBmih.biSizeImage ); + + if (src_bits && GetDIBits( screen_dc, src->hbmColor, 0, bmpXor.dsBm.bmHeight, + src_bits, &bmi, DIB_RGB_COLORS )) + { + int y; + for (y = 0; y < bmpXor.dsBm.bmHeight; y++) + memcpy( dst_bits + y * bitmap_width, src_bits + y * dib_width, bitmap_width ); + ret = TRUE; + } + HeapFree( GetProcessHeap(), 0, src_bits ); + } + else + ret = GetDIBits( screen_dc, src->hbmColor, 0, bmpXor.dsBm.bmHeight, + dst_bits, &bmi, DIB_RGB_COLORS ); + return ret; +} + + +/********************************************************************** + * CURSORICON_CloneBitmaps + * + * Clone the bitmaps in an ICONINFO structure. Note: this routine is + * only intended to be used for the creation and duplication of icons. + */ +static BOOL CURSORICON_CloneBitmaps( ICONINFO *src, ICONINFO *dst, BOOL convert_flat ) +{ + BOOL ret = FALSE, flat_mask; + INT height, xor_objsize, planes, bpp; + HDC hdc_mem, hdc_mem2; + DIBSECTION bmpXor; + BITMAP bmpAnd; + + hdc_mem = CreateCompatibleDC( NULL ); + hdc_mem2 = CreateCompatibleDC( NULL ); + GetObjectW( src->hbmMask, sizeof(bmpAnd), &bmpAnd ); + xor_objsize = GetObjectW( src->hbmColor, sizeof(bmpXor), &bmpXor ); + + TRACE("mask: width %d, height %d, width bytes %d, planes %u, bpp %u\n", + bmpAnd.bmWidth, bmpAnd.bmHeight, bmpAnd.bmWidthBytes, + bmpAnd.bmPlanes, bmpAnd.bmBitsPixel); + + height = bmpAnd.bmHeight; + planes = GetDeviceCaps( screen_dc, PLANES ); + bpp = GetDeviceCaps( screen_dc, BITSPIXEL ); + flat_mask = convert_flat && bmpXor.dsBm.bmPlanes == 1 && bmpXor.dsBm.bmBitsPixel == 1; + if (!src->hbmColor || (bmpXor.dsBm.bmPlanes == 1 && bmpXor.dsBm.bmBitsPixel == 1)) + planes = bpp = 1; + if (flat_mask) + height *= 2; + + dst->hbmMask = CreateBitmap( bmpAnd.bmWidth, height, 1, 1, NULL); + dst->hbmColor = NULL; + if( dst->hbmMask ) + { + SelectObject( hdc_mem, src->hbmMask ); + SelectObject( hdc_mem2, dst->hbmMask ); + BitBlt(hdc_mem2, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, hdc_mem, 0, 0, SRCCOPY); + if (src->hbmColor) + { + if (convert_flat) + { + /* GetIconInfo() call, flatten alpha channel */ + INT y = 0; + + SelectObject( hdc_mem, src->hbmColor ); + if (flat_mask) + { + /* 1 bit per pixel, append color data to mask */ + y = bmpAnd.bmHeight; + SelectObject( hdc_mem2, dst->hbmMask ); + } + else + { + /* Normal bpp, color data is separate from mask */ + dst->hbmColor = CreateBitmap( bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, + planes, bpp, NULL ); + SelectObject( hdc_mem2, dst->hbmColor ); + } + BitBlt(hdc_mem2, 0, y, bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, + hdc_mem, 0, 0, SRCCOPY); + } + else + { + /* Normal copy: retain all alpha channel information */ + BITMAPINFOHEADER bmih; + char *dst_bits = NULL; + + memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); + bmih.biSize = sizeof(BITMAPINFOHEADER); + bmih.biWidth = bmpXor.dsBm.bmWidth; + bmih.biHeight = -bmpXor.dsBm.bmHeight; + bmih.biPlanes = planes; + bmih.biBitCount = bpp; + bmih.biCompression = BI_RGB; + dst->hbmColor = CreateDIBSection( screen_dc, (BITMAPINFO*) &bmih, DIB_RGB_COLORS, + (void **)&dst_bits, NULL, 0 ); + if (!dst->hbmColor) + FIXME("Failed to create DIB section!\n"); + if (!CURSORICON_GetXorBits( src, dst_bits )) + FIXME("Failed to copy DIB section!\n"); + } + } + ret = TRUE; + } + SelectObject(hdc_mem, 0 ); + SelectObject(hdc_mem2, 0 ); + DeleteDC(hdc_mem); + DeleteDC(hdc_mem2); + return ret; +} + + /*********************************************************************** * CopyIcon (USER32.@) */ HICON WINAPI CopyIcon( HICON hIcon ) { - CURSORICONINFO *ptrOld, *ptrNew; - int size; + ICONINFO *ptrOld; + ICONINFO newIcon; HICON hNew; if (!(ptrOld = get_icon_ptr( hIcon ))) return 0; - size = sizeof(CURSORICONINFO); - size += ptrOld->nHeight * get_bitmap_width_bytes( ptrOld->nWidth, 1 ); /* and bitmap */ - size += ptrOld->nHeight * ptrOld->nWidthBytes; /* xor bitmap */ - hNew = alloc_icon_handle( size ); - ptrNew = get_icon_ptr( hNew ); - memcpy( ptrNew, ptrOld, size ); + memset(&newIcon, 0, sizeof(ICONINFO)); + if (!CURSORICON_CloneBitmaps( ptrOld, &newIcon, FALSE )) + return NULL; + hNew = alloc_icon_handle( newIcon ); release_icon_ptr( hIcon, ptrOld ); - release_icon_ptr( hNew, ptrNew ); - USER_Driver->pCreateCursorIcon( hNew, ptrNew ); + USER_Driver->pCreateCursorIcon( hNew, &newIcon ); return hNew; } @@ -1892,49 +1998,34 @@ HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name) */ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo) { - CURSORICONINFO *ciconinfo; - INT height; - - if (!(ciconinfo = get_icon_ptr( hIcon ))) return FALSE; + BOOL ret = FALSE; + ICONINFO *icon; - TRACE("%p => %dx%d, %d bpp\n", hIcon, - ciconinfo->nWidth, ciconinfo->nHeight, ciconinfo->bBitsPerPixel); + if (!(icon = get_icon_ptr( hIcon ))) return FALSE; - if ( (ciconinfo->ptHotSpot.x == ICON_HOTSPOT) && - (ciconinfo->ptHotSpot.y == ICON_HOTSPOT) ) + *iconinfo = *icon; + if ( (icon->xHotspot == ICON_HOTSPOT) && + (icon->yHotspot == ICON_HOTSPOT) ) { - iconinfo->fIcon = TRUE; - iconinfo->xHotspot = ciconinfo->nWidth / 2; - iconinfo->yHotspot = ciconinfo->nHeight / 2; - } - else - { - iconinfo->fIcon = FALSE; - iconinfo->xHotspot = ciconinfo->ptHotSpot.x; - iconinfo->yHotspot = ciconinfo->ptHotSpot.y; - } - - height = ciconinfo->nHeight; + BITMAP bmpAnd; - if (ciconinfo->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) ); + GetObjectW( icon->hbmMask, sizeof(bmpAnd), &bmpAnd ); + iconinfo->fIcon = TRUE; + iconinfo->xHotspot = bmpAnd.bmWidth / 2; + iconinfo->yHotspot = bmpAnd.bmWidth / 2; /* bmWidth use intentional */ } else { - iconinfo->hbmColor = 0; - height *= 2; + iconinfo->fIcon = FALSE; + iconinfo->xHotspot = icon->xHotspot; + iconinfo->yHotspot = icon->yHotspot; } + if (CURSORICON_CloneBitmaps( icon, iconinfo, TRUE )) + ret = TRUE; - iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, height, - 1, 1, ciconinfo + 1); - release_icon_ptr( hIcon, ciconinfo ); + release_icon_ptr( hIcon, icon ); - return TRUE; + return ret; } /********************************************************************** @@ -1942,10 +2033,8 @@ BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo) */ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo) { - DIBSECTION bmpXor; - BITMAP bmpAnd; - HICON hObj; - int xor_objsize = 0, sizeXor = 0, sizeAnd, planes, bpp; + HICON hObj = NULL; + ICONINFO iinfo; TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n", iconinfo->hbmColor, iconinfo->hbmMask, @@ -1953,140 +2042,35 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo) if (!iconinfo->hbmMask) return 0; - planes = GetDeviceCaps( screen_dc, PLANES ); - bpp = GetDeviceCaps( screen_dc, BITSPIXEL ); - if (iconinfo->hbmColor) { - xor_objsize = GetObjectW( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor ); + DIBSECTION bmpXor; + + GetObjectW( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor ); TRACE("color: width %d, height %d, width bytes %d, planes %u, bpp %u\n", bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, bmpXor.dsBm.bmWidthBytes, bmpXor.dsBm.bmPlanes, bmpXor.dsBm.bmBitsPixel); - /* we can use either depth 1 or screen depth for xor bitmap */ - if (bmpXor.dsBm.bmPlanes == 1 && bmpXor.dsBm.bmBitsPixel == 1) planes = bpp = 1; - sizeXor = bmpXor.dsBm.bmHeight * planes * get_bitmap_width_bytes( bmpXor.dsBm.bmWidth, bpp ); + TRACE("XXX color: width %d, height %d, width bytes %d, planes %u, bpp %u\n", + bmpXor.dsBmih.biWidth, bmpXor.dsBmih.biHeight, bmpXor.dsBmih.biSizeImage, + bmpXor.dsBmih.biPlanes, bmpXor.dsBmih.biBitCount); } - GetObjectW( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd ); - TRACE("mask: width %d, height %d, width bytes %d, planes %u, bpp %u\n", - bmpAnd.bmWidth, bmpAnd.bmHeight, bmpAnd.bmWidthBytes, - bmpAnd.bmPlanes, bmpAnd.bmBitsPixel); - - sizeAnd = bmpAnd.bmHeight * get_bitmap_width_bytes(bmpAnd.bmWidth, 1); - hObj = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd ); - if (hObj) + iinfo = *iconinfo; + /* If we are creating an icon, the hotspot is unused */ + if (iinfo.fIcon) { - CURSORICONINFO *info = get_icon_ptr( 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.dsBm.bmWidth; - info->nHeight = bmpXor.dsBm.bmHeight; - info->nWidthBytes = bmpXor.dsBm.bmWidthBytes; - info->bPlanes = planes; - info->bBitsPerPixel = bpp; - } - else - { - info->nWidth = bmpAnd.bmWidth; - info->nHeight = bmpAnd.bmHeight / 2; - info->nWidthBytes = get_bitmap_width_bytes(bmpAnd.bmWidth, 1); - info->bPlanes = 1; - info->bBitsPerPixel = 1; - } - - /* Transfer the bitmap bits to the CURSORICONINFO structure */ - - /* Some apps pass a color bitmap as a mask, convert it to b/w */ - if (bmpAnd.bmBitsPixel == 1) - { - GetBitmapBits( iconinfo->hbmMask, sizeAnd, info + 1 ); - } - else - { - HDC hdc_mem, hdc_mem2; - HBITMAP hbmp_mem_old, hbmp_mem2_old, hbmp_mono; - - hdc_mem = CreateCompatibleDC( 0 ); - hdc_mem2 = CreateCompatibleDC( 0 ); - - hbmp_mono = CreateBitmap( bmpAnd.bmWidth, bmpAnd.bmHeight, 1, 1, NULL ); - - hbmp_mem_old = SelectObject( hdc_mem, iconinfo->hbmMask ); - hbmp_mem2_old = SelectObject( hdc_mem2, hbmp_mono ); - - BitBlt( hdc_mem2, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, hdc_mem, 0, 0, SRCCOPY ); - - SelectObject( hdc_mem, hbmp_mem_old ); - SelectObject( hdc_mem2, hbmp_mem2_old ); - - DeleteDC( hdc_mem ); - DeleteDC( hdc_mem2 ); - - GetBitmapBits( hbmp_mono, sizeAnd, info + 1 ); - DeleteObject( hbmp_mono ); - } - - if (iconinfo->hbmColor) - { - char *dst_bits = (char*)(info + 1) + sizeAnd; - - if (bmpXor.dsBm.bmPlanes == planes && bmpXor.dsBm.bmBitsPixel == bpp) - GetBitmapBits( iconinfo->hbmColor, sizeXor, dst_bits ); - else - { - BITMAPINFO bminfo; - int dib_width = get_dib_width_bytes( info->nWidth, info->bBitsPerPixel ); - int bitmap_width = get_bitmap_width_bytes( info->nWidth, info->bBitsPerPixel ); - - bminfo.bmiHeader.biSize = sizeof(bminfo); - bminfo.bmiHeader.biWidth = info->nWidth; - bminfo.bmiHeader.biHeight = info->nHeight; - bminfo.bmiHeader.biPlanes = info->bPlanes; - bminfo.bmiHeader.biBitCount = info->bBitsPerPixel; - bminfo.bmiHeader.biCompression = BI_RGB; - bminfo.bmiHeader.biSizeImage = info->nHeight * dib_width; - bminfo.bmiHeader.biXPelsPerMeter = 0; - bminfo.bmiHeader.biYPelsPerMeter = 0; - bminfo.bmiHeader.biClrUsed = 0; - bminfo.bmiHeader.biClrImportant = 0; - - /* swap lines for dib sections */ - if (xor_objsize == sizeof(DIBSECTION)) - bminfo.bmiHeader.biHeight = -bminfo.bmiHeader.biHeight; - - if (dib_width != bitmap_width) /* need to fixup alignment */ - { - char *src_bits = HeapAlloc( GetProcessHeap(), 0, bminfo.bmiHeader.biSizeImage ); - - if (src_bits && GetDIBits( screen_dc, iconinfo->hbmColor, 0, info->nHeight, - src_bits, &bminfo, DIB_RGB_COLORS )) - { - int y; - for (y = 0; y < info->nHeight; y++) - memcpy( dst_bits + y * bitmap_width, src_bits + y * dib_width, bitmap_width ); - } - HeapFree( GetProcessHeap(), 0, src_bits ); - } - else - GetDIBits( screen_dc, iconinfo->hbmColor, 0, info->nHeight, - dst_bits, &bminfo, DIB_RGB_COLORS ); - } - } - release_icon_ptr( hObj, info ); - USER_Driver->pCreateCursorIcon( hObj, info ); + iinfo.xHotspot = ICON_HOTSPOT; + iinfo.yHotspot = ICON_HOTSPOT; + } + else + { + iinfo.xHotspot = iconinfo->xHotspot; + iinfo.yHotspot = iconinfo->yHotspot; + } + if (CURSORICON_CloneBitmaps( iconinfo, &iinfo, FALSE )) + { + hObj = alloc_icon_handle( iinfo ); + USER_Driver->pCreateCursorIcon( hObj, &iinfo ); } return hObj; } @@ -2116,21 +2100,23 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, INT cxWidth, INT cyWidth, UINT istep, HBRUSH hbr, UINT flags ) { - CURSORICONINFO *ptr; + ICONINFO *icon; HDC hDC_off = 0, hMemDC; BOOL result = FALSE, DoOffscreen; HBITMAP hB_off = 0, hOld = 0; - unsigned char *xorBitmapBits; - unsigned int xorLength; + BITMAP bmpAnd; + DIBSECTION bmpXor; + unsigned char *xorBitmapBits, *andBitmapBits; + unsigned int andLength, dibLength; BOOL has_alpha = FALSE; 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 ); - if (!(ptr = get_icon_ptr( hIcon ))) return FALSE; + if (!(icon = get_icon_ptr( hIcon ))) return FALSE; if (!(hMemDC = CreateCompatibleDC( hdc ))) { - release_icon_ptr( hIcon, ptr ); + release_icon_ptr( hIcon, icon ); return FALSE; } @@ -2139,14 +2125,22 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, if (flags & DI_NOMIRROR) FIXME_(icon)("Ignoring flag DI_NOMIRROR\n"); - xorLength = ptr->nHeight * get_bitmap_width_bytes( - ptr->nWidth, ptr->bBitsPerPixel); - xorBitmapBits = (unsigned char *)(ptr + 1) + ptr->nHeight * - get_bitmap_width_bytes(ptr->nWidth, 1); + GetObjectW( icon->hbmMask, sizeof(bmpAnd), &bmpAnd ); + GetObjectW( icon->hbmColor, sizeof(bmpXor), &bmpXor ); + + andLength = bmpAnd.bmHeight * get_bitmap_width_bytes( + bmpAnd.bmWidth, bmpAnd.bmBitsPixel); + dibLength = bmpXor.dsBm.bmHeight * get_bitmap_width_bytes( + bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmBitsPixel); + + andBitmapBits = (unsigned char *) HeapAlloc(GetProcessHeap(), 0, andLength); + xorBitmapBits = (unsigned char *) HeapAlloc(GetProcessHeap(), 0, dibLength); + GetBitmapBits( icon->hbmMask, andLength, andBitmapBits ); + CURSORICON_GetXorBits( icon, (char *)xorBitmapBits ); if (flags & DI_IMAGE) has_alpha = bitmap_has_alpha_channel( - ptr->bBitsPerPixel, xorBitmapBits, xorLength); + bmpXor.dsBm.bmBitsPixel, xorBitmapBits, dibLength); /* Calculate the size of the destination image. */ if (cxWidth == 0) @@ -2154,14 +2148,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 = bmpAnd.bmWidth; } if (cyWidth == 0) { if (flags & DI_DEFAULTSIZE) cyWidth = GetSystemMetrics (SM_CYICON); else - cyWidth = ptr->nHeight; + cyWidth = bmpAnd.bmHeight; } DoOffscreen = (GetObjectType( hbr ) == OBJ_BRUSH); @@ -2196,25 +2190,25 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, if ((flags & DI_MASK) && !has_alpha) { - hAndBits = CreateBitmap ( ptr->nWidth, ptr->nHeight, 1, 1, ptr + 1 ); + hAndBits = CreateBitmap ( bmpAnd.bmWidth, bmpAnd.bmHeight, 1, 1, andBitmapBits ); if (hAndBits) { hBitTemp = SelectObject( hMemDC, hAndBits ); if (DoOffscreen) StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth, - hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND); + hMemDC, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, SRCAND); else StretchBlt (hdc, x0, y0, cxWidth, cyWidth, - hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND); + hMemDC, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, SRCAND); SelectObject( hMemDC, hBitTemp ); } } if (flags & DI_IMAGE) { - if (ptr->bPlanes * ptr->bBitsPerPixel == 1) + if (bmpXor.dsBm.bmPlanes * bmpXor.dsBm.bmBitsPixel == 1) { - hXorBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, xorBitmapBits ); + hXorBits = CreateBitmap( bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, 1, 1, xorBitmapBits ); } else { @@ -2222,10 +2216,10 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, BITMAPINFO *bmi = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi->bmiHeader.biWidth = ptr->nWidth; - bmi->bmiHeader.biHeight = -ptr->nHeight; - bmi->bmiHeader.biPlanes = ptr->bPlanes; - bmi->bmiHeader.biBitCount = ptr->bBitsPerPixel; + bmi->bmiHeader.biWidth = bmpXor.dsBm.bmWidth; + bmi->bmiHeader.biHeight = -bmpXor.dsBm.bmHeight; + bmi->bmiHeader.biPlanes = bmpXor.dsBm.bmPlanes; + bmi->bmiHeader.biBitCount = bmpXor.dsBm.bmBitsPixel; bmi->bmiHeader.biCompression = BI_RGB; /* FIXME: color table */ @@ -2233,9 +2227,9 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, if (hXorBits) { if(has_alpha) - premultiply_alpha_channel(dibBits, xorBitmapBits, xorLength); + premultiply_alpha_channel(dibBits, xorBitmapBits, dibLength); else - memcpy(dibBits, xorBitmapBits, xorLength); + memcpy(dibBits, xorBitmapBits, dibLength); } } @@ -2250,10 +2244,10 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, if (DoOffscreen) GdiAlphaBlend(hDC_off, 0, 0, cxWidth, cyWidth, hMemDC, - 0, 0, ptr->nWidth, ptr->nHeight, pixelblend); + 0, 0, bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, pixelblend); else GdiAlphaBlend(hdc, x0, y0, cxWidth, cyWidth, hMemDC, - 0, 0, ptr->nWidth, ptr->nHeight, pixelblend); + 0, 0, bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, pixelblend); SelectObject( hMemDC, hBitTemp ); } @@ -2263,10 +2257,10 @@ BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, hBitTemp = SelectObject( hMemDC, hXorBits ); if (DoOffscreen) StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth, - hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, rop); + hMemDC, 0, 0, bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, rop); else StretchBlt (hdc, x0, y0, cxWidth, cyWidth, - hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, rop); + hMemDC, 0, 0, bmpXor.dsBm.bmWidth, bmpXor.dsBm.bmHeight, rop); SelectObject( hMemDC, hBitTemp ); } @@ -2289,7 +2283,9 @@ 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); - release_icon_ptr( hIcon, ptr ); + HeapFree(GetProcessHeap(), 0, andBitmapBits); + HeapFree(GetProcessHeap(), 0, xorBitmapBits); + release_icon_ptr( hIcon, icon ); return result; } diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index dc17264..aa6f032 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -217,7 +217,7 @@ static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout ) return -1; } -static void CDECL nulldrv_CreateCursorIcon( HCURSOR cursor, struct tagCURSORICONINFO *info ) +static void CDECL nulldrv_CreateCursorIcon( HCURSOR cursor, struct _ICONINFO *info ) { } @@ -570,7 +570,7 @@ static SHORT CDECL loaderdrv_VkKeyScanEx( WCHAR ch, HKL layout ) return load_driver()->pVkKeyScanEx( ch, layout ); } -static void CDECL loaderdrv_CreateCursorIcon( HCURSOR cursor, struct tagCURSORICONINFO *info ) +static void CDECL loaderdrv_CreateCursorIcon( HCURSOR cursor, struct _ICONINFO *info ) { load_driver()->pCreateCursorIcon( cursor, info ); } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 43daafd..3ef7435 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -51,7 +51,7 @@ enum wine_internal_message WM_WINE_LAST_DRIVER_MSG = 0x80001fff }; -struct tagCURSORICONINFO; +struct _ICONINFO; typedef struct tagUSER_DRIVER { /* keyboard functions */ @@ -68,7 +68,7 @@ typedef struct tagUSER_DRIVER { BOOL (CDECL *pUnloadKeyboardLayout)(HKL); SHORT (CDECL *pVkKeyScanEx)(WCHAR, HKL); /* cursor/icon functions */ - void (CDECL *pCreateCursorIcon)(HCURSOR,struct tagCURSORICONINFO *); + void (CDECL *pCreateCursorIcon)(HCURSOR,struct _ICONINFO *); void (CDECL *pDestroyCursorIcon)(HCURSOR); void (CDECL *pSetCursor)(HCURSOR); BOOL (CDECL *pGetCursorPos)(LPPOINT); diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 5a1a09f..e534abb 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -39,7 +39,7 @@ MAKE_FUNCPTR(XcursorImageLoadCursor); #define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" -#include "wine/winuser16.h" +#include "winuser.h" #include "x11drv.h" #include "wine/server.h" @@ -483,17 +483,17 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y, * * Non-32 bit bitmaps always use the AND mask. */ -static BOOL check_alpha_zero(CURSORICONINFO *ptr, unsigned char *xor_bits) +static BOOL check_alpha_zero(BITMAP bmpXor, unsigned char *xor_bits) { int x, y; unsigned char *xor_ptr; - if (ptr->bBitsPerPixel == 32) + if (bmpXor.bmBitsPixel == 32) { - for (y = 0; y < ptr->nHeight; ++y) + for (y = 0; y < bmpXor.bmHeight; ++y) { - xor_ptr = xor_bits + (y * ptr->nWidthBytes); - for (x = 0; x < ptr->nWidth; ++x) + xor_ptr = xor_bits + (y * bmpXor.bmWidthBytes); + for (x = 0; x < bmpXor.bmWidth; ++x) { if (xor_ptr[3] != 0x00) { @@ -513,9 +513,9 @@ static BOOL check_alpha_zero(CURSORICONINFO *ptr, unsigned char *xor_bits) /*********************************************************************** * create_cursor_image * - * Create an XcursorImage from a CURSORICONINFO + * Create an XcursorImage from an ICONINFO */ -static XcursorImage *create_cursor_image( CURSORICONINFO *ptr ) +static XcursorImage *create_cursor_image( ICONINFO *icon ) { static const unsigned char convert_5to8[] = { @@ -537,28 +537,35 @@ static XcursorImage *create_cursor_image( CURSORICONINFO *ptr ) }; int x; int y; - int and_size; - unsigned char *and_bits, *and_ptr, *xor_bits, *xor_ptr; + int and_size, xor_size; + unsigned char *and_bits, *xor_bits, *and_ptr, *xor_ptr; int and_width_bytes, xor_width_bytes; XcursorPixel *pixel_ptr; + BITMAP bmpAnd, bmpXor; XcursorImage *image; unsigned char tmp; BOOL alpha_zero; - and_width_bytes = 2 * ((ptr->nWidth+15) / 16); - xor_width_bytes = ptr->nWidthBytes; + GetObjectW( icon->hbmMask, sizeof(bmpAnd), &bmpAnd ); + GetObjectW( icon->hbmColor, sizeof(bmpXor), &bmpXor ); - and_size = ptr->nHeight * and_width_bytes; - and_ptr = and_bits = (unsigned char *)(ptr + 1); + and_width_bytes = 2 * ((bmpAnd.bmWidth+15) / 16); + xor_width_bytes = bmpXor.bmWidthBytes; - xor_ptr = xor_bits = and_ptr + and_size; + and_size = bmpAnd.bmHeight * and_width_bytes; + xor_size = bmpXor.bmHeight * xor_width_bytes; - image = pXcursorImageCreate( ptr->nWidth, ptr->nHeight ); - if (!image) return NULL; + and_ptr = and_bits = (unsigned char *) HeapAlloc(GetProcessHeap(), 0, and_size); + xor_ptr = xor_bits = (unsigned char *) HeapAlloc(GetProcessHeap(), 0, xor_size); + GetBitmapBits( icon->hbmMask, and_size, and_ptr ); + GetBitmapBits( icon->hbmColor, xor_size, xor_ptr ); + + image = pXcursorImageCreate( bmpAnd.bmWidth, bmpAnd.bmHeight ); + if (!image) goto cleanup; pixel_ptr = image->pixels; - alpha_zero = check_alpha_zero(ptr, xor_bits); + alpha_zero = check_alpha_zero(bmpXor, xor_bits); /* On windows, to calculate the color for a pixel, first an AND is done * with the background and the "and" bitmap, then an XOR with the "xor" @@ -574,15 +581,15 @@ static XcursorImage *create_cursor_image( CURSORICONINFO *ptr ) * the "xor" data to the alpha channel, and xor the color with either * black or white. */ - for (y = 0; y < ptr->nHeight; ++y) + for (y = 0; y < bmpAnd.bmHeight; ++y) { and_ptr = and_bits + (y * and_width_bytes); xor_ptr = xor_bits + (y * xor_width_bytes); - for (x = 0; x < ptr->nWidth; ++x) + for (x = 0; x < bmpAnd.bmWidth; ++x) { /* Xcursor pixel data is in ARGB format, with A in the high byte */ - switch (ptr->bBitsPerPixel) + switch (bmpXor.bmBitsPixel) { case 32: /* BGRA, 8 bits each */ @@ -616,8 +623,8 @@ static XcursorImage *create_cursor_image( CURSORICONINFO *ptr ) break; default: - FIXME("Currently no support for cursors with %d bits per pixel\n", ptr->bBitsPerPixel); - return 0; + FIXME("Currently no support for cursors with %d bits per pixel\n", bmpXor.bmBitsPixel); + goto cleanup; } if (alpha_zero) @@ -638,6 +645,9 @@ static XcursorImage *create_cursor_image( CURSORICONINFO *ptr ) } } +cleanup: + HeapFree(GetProcessHeap(), 0, and_bits); + HeapFree(GetProcessHeap(), 0, xor_bits); return image; } @@ -647,17 +657,17 @@ 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, ICONINFO *icon ) { Cursor cursor; XcursorImage *image; - image = create_cursor_image( ptr ); + image = create_cursor_image( icon ); if (!image) return 0; /* Make sure hotspot is valid */ - image->xhot = ptr->ptHotSpot.x; - image->yhot = ptr->ptHotSpot.y; + image->xhot = icon->xHotspot; + image->yhot = icon->yHotspot; if (image->xhot >= image->width || image->yhot >= image->height) { @@ -681,8 +691,9 @@ 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, ICONINFO *icon ) { + char *and_bits = NULL, *xor_bits = NULL; Pixmap pixmapBits, pixmapMask, pixmapMaskInv = 0, pixmapAll; XColor fg, bg; Cursor cursor = None; @@ -690,20 +701,33 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) char *bitMask32 = NULL; BOOL alpha_zero = TRUE; - if (!ptr) return get_empty_cursor(); + if (!icon) return get_empty_cursor(); #ifdef SONAME_LIBXCURSOR - if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr ); + if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, icon ); #endif /* Create the X cursor from the bits */ { + unsigned int dibLength, xorLength; + BITMAP bmpAnd, bmpXor; XImage *image; GC gc; + GetObjectW( icon->hbmMask, sizeof(bmpAnd), &bmpAnd ); + GetObjectW( icon->hbmColor, sizeof(bmpXor), &bmpXor ); + TRACE("Bitmap %dx%d planes=%d bpp=%d bytesperline=%d\n", - ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel, - ptr->nWidthBytes); + bmpAnd.bmWidth, bmpAnd.bmHeight, bmpXor.bmPlanes, bmpXor.bmBitsPixel, + bmpXor.bmWidthBytes); + + dibLength = bmpAnd.bmHeight * bmpAnd.bmWidthBytes; + xorLength = bmpXor.bmHeight * bmpXor.bmWidthBytes; + + and_bits = (char *) HeapAlloc(GetProcessHeap(), 0, dibLength); + xor_bits = (char *) HeapAlloc(GetProcessHeap(), 0, xorLength); + GetBitmapBits( icon->hbmMask, dibLength, and_bits ); + GetBitmapBits( icon->hbmColor, xorLength, xor_bits ); /* Create a pixmap and transfer all the bits to it */ @@ -716,14 +740,14 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) * the mask and the second is the image. */ if (!(pixmapAll = XCreatePixmap( display, root_window, - ptr->nWidth, ptr->nHeight * 2, 1 ))) - return 0; + bmpAnd.bmWidth, bmpAnd.bmHeight * 2, 1 ))) + goto cleanup; if (!(image = XCreateImage( display, visual, - 1, ZPixmap, 0, (char *)(ptr + 1), ptr->nWidth, - ptr->nHeight * 2, 16, ptr->nWidthBytes/ptr->bBitsPerPixel))) + 1, ZPixmap, 0, and_bits, bmpAnd.bmWidth, + bmpAnd.bmHeight * 2, 16, bmpAnd.bmWidthBytes/bmpAnd.bmBitsPixel))) { XFreePixmap( display, pixmapAll ); - return 0; + goto cleanup; } gc = XCreateGC( display, pixmapAll, 0, NULL ); XSetGraphicsExposures( display, gc, False ); @@ -731,13 +755,13 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) image->bitmap_bit_order = MSBFirst; image->bitmap_unit = 16; _XInitImageFuncPtrs(image); - if (ptr->bPlanes * ptr->bBitsPerPixel == 1) + if (bmpXor.bmPlanes * bmpXor.bmBitsPixel == 1) { /* A plain old white on black cursor. */ fg.red = fg.green = fg.blue = 0xffff; bg.red = bg.green = bg.blue = 0x0000; XPutImage( display, pixmapAll, gc, image, - 0, 0, 0, 0, ptr->nWidth, ptr->nHeight * 2 ); + 0, 0, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight * 2 ); } else { @@ -749,11 +773,11 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) int threshold, fgBits, bgBits, bitShifted; BYTE pXorBits[128]; /* Up to 32x32 icons */ - switch (ptr->bBitsPerPixel) + switch (bmpXor.bmBitsPixel) { case 32: bitMask32 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - ptr->nWidth * ptr->nHeight / 8 ); + bmpXor.bmWidth * bmpXor.bmHeight / 8 ); /* Fallthrough */ case 24: rbits = 8; @@ -769,31 +793,29 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) break; default: FIXME("Currently no support for cursors with %d bits per pixel\n", - ptr->bBitsPerPixel); + bmpXor.bmBitsPixel); XFreePixmap( display, pixmapAll ); XFreeGC( display, gc ); image->data = NULL; XDestroyImage( image ); - return 0; + goto cleanup; } /* The location of the mask. */ - theMask = (unsigned char *)(ptr + 1); - /* The mask should still be 1 bit per pixel. The color image - * should immediately follow the mask. - */ - theImage = &theMask[ptr->nWidth/8 * ptr->nHeight]; + theMask = (unsigned char *) and_bits; + /* The mask should still be 1 bit per pixel. */ + theImage = (unsigned char *) xor_bits; rfg = gfg = bfg = rbg = gbg = bbg = 0; byteIndex = 0; xorIndex = 0; fgBits = 0; bitShifted = 0x01; - xmax = (ptr->nWidth > 32) ? 32 : ptr->nWidth; - if (ptr->nWidth > 32) { + xmax = (bmpAnd.bmWidth > 32) ? 32 : bmpAnd.bmWidth; + if (bmpAnd.bmWidth > 32) { ERR("Got a %dx%d cursor. Cannot handle larger than 32x32.\n", - ptr->nWidth, ptr->nHeight); + bmpAnd.bmWidth, bmpAnd.bmHeight); } - ymax = (ptr->nHeight > 32) ? 32 : ptr->nHeight; - alpha_zero = check_alpha_zero(ptr, theImage); + ymax = (bmpAnd.bmHeight > 32) ? 32 : bmpAnd.bmHeight; + alpha_zero = check_alpha_zero(bmpXor, theImage); memset(pXorBits, 0, 128); for (y=0; ybBitsPerPixel) + switch (bmpXor.bmBitsPixel) { case 32: theChar = theImage[byteIndex++]; @@ -884,16 +906,16 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) XFreeGC( display, gc ); image->data = NULL; XDestroyImage( image ); - return 0; + goto cleanup; } /* Put the mask. */ XPutImage( display, pixmapAll, gc, image, - 0, 0, 0, 0, ptr->nWidth, ptr->nHeight ); + 0, 0, 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight ); XSetFunction( display, gc, GXcopy ); /* Put the image */ XCopyArea( display, pixmapBits, pixmapAll, gc, - 0, 0, xmax, ymax, 0, ptr->nHeight ); + 0, 0, xmax, ymax, 0, bmpAnd.bmHeight ); XFreePixmap( display, pixmapBits ); } image->data = NULL; @@ -901,11 +923,11 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) /* Now create the 2 pixmaps for bits and mask */ - pixmapBits = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); + pixmapBits = XCreatePixmap( display, root_window, bmpAnd.bmWidth, bmpAnd.bmHeight, 1 ); if (alpha_zero) { - pixmapMaskInv = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); - pixmapMask = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); + pixmapMaskInv = XCreatePixmap( display, root_window, bmpAnd.bmWidth, bmpAnd.bmHeight, 1 ); + pixmapMask = XCreatePixmap( display, root_window, bmpAnd.bmWidth, bmpAnd.bmHeight, 1 ); /* Make sure everything went OK so far */ if (pixmapBits && pixmapMask && pixmapMaskInv) @@ -934,44 +956,44 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) */ XSetFunction( display, gc, GXcopy ); XCopyArea( display, pixmapAll, pixmapBits, gc, - 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); XCopyArea( display, pixmapAll, pixmapMask, gc, - 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); XCopyArea( display, pixmapAll, pixmapMaskInv, gc, - 0, 0, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); XSetFunction( display, gc, GXand ); XCopyArea( display, pixmapAll, pixmapMaskInv, gc, - 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, bmpAnd.bmHeight, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); XSetFunction( display, gc, GXandReverse ); XCopyArea( display, pixmapAll, pixmapBits, gc, - 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, bmpAnd.bmHeight, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); XSetFunction( display, gc, GXorReverse ); XCopyArea( display, pixmapAll, pixmapMask, gc, - 0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 ); + 0, bmpAnd.bmHeight, bmpAnd.bmWidth, bmpAnd.bmHeight, 0, 0 ); /* Additional white */ XSetFunction( display, gc, GXor ); XCopyArea( display, pixmapMaskInv, pixmapMask, gc, - 0, 0, ptr->nWidth, ptr->nHeight, 1, 1 ); + 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, 1, 1 ); XCopyArea( display, pixmapMaskInv, pixmapBits, gc, - 0, 0, ptr->nWidth, ptr->nHeight, 1, 1 ); + 0, 0, bmpAnd.bmWidth, bmpAnd.bmHeight, 1, 1 ); XSetFunction( display, gc, GXcopy ); } } else { pixmapMask = XCreateBitmapFromData( display, root_window, - bitMask32, ptr->nWidth, - ptr->nHeight ); + bitMask32, bmpAnd.bmWidth, + bmpAnd.bmHeight ); } /* Make sure hotspot is valid */ - hotspot.x = ptr->ptHotSpot.x; - hotspot.y = ptr->ptHotSpot.y; - if (hotspot.x < 0 || hotspot.x >= ptr->nWidth || - hotspot.y < 0 || hotspot.y >= ptr->nHeight) + hotspot.x = icon->xHotspot; + hotspot.y = icon->yHotspot; + if (hotspot.x < 0 || hotspot.x >= bmpAnd.bmWidth || + hotspot.y < 0 || hotspot.y >= bmpAnd.bmHeight) { - hotspot.x = ptr->nWidth / 2; - hotspot.y = ptr->nHeight / 2; + hotspot.x = bmpAnd.bmWidth / 2; + hotspot.y = bmpAnd.bmHeight / 2; } if (pixmapBits && pixmapMask) @@ -987,28 +1009,30 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) HeapFree( GetProcessHeap(), 0, bitMask32 ); XFreeGC( display, gc ); } +cleanup: + HeapFree(GetProcessHeap(), 0, and_bits); + HeapFree(GetProcessHeap(), 0, xor_bits); return cursor; } /*********************************************************************** * CreateCursorIcon (X11DRV.@) */ -void CDECL X11DRV_CreateCursorIcon( HCURSOR handle, CURSORICONINFO *info ) +void CDECL X11DRV_CreateCursorIcon( HCURSOR handle, ICONINFO *icon ) { static const WORD ICON_HOTSPOT = 0x4242; Cursor cursor; /* ignore icons (FIXME: shouldn't use magic hotspot value) */ - if (info->ptHotSpot.x == ICON_HOTSPOT && info->ptHotSpot.y == ICON_HOTSPOT) return; + if (icon->xHotspot == ICON_HOTSPOT && icon->yHotspot == ICON_HOTSPOT) return; wine_tsx11_lock(); - cursor = create_cursor( gdi_display, info ); + cursor = create_cursor( gdi_display, icon ); if (cursor) { if (!cursor_context) cursor_context = XUniqueContext(); XSaveContext( gdi_display, (XID)handle, cursor_context, (char *)cursor ); - TRACE( "cursor %p %ux%u, planes %u, bpp %u -> xid %lx\n", - handle, info->nWidth, info->nHeight, info->bPlanes, info->bBitsPerPixel, cursor ); + TRACE( "cursor %p -> xid %lx\n", handle, cursor ); } wine_tsx11_unlock(); } -- 1.7.0.4