Author: jgardou Date: Thu Nov 8 12:51:24 2012 New Revision: 57692
URL: http://svn.reactos.org/svn/reactos?rev=57692&view=rev Log: [WIN32SS/USER] - Start using CURSORDATA structure for passing data from user to kernel mode. - Start using the proper CURSOR structure for win32k internal represesentation of cursor and icons - Create the alpha bitmap in user mode instead of kernel mode.
Modified: trunk/reactos/win32ss/include/ntuser.h trunk/reactos/win32ss/user/ntuser/cursoricon.h trunk/reactos/win32ss/user/ntuser/cursoricon_new.c trunk/reactos/win32ss/user/ntuser/msgqueue.c trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c trunk/reactos/win32ss/w32ksvc.h
Modified: trunk/reactos/win32ss/include/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?re... ============================================================================== --- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -975,6 +975,43 @@ BOOL fGlobalHandle; BOOL fIncSerialNumber; } SETCLIPBDATA, *PSETCLIPBDATA; + +// Used with NtUserSetCursorIconData, last parameter. +typedef struct tagCURSORDATA +{ + LPWSTR lpName; + LPWSTR lpModName; + USHORT rt; + USHORT dummy; + ULONG CURSORF_flags; + SHORT xHotspot; + SHORT yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; + HBITMAP hbmAlpha; + RECT rcBounds; + HBITMAP hbmUserAlpha; // Could be in W7U, not in W2k + ULONG bpp; + ULONG cx; + ULONG cy; + INT cpcur; + INT cicur; + struct tagCURSORDATA * aspcur; + DWORD * aicur; + INT * ajifRate; + INT iicur; +} CURSORDATA, *PCURSORDATA; /* !dso CURSORDATA */ + +// CURSORF_flags: +#define CURSORF_FROMRESOURCE 0x0001 +#define CURSORF_GLOBAL 0x0002 +#define CURSORF_LRSHARED 0x0004 +#define CURSORF_ACON 0x0008 +#define CURSORF_WOWCLEANUP 0x0010 +#define CURSORF_ACONFRAME 0x0040 +#define CURSORF_SECRET 0x0080 +#define CURSORF_LINKED 0x0100 +#define CURSORF_CURRENT 0x0200
DWORD NTAPI @@ -2737,15 +2774,21 @@ _In_ HCURSOR hCursor, _In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING puSrcName, - _In_ PICONINFO pii); + _In_ PCURSORDATA pCursorData); + +typedef struct _tagFINDEXISTINGCURICONPARAM +{ + BOOL bIcon; + LONG cx; + LONG cy; +} FINDEXISTINGCURICONPARAM;
HICON NTAPI NtUserFindExistingCursorIcon( _In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, - _In_ LONG cxDesired, - _In_ LONG cyDesired); + _In_ FINDEXISTINGCURICONPARAM* param); #else BOOL NTAPI
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -9,26 +9,29 @@ } CURICON_PROCESS, *PCURICON_PROCESS;
#ifdef NEW_CURSORICON -typedef struct _CURICON_FRAME -{ - HBITMAP hbmMask; - HBITMAP hbmColor; - HBITMAP hbmAlpha; -} CURICON_FRAME, *PCURICON_FRAME; - typedef struct _CURICON_OBJECT { - PROCMARKHEAD head; + PROCMARKHEAD head; + struct _tagCURSOR* pcurNext; + UNICODE_STRING strName; + USHORT atomModName; + USHORT rt; + ULONG CURSORF_flags; + SHORT xHotspot; + SHORT yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; + HBITMAP hbmAlpha; + RECT rcBounds; + HBITMAP hbmUserAlpha; + ULONG bpp; + ULONG cx; + ULONG cy; +/* ReactOS specific, to be deleted */ LIST_ENTRY ListEntry; HANDLE Self; LIST_ENTRY ProcessList; UNICODE_STRING ustrModule; - UNICODE_STRING ustrRsrc; - SIZE Size; - BYTE Shadow; - BOOL bIcon; - POINTL ptlHotspot; - CURICON_FRAME aFrame[1]; } CURICON_OBJECT, *PCURICON_OBJECT;
#else
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -27,8 +27,8 @@ #include <win32k.h> DBG_DEFAULT_CHANNEL(UserIcon);
-static PPAGED_LOOKASIDE_LIST pgProcessLookasideList; static LIST_ENTRY gCurIconList; +static PAGED_LOOKASIDE_LIST *pgProcessLookasideList;
SYSTEM_CURSORINFO gSysCursorInfo;
@@ -48,14 +48,14 @@ 128); InitializeListHead(&gCurIconList);
- gSysCursorInfo.Enabled = FALSE; - gSysCursorInfo.ButtonsDown = 0; - gSysCursorInfo.bClipped = FALSE; - gSysCursorInfo.LastBtnDown = 0; - gSysCursorInfo.CurrentCursorObject = NULL; - gSysCursorInfo.ShowingCursor = -1; - gSysCursorInfo.ClickLockActive = FALSE; - gSysCursorInfo.ClickLockTime = 0; + gSysCursorInfo.Enabled = FALSE; + gSysCursorInfo.ButtonsDown = 0; + gSysCursorInfo.bClipped = FALSE; + gSysCursorInfo.LastBtnDown = 0; + gSysCursorInfo.CurrentCursorObject = NULL; + gSysCursorInfo.ShowingCursor = -1; + gSysCursorInfo.ClickLockActive = FALSE; + gSysCursorInfo.ClickLockTime = 0;
return TRUE; } @@ -64,6 +64,13 @@ IntGetSysCursorInfo() { return &gSysCursorInfo; +} + +FORCEINLINE +BOOL +is_icon(PCURICON_OBJECT object) +{ + return MAKEINTRESOURCE(object->rt) == RT_ICON; }
/* This function creates a reference for the object! */ @@ -182,23 +189,23 @@ LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry) { /* See if we are looking for an icon or a cursor */ - if(CurIcon->bIcon != param->bIcon) + if(MAKEINTRESOURCE(CurIcon->rt) != (param->bIcon ? RT_ICON : RT_CURSOR)) continue; /* See if module names match */ if(RtlCompareUnicodeString(pustrModule, &CurIcon->ustrModule, TRUE) == 0) { /* They do. Now see if this is the same resource */ - if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer)) + if(IS_INTRESOURCE(CurIcon->strName.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer)) { - if(CurIcon->ustrRsrc.Buffer != pustrRsrc->Buffer) + if(CurIcon->strName.Buffer != pustrRsrc->Buffer) continue; } - else if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer)) + else if(IS_INTRESOURCE(CurIcon->strName.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer)) continue; - else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->ustrRsrc, TRUE) != 0) + else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->strName, TRUE) != 0) continue;
- if ((param->cx == CurIcon->Size.cx) &&(param->cy == CurIcon->Size.cy)) + if ((param->cx == CurIcon->cx) && (param->cy == CurIcon->cy)) { if (! ReferenceCurIconByProcess(CurIcon)) { @@ -217,13 +224,12 @@ IntCreateCurIconHandle(DWORD dwNumber) { PCURICON_OBJECT CurIcon; - BOOLEAN bIcon = dwNumber == 0; HANDLE hCurIcon;
if(dwNumber == 0) dwNumber = 1;
- CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, FIELD_OFFSET(CURICON_OBJECT, aFrame[dwNumber])); + CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
if (!CurIcon) { @@ -232,14 +238,13 @@ }
CurIcon->Self = hCurIcon; - CurIcon->bIcon = bIcon; InitializeListHead(&CurIcon->ProcessList);
if (! ReferenceCurIconByProcess(CurIcon)) { ERR("Failed to add process\n"); + UserDereferenceObject(CurIcon); UserDeleteObject(hCurIcon, otCursorIcon); - UserDereferenceObject(CurIcon); return NULL; }
@@ -251,10 +256,16 @@ BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi, BOOLEAN bForce) { - PSYSTEM_CURSORINFO CurInfo; HBITMAP bmpMask, bmpColor, bmpAlpha; BOOLEAN Ret, bListEmpty, bFound = FALSE; PCURICON_PROCESS Current = NULL; + + /* Check if this is the current cursor */ + if(CurIcon->CURSORF_flags & CURSORF_CURRENT) + { + UserDereferenceObject(CurIcon); + return FALSE; + }
/* For handles created without any data (error handling) */ if(IsListEmpty(&CurIcon->ProcessList)) @@ -308,40 +319,32 @@ /* Remove it from the list */ RemoveEntryList(&CurIcon->ListEntry);
- CurInfo = IntGetSysCursorInfo(); - - if (CurInfo->CurrentCursorObject == CurIcon) - { - /* Hide the cursor if we're destroying the current cursor */ - UserSetCursor(NULL, TRUE); - } - - bmpMask = CurIcon->aFrame[0].hbmMask; - bmpColor = CurIcon->aFrame[0].hbmColor; - bmpAlpha = CurIcon->aFrame[0].hbmAlpha; + bmpMask = CurIcon->hbmMask; + bmpColor = CurIcon->hbmColor; + bmpAlpha = CurIcon->hbmAlpha;
/* Delete bitmaps */ if (bmpMask) { GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpMask); - CurIcon->aFrame[0].hbmMask = NULL; + CurIcon->hbmMask = NULL; } if (bmpColor) { GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpColor); - CurIcon->aFrame[0].hbmColor = NULL; + CurIcon->hbmColor = NULL; } if (bmpAlpha) { GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpAlpha); - CurIcon->aFrame[0].hbmAlpha = NULL; - } - - if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) - ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING); + CurIcon->hbmAlpha = NULL; + } + + if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) + ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if(CurIcon->ustrModule.Buffer) ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
@@ -408,27 +411,16 @@ if(IconInfo) { /* Fill data */ - ii.fIcon = CurIcon->bIcon; - ii.xHotspot = CurIcon->ptlHotspot.x; - ii.yHotspot = CurIcon->ptlHotspot.y; + ii.fIcon = is_icon(CurIcon); + ii.xHotspot = CurIcon->xHotspot; + ii.yHotspot = CurIcon->yHotspot;
/* Copy bitmaps */ - ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask); + ii.hbmMask = BITMAP_CopyBitmap(CurIcon->hbmMask); GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED); - ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor); + ii.hbmColor = BITMAP_CopyBitmap(CurIcon->hbmColor); GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED); - - if (pbpp) - { - PSURFACE psurfBmp; - - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor); - if (psurfBmp) - { - colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat); - SURFACE_ShareUnlockSurface(psurfBmp); - } - } + colorBpp = CurIcon->bpp;
/* Copy fields */ _SEH2_TRY @@ -487,7 +479,7 @@
if(lpResName) { - if(!CurIcon->ustrRsrc.Buffer) + if(!CurIcon->strName.Buffer) { EngSetLastError(ERROR_INVALID_HANDLE); goto leave; @@ -496,15 +488,15 @@ _SEH2_TRY { ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1); - if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) + if(IS_INTRESOURCE(CurIcon->strName.Buffer)) { - lpResName->Buffer = CurIcon->ustrRsrc.Buffer; + lpResName->Buffer = CurIcon->strName.Buffer; lpResName->Length = 0; } else { - lpResName->Length = min(lpResName->MaximumLength, CurIcon->ustrRsrc.Length); - RtlCopyMemory(lpResName->Buffer, CurIcon->ustrRsrc.Buffer, lpResName->Length); + lpResName->Length = min(lpResName->MaximumLength, CurIcon->strName.Length); + RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -558,9 +550,9 @@ _SEH2_TRY { ProbeForWrite(plcx, sizeof(LONG), 1); - RtlCopyMemory(plcx, &CurIcon->Size.cx, sizeof(LONG)); + *plcx = CurIcon->cx; ProbeForWrite(plcy, sizeof(LONG), 1); - RtlCopyMemory(plcy, &CurIcon->Size.cy, sizeof(LONG)); + *plcy = CurIcon->cy; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -788,7 +780,7 @@ _SEH2_TRY { ProbeForRead(param, sizeof(*param), 1); - paramSafe = *param; + RtlCopyMemory(¶mSafe, param, sizeof(paramSafe)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -882,6 +874,7 @@ EngSetLastError(ERROR_INVALID_CURSOR_HANDLE); goto leave; } + pcurNew->CURSORF_flags |= CURSORF_CURRENT; } else { @@ -892,6 +885,7 @@ if (pcurOld) { hOldCursor = (HCURSOR)pcurOld->Self; + pcurOld->CURSORF_flags &= ~CURSORF_CURRENT; UserDereferenceObject(pcurOld); }
@@ -902,7 +896,7 @@
/* - * @implemented + * @unimplemented */ BOOL APIENTRY @@ -910,150 +904,8 @@ HANDLE hCurIcon, PICONINFO UnsafeIconInfo) { - PCURICON_OBJECT CurIcon; - ICONINFO IconInfo; - PSURFACE psurfBmp; - NTSTATUS Status; - BOOL Ret = FALSE; - DECLARE_RETURN(BOOL); - - TRACE("Enter NtUserSetCursorContents\n"); - UserEnterExclusive(); - - if (!(CurIcon = UserGetCurIconObject(hCurIcon))) - { - RETURN(FALSE); - } - - /* Copy fields */ - Status = MmCopyFromCaller(&IconInfo, UnsafeIconInfo, sizeof(ICONINFO)); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - goto done; - } - -#if 0 - /* Check if we get valid information */ - if(IconInfo.fIcon != CurInfo->bIcon) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } -#endif - - /* Delete old bitmaps */ - if (CurIcon->aFrame[0].hbmColor) - GreDeleteObject(CurIcon->aFrame[0].hbmColor); - if (CurIcon->aFrame[0].hbmMask) - GreDeleteObject(CurIcon->aFrame[0].hbmMask); - if(CurIcon->aFrame[0].hbmAlpha) - GreDeleteObject(CurIcon->aFrame[0].hbmAlpha); - - /* Set fields */ - CurIcon->bIcon = IconInfo.fIcon; - CurIcon->ptlHotspot.x = IconInfo.xHotspot; - CurIcon->ptlHotspot.y = IconInfo.yHotspot; - CurIcon->aFrame[0].hbmMask = IconInfo.hbmMask; - CurIcon->aFrame[0].hbmColor = IconInfo.hbmColor; - CurIcon->aFrame[0].hbmAlpha = NULL; - - if (IconInfo.hbmColor) - { - BOOLEAN bAlpha = FALSE; - psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmColor); - if (!psurfBmp) - goto done; - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy; - - /* 32bpp bitmap is likely to have an alpha channel */ - if(psurfBmp->SurfObj.iBitmapFormat == BMF_32BPP) - { - PFN_DIB_GetPixel fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel; - INT i, j; - - fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel; - for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cx; i++) - { - for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cy; j++) - { - bAlpha = ((BYTE)(fn_GetPixel(&psurfBmp->SurfObj, i, j) >> 24)) != 0; - if (bAlpha) - break; - } - if (bAlpha) - break; - } - } - /* We're done with this one */ - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC); - - if(bAlpha) - { - UCHAR Alpha; - PUCHAR ptr; - INT i, j; - /* Copy the bitmap */ - CurIcon->aFrame[0].hbmAlpha = BITMAP_CopyBitmap(IconInfo.hbmColor); - if(!CurIcon->aFrame[0].hbmAlpha) - { - ERR("BITMAP_CopyBitmap failed!"); - goto done; - } - - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmAlpha); - if(!psurfBmp) - { - ERR("SURFACE_LockSurface failed!\n"); - goto done; - } - - /* Premultiply with the alpha channel value */ - for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cy; i++) - { - ptr = (PBYTE)psurfBmp->SurfObj.pvScan0 + i*psurfBmp->SurfObj.lDelta; - for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cx; j++) - { - Alpha = ptr[3]; - ptr[0] = (ptr[0] * Alpha) / 0xff; - ptr[1] = (ptr[1] * Alpha) / 0xff; - ptr[2] = (ptr[2] * Alpha) / 0xff; - ptr += 4; - } - } - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC); - } - } - else - { - psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask); - if (!psurfBmp) - goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2; - - SURFACE_ShareUnlockSurface(psurfBmp); - } - GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC); - - Ret = TRUE; - -done: - - if (CurIcon) - { - UserDereferenceObject(CurIcon); - } - RETURN(Ret); - -CLEANUP: - TRACE("Leave NtUserSetCursorContents, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + FIXME(" is UNIMPLEMENTED.\n"); + return FALSE; }
@@ -1066,13 +918,12 @@ _In_ HCURSOR Handle, _In_opt_ PUNICODE_STRING pustrModule, _In_opt_ PUNICODE_STRING pustrRsrc, - _In_ PICONINFO pIconInfo) + _In_ PCURSORDATA pCursorData) { PCURICON_OBJECT CurIcon; - PSURFACE psurfBmp; NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = FALSE; - ICONINFO ii; + CURSORDATA dataSafe;
TRACE("Enter NtUserSetCursorIconData\n");
@@ -1091,8 +942,8 @@
_SEH2_TRY { - ProbeForRead(pIconInfo, sizeof(ICONINFO), 1); - ii = *pIconInfo; + ProbeForRead(pCursorData, sizeof(*pCursorData), 1); + RtlCopyMemory(&dataSafe, pCursorData, sizeof(dataSafe)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1105,60 +956,46 @@ SetLastNtError(Status); goto done; } - - /* This is probably not what windows does, but consistency checks can't hurt */ - if(CurIcon->bIcon != ii.fIcon) - { + + CurIcon->xHotspot = dataSafe.xHotspot; + CurIcon->yHotspot = dataSafe.yHotspot; + CurIcon->cx = dataSafe.cx; + CurIcon->cy = dataSafe.cy; + CurIcon->rt = dataSafe.rt; + CurIcon->bpp = dataSafe.bpp; + + if(!dataSafe.hbmMask) + { + ERR("NtUserSetCursorIconData was got no hbmMask.\n"); EngSetLastError(ERROR_INVALID_PARAMETER); goto done; } - CurIcon->ptlHotspot.x = ii.xHotspot; - CurIcon->ptlHotspot.y = ii.yHotspot; - - if(!ii.hbmMask) - { - EngSetLastError(ERROR_INVALID_PARAMETER); + + CurIcon->hbmMask = BITMAP_CopyBitmap(dataSafe.hbmMask); + if(!CurIcon->hbmMask) goto done; - } - - CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask); - if(!CurIcon->aFrame[0].hbmMask) - goto done; - - if(ii.hbmColor) - { - CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor); - if(!CurIcon->aFrame[0].hbmColor) + GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC); + + if(dataSafe.hbmColor) + { + CurIcon->hbmColor = BITMAP_CopyBitmap(dataSafe.hbmColor); + if(!CurIcon->hbmColor) goto done; - } - - if (CurIcon->aFrame[0].hbmColor) - { - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor); - if(!psurfBmp) + GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC); + } + + if(dataSafe.hbmAlpha) + { + CurIcon->hbmAlpha = BITMAP_CopyBitmap(dataSafe.hbmAlpha); + if(!CurIcon->hbmAlpha) goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy; - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC); - } - else - { - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask); - if(!psurfBmp) - goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2; - SURFACE_ShareUnlockSurface(psurfBmp); - } - GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC); + GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC); + }
if(pustrModule) { /* We use this convenient function, because INTRESOURCEs and ATOMs are the same */ - Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->ustrRsrc, pustrRsrc); + Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->strName, pustrRsrc); if(!NT_SUCCESS(Status)) goto done; Status = ProbeAndCaptureUnicodeString(&CurIcon->ustrModule, UserMode, pustrModule); @@ -1169,27 +1006,32 @@ Ret = TRUE;
done: - UserDereferenceObject(CurIcon); if(!Ret) { - if (CurIcon->aFrame[0].hbmMask) - { - GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->aFrame[0].hbmMask); - CurIcon->aFrame[0].hbmMask = NULL; - } - if (CurIcon->aFrame[0].hbmColor) - { - GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->aFrame[0].hbmColor); - CurIcon->aFrame[0].hbmColor = NULL; - } - if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) - ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING); + if (CurIcon->hbmMask) + { + GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(CurIcon->hbmMask); + CurIcon->hbmMask = NULL; + } + if (CurIcon->hbmColor) + { + GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(CurIcon->hbmColor); + CurIcon->hbmColor = NULL; + } + if (CurIcon->hbmAlpha) + { + GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(CurIcon->hbmAlpha); + CurIcon->hbmAlpha = NULL; + } + if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) + ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if(CurIcon->ustrModule.Buffer) ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode); } - + UserDereferenceObject(CurIcon); TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret); UserLeave();
@@ -1232,9 +1074,9 @@ return FALSE; }
- hbmMask = pIcon->aFrame[0].hbmMask; - hbmColor = pIcon->aFrame[0].hbmColor; - hbmAlpha = pIcon->aFrame[0].hbmAlpha; + hbmMask = pIcon->hbmMask; + hbmColor = pIcon->hbmColor; + hbmAlpha = pIcon->hbmAlpha;
if (istepIfAniCur) ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); @@ -1254,7 +1096,7 @@ if(hbmColor == NULL) { /* But then the mask bitmap must have the information in it's bottom half */ - ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->Size.cy); + ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->cy); psurfColor = NULL; } else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL) @@ -1294,26 +1136,26 @@ }
/* Set source rect */ - RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy); + RECTL_vSetRect(&rcSrc, 0, 0, pIcon->cx, pIcon->cy);
/* Fix width parameter, if needed */ if (!cxWidth) { if(diFlags & DI_DEFAULTSIZE) - cxWidth = pIcon->bIcon ? + cxWidth = is_icon(pIcon) ? UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR); else - cxWidth = pIcon->Size.cx; + cxWidth = pIcon->cx; }
/* Fix height parameter, if needed */ if (!cyHeight) { if(diFlags & DI_DEFAULTSIZE) - cyHeight = pIcon->bIcon ? + cyHeight = is_icon(pIcon) ? UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR); else - cyHeight = pIcon->Size.cy; + cyHeight = pIcon->cy; }
/* Should we render off-screen? */ @@ -1410,7 +1252,7 @@ }
/* Now do the rendering */ - if(hbmAlpha && (diFlags & DI_IMAGE)) + if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL)) { BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } }; PSURFACE psurf = NULL; @@ -1501,7 +1343,7 @@ { /* Mask bitmap holds the information in its bottom half */ DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY; - RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy); + RECTL_vOffsetRect(&rcSrc, 0, pIcon->cy);
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueu... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -147,10 +147,10 @@ /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON GreSetPointerShape(hdcScreen, - NewCursor->aFrame[0].hbmMask, - NewCursor->aFrame[0].hbmColor, - NewCursor->ptlHotspot.x, - NewCursor->ptlHotspot.y, + NewCursor->hbmMask, + NewCursor->hbmColor, + NewCursor->xHotspot, + NewCursor->yHotspot, gpsi->ptCursor.x, gpsi->ptCursor.y); #else @@ -583,10 +583,10 @@ /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON GreSetPointerShape(hdcScreen, - MessageQueue->CursorObject->aFrame[0].hbmMask, - MessageQueue->CursorObject->aFrame[0].hbmColor, - MessageQueue->CursorObject->ptlHotspot.x, - MessageQueue->CursorObject->ptlHotspot.y, + MessageQueue->CursorObject->hbmMask, + MessageQueue->CursorObject->hbmColor, + MessageQueue->CursorObject->xHotspot, + MessageQueue->CursorObject->yHotspot, gpsi->ptCursor.x, gpsi->ptCursor.y); #else
Modified: trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/windows... ============================================================================== --- trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -1,8 +1,8 @@ /* * PROJECT: ReactOS user32.dll * COPYRIGHT: GPL - See COPYING in the top level directory - * FILE: dll/win32/user32/windows/class.c - * PURPOSE: Window classes + * FILE: dll/win32/user32/windows/cursoricon.c + * PURPOSE: cursor and icons implementation * PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org) */
@@ -171,13 +171,144 @@ return -1; }
+/*********************************************************************** + * bmi_has_alpha + */ +static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits ) +{ + int i; + BOOL has_alpha = FALSE; + const unsigned char *ptr = bits; + + if (info->bmiHeader.biBitCount != 32) return FALSE; + for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4) + if ((has_alpha = (ptr[3] != 0))) break; + return has_alpha; +} + +/*********************************************************************** + * create_alpha_bitmap + * + * Create the alpha bitmap for a 32-bpp icon that has an alpha channel. + */ +static HBITMAP create_alpha_bitmap( + _In_ HBITMAP color, + _In_opt_ const BITMAPINFO *src_info, + _In_opt_ const void *color_bits ) +{ + HBITMAP alpha = NULL, hbmpOld; + BITMAPINFO *info = NULL; + HDC hdc = NULL, hdcScreen; + void *bits = NULL; + unsigned char *ptr; + int i; + LONG width, height; + BITMAP bm; + + if (!GetObjectW( color, sizeof(bm), &bm )) + return NULL; + if (bm.bmBitsPixel != 32) + return NULL; + + hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL); + if(!hdcScreen) + return NULL; + if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32) + goto done; + hdc = CreateCompatibleDC(hdcScreen); + if(!hdc) + goto done; + + if(src_info) + { + WORD bpp; + DWORD compr; + int size; + + if(!bmi_has_alpha(src_info, color_bits)) + goto done; + + if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &width, &height, &bpp, &compr)) + goto done; + if(bpp != 32) + goto done; + + size = get_dib_image_size(width, height, bpp); + bits = HeapAlloc(GetProcessHeap(), 0, size); + if(!bits) + goto done; + CopyMemory(bits, color_bits, size); + } + else + { + info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); + if(!info) + goto done; + info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info->bmiHeader.biWidth = bm.bmWidth; + info->bmiHeader.biHeight = -bm.bmHeight; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + + bits = HeapAlloc(GetProcessHeap(), 0, info->bmiHeader.biSizeImage); + if(!bits) + goto done; + if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS )) + goto done; + if (!bmi_has_alpha( info, bits )) + goto done; + width = bm.bmWidth; + height = bm.bmHeight; + } + + /* pre-multiply by alpha */ + for (i = 0, ptr = bits; i < width * height; i++, ptr += 4) + { + unsigned int alpha = ptr[3]; + ptr[0] = ptr[0] * alpha / 255; + ptr[1] = ptr[1] * alpha / 255; + ptr[2] = ptr[2] * alpha / 255; + } + + /* Create the bitmap */ + alpha = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight); + if(!alpha) + goto done; + hbmpOld = SelectObject(hdc, alpha); + if(!hbmpOld) + goto done; + if(!StretchDIBits( hdc, 0, 0, bm.bmWidth, bm.bmHeight, + 0, 0, width, height, + bits, src_info ? src_info : info, DIB_RGB_COLORS, SRCCOPY )) + { + SelectObject(hdc, hbmpOld); + hbmpOld = NULL; + DeleteObject(alpha); + alpha = NULL; + } + SelectObject(hdc, hbmpOld); + +done: + DeleteDC(hdcScreen); + if(hdc) DeleteDC( hdc ); + if(info) HeapFree( GetProcessHeap(), 0, info ); + if(bits) HeapFree(GetProcessHeap(), 0, bits); + + TRACE("Returning 0x%08x.\n", alpha); + return alpha; +} + /************* IMPLEMENTATION CORE ****************/
-static BOOL CURSORICON_GetIconInfoFromBMI( - _Inout_ ICONINFO* pii, - _In_ const BITMAPINFO *pbmi, - _In_ int cxDesired, - _In_ int cyDesired +static BOOL CURSORICON_GetCursorDataFromBMI( + _Inout_ CURSORDATA* pdata, + _In_ const BITMAPINFO *pbmi ) { UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS); @@ -201,13 +332,22 @@ if(compr != BI_RGB) return FALSE;
+ /* If no dimensions were set, use the one from the icon */ + if(!pdata->cx) pdata->cx = width; + if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2; + /* Fix the hotspot coords */ - if(!pii->fIcon) - { - if(cxDesired != pbmi->bmiHeader.biWidth) - pii->xHotspot = (pii->xHotspot * cxDesired) / pbmi->bmiHeader.biWidth; - if(cxDesired != (pbmi->bmiHeader.biHeight/2)) - pii->yHotspot = (pii->yHotspot * cyDesired * 2) / pbmi->bmiHeader.biHeight; + if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR)) + { + if(pdata->cx != width) + pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width; + if(pdata->cy != height/2) + pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height; + } + else + { + pdata->xHotspot = pdata->cx/2; + pdata->yHotspot = pdata->cy/2; }
hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL); @@ -230,49 +370,52 @@ ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2; else pbmiCopy->bmiHeader.biHeight /= 2; + height /= 2;
pvColor = (const char*)pbmi + ubmiSize; pvMask = (const char*)pvColor + - get_dib_image_size(pbmi->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, pbmi->bmiHeader.biBitCount ); + get_dib_image_size(width, height, bpp );
/* Set XOR bits */ if(monochrome) { /* Create the 1bpp bitmap which will contain everything */ - pii->hbmColor = NULL; - pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired * 2); - if(!pii->hbmMask) + pdata->hbmColor = NULL; + pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL); + if(!pdata->hbmMask) goto done; - hbmpOld = SelectObject(hdc, pii->hbmMask); + hbmpOld = SelectObject(hdc, pdata->hbmMask); if(!hbmpOld) goto done;
- if(!StretchDIBits(hdc, 0, cyDesired, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, + if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy, + 0, 0, width, height, pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY)) goto done; + pdata->bpp = 1; } else { /* Create the bitmap. It has to be compatible with the screen surface */ - pii->hbmColor = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired); - if(!pii->hbmColor) + pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy); + if(!pdata->hbmColor) goto done; /* Create the 1bpp mask bitmap */ - pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired); - if(!pii->hbmMask) + pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL); + if(!pdata->hbmMask) goto done; - hbmpOld = SelectObject(hdc, pii->hbmColor); + hbmpOld = SelectObject(hdc, pdata->hbmColor); if(!hbmpOld) goto done; - if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, + if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy, + 0, 0, width, height, pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY)) goto done; + pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL); + if(pdata->bpp == 32) + pdata->hbmAlpha = create_alpha_bitmap(pdata->hbmColor, pbmiCopy, pvColor);
/* Now convert the info to monochrome for the mask bits */ - pbmiCopy->bmiHeader.biBitCount = 1; - /* Handle the CORE/INFO difference */ if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) { RGBQUAD *rgb = pbmiCopy->bmiColors; @@ -281,6 +424,7 @@ rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00; rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff; rgb[0].rgbReserved = rgb[1].rgbReserved = 0; + pbmiCopy->bmiHeader.biBitCount = 1; } else { @@ -288,14 +432,15 @@
rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00; rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff; + ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1; } } /* Set the mask bits */ - if(!SelectObject(hdc, pii->hbmMask)) + if(!SelectObject(hdc, pdata->hbmMask)) goto done; - bResult = StretchDIBits(hdc, 0, 0, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, - pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0; + bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy, + 0, 0, width, height, + pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
done: DeleteDC(hdcScreen); @@ -305,10 +450,63 @@ /* Clean up in case of failure */ if(!bResult) { - if(pii->hbmMask) DeleteObject(pii->hbmMask); - if(pii->hbmColor) DeleteObject(pii->hbmColor); + if(pdata->hbmMask) DeleteObject(pdata->hbmMask); + if(pdata->hbmColor) DeleteObject(pdata->hbmColor); + if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha); } return bResult; +} + +static BOOL CURSORICON_GetCursorDataFromIconInfo( + _Out_ CURSORDATA* pCursorData, + _In_ ICONINFO* pIconInfo +) +{ + BITMAP bm; + + ZeroMemory(pCursorData, sizeof(*pCursorData)); + /* Use the CopyImage function, as it will gracefully convert our bitmap to the screen bit depth */ + if(pIconInfo->hbmColor) + { + pCursorData->hbmColor = CopyImage(pIconInfo->hbmColor, IMAGE_BITMAP, 0, 0, 0); + if(!pCursorData->hbmColor) + return FALSE; + } + pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME); + if(!pCursorData->hbmMask) + return FALSE; + + /* Now, fill some information */ + pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR)); + if(pCursorData->hbmColor) + { + GetObject(pCursorData->hbmColor, sizeof(bm), &bm); + pCursorData->bpp = bm.bmBitsPixel; + pCursorData->cx = bm.bmWidth; + pCursorData->cy = bm.bmHeight; + if(pCursorData->bpp == 32) + pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL); + } + else + { + GetObject(pCursorData->hbmMask, sizeof(bm), &bm); + pCursorData->bpp = 1; + pCursorData->cx = bm.bmWidth; + pCursorData->cy = bm.bmHeight/2; + } + + if(pIconInfo->fIcon) + { + pCursorData->xHotspot = pCursorData->cx/2; + pCursorData->yHotspot = pCursorData->cy/2; + } + else + { + pCursorData->xHotspot = pIconInfo->xHotspot; + pCursorData->yHotspot = pIconInfo->yHotspot; + } + + return TRUE; }
static @@ -324,14 +522,17 @@ const BITMAPINFO* pbmi; BITMAPINFO* pbmiScaled = NULL; BITMAPINFO* pbmiCopy = NULL; - const VOID* pvMapping; + const VOID* pvMapping = NULL; DWORD dwOffset = 0; - HGLOBAL hgRsrc; + HGLOBAL hgRsrc = NULL; int iBMISize; PVOID pvBits; HDC hdcScreen = NULL; HDC hdc = NULL; - HBITMAP hbmpRet, hbmpOld; + HBITMAP hbmpOld, hbmpRet = NULL; + LONG width, height; + WORD bpp; + DWORD compr;
/* Map the bitmap info */ if(fuLoad & LR_LOADFROMFILE) @@ -371,7 +572,18 @@ return NULL; }
- /* See if we must scale the bitmap */ + /* Fix up values */ + if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1) + goto end; + if((width > 65535) || (height > 65535)) + goto end; + if(cxDesired == 0) + cxDesired = width; + if(cyDesired == 0) + cyDesired = height; + else if(height < 0) + cyDesired = -cyDesired; + iBMISize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
/* Get a pointer to the image data */ @@ -492,35 +704,15 @@ if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader; - if(cxDesired == 0) - cxDesired = pbmch->bcWidth; - if(cyDesired == 0) - cyDesired == pbmch->bcHeight; - else if(pbmch->bcHeight < 0) - cyDesired = -cyDesired; - pbmch->bcWidth = cxDesired; pbmch->bcHeight = cyDesired; } else { - if ((pbmi->bmiHeader.biHeight > 65535) || (pbmi->bmiHeader.biWidth > 65535)) { - WARN("Broken BITMAPINFO!\n"); - goto end; - } - - if(cxDesired == 0) - cxDesired = pbmi->bmiHeader.biWidth; - if(cyDesired == 0) - cyDesired = pbmi->bmiHeader.biHeight; - else if(pbmi->bmiHeader.biHeight < 0) - cyDesired = -cyDesired; - pbmiScaled->bmiHeader.biWidth = cxDesired; pbmiScaled->bmiHeader.biHeight = cyDesired; /* No compression for DIB sections */ - if(fuLoad & LR_CREATEDIBSECTION) - pbmiScaled->bmiHeader.biCompression = BI_RGB; + pbmiScaled->bmiHeader.biCompression = BI_RGB; } }
@@ -574,9 +766,9 @@ HeapFree(GetProcessHeap(), 0, pbmiScaled); if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy); - if (fuLoad & LR_LOADFROMFILE) + if (pvMapping) UnmapViewOfFile( pvMapping ); - else + if(hgRsrc) FreeResource(hgRsrc);
return hbmpRet; @@ -621,9 +813,9 @@ CURSORICONFILEDIR *dir; DWORD filesize = 0; LPBYTE bits; - HANDLE hRet = NULL; + HANDLE hCurIcon = NULL; WORD i; - ICONINFO ii; + CURSORDATA cursorData;
TRACE("loading %s\n", debugstr_w( lpszName ));
@@ -696,25 +888,42 @@
/* Get our entry */ entry = &dir->idEntries[i-1]; + /* Fix dimensions */ + if(!cxDesired) cxDesired = entry->bWidth; + if(!cyDesired) cyDesired = entry->bHeight; /* A bit of preparation */ - ii.xHotspot = entry->xHotspot; - ii.yHotspot = entry->yHotspot; - ii.fIcon = bIcon; + ZeroMemory(&cursorData, sizeof(cursorData)); + if(!bIcon) + { + cursorData.xHotspot = entry->xHotspot; + cursorData.yHotspot = entry->yHotspot; + } + cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
/* Do the dance */ - if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)&bits[entry->dwDIBOffset], cxDesired, cyDesired)) + if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)&bits[entry->dwDIBOffset])) goto end;
- /* Create the icon. NOTE: there's no LR_SHARED icons if they are created from file */ - hRet = CreateIconIndirect(&ii); + hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); + if(!hCurIcon) + goto end_clean; + + /* Tell win32k */ + if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData)) + { + NtUserDestroyCursor(hCurIcon, TRUE); + hCurIcon = NULL; + }
/* Clean up */ - DeleteObject(ii.hbmMask); - DeleteObject(ii.hbmColor); +end_clean: + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
end: UnmapViewOfFile(bits); - return hRet; + return hCurIcon; }
static @@ -733,7 +942,7 @@ CURSORICONDIR* dir; WORD wResId; LPBYTE bits; - ICONINFO ii; + CURSORDATA cursorData; BOOL bStatus; UNICODE_STRING ustrRsrc; UNICODE_STRING ustrModule = {0, 0, NULL}; @@ -775,7 +984,7 @@ /* Get it */ do { - DWORD ret = GetModuleFileName(hinst, ustrModule.Buffer, size); + DWORD ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size); if(ret == 0) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); @@ -783,8 +992,8 @@ } if(ret < size) { - ustrModule.Length = ret; - ustrModule.MaximumLength = size; + ustrModule.Length = ret*sizeof(WCHAR); + ustrModule.MaximumLength = size*sizeof(WCHAR); break; } size *= 2; @@ -845,27 +1054,24 @@ goto done; }
- /* Get the hotspot */ - if(bIcon) - { - ii.xHotspot = cxDesired/2; - ii.yHotspot = cyDesired/2; - } - if(!bIcon) - { + ZeroMemory(&cursorData, sizeof(cursorData)); + + if(dir->idType == 2) + { + /* idType == 2 for cursor resources */ SHORT* ptr = (SHORT*)bits; - ii.xHotspot = ptr[0]; - ii.yHotspot = ptr[1]; + cursorData.xHotspot = ptr[0]; + cursorData.yHotspot = ptr[1]; bits += 2*sizeof(SHORT); } - ii.fIcon = bIcon; + cursorData.cx = cxDesired; + cursorData.cy = cyDesired; + cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
/* Get the bitmaps */ - bStatus = CURSORICON_GetIconInfoFromBMI( - &ii, - (BITMAPINFO*)bits, - cxDesired, - cyDesired); + bStatus = CURSORICON_GetCursorDataFromBMI( + &cursorData, + (BITMAPINFO*)bits);
FreeResource( handle );
@@ -876,16 +1082,17 @@ hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); if(!hCurIcon) { - DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); goto done; }
/* Tell win32k */ if(fuLoad & LR_SHARED) - bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &ii); + bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData); else - bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii); + bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData);
if(!bStatus) { @@ -893,8 +1100,9 @@ hCurIcon = NULL; }
- DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
done: if(ustrModule.Buffer) @@ -905,10 +1113,10 @@ static HBITMAP BITMAP_CopyImage( - _In_ HBITMAP hbmp, - _In_ int cxDesired, - _In_ int cyDesired, - _In_ UINT fuFlags + _In_ HBITMAP hnd, + _In_ int desiredx, + _In_ int desiredy, + _In_ UINT flags ) { HBITMAP res = NULL; @@ -916,22 +1124,22 @@ int objSize; BITMAPINFO * bi;
- objSize = GetObjectW( hbmp, sizeof(ds), &ds ); + objSize = GetObjectW( hnd, sizeof(ds), &ds ); if (!objSize) return 0; - if ((cxDesired < 0) || (cyDesired < 0)) return 0; - - if (fuFlags & LR_COPYFROMRESOURCE) + if ((desiredx < 0) || (desiredy < 0)) return 0; + + if (flags & LR_COPYFROMRESOURCE) { FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n"); }
- if (fuFlags & LR_COPYRETURNORG) + if (flags & LR_COPYRETURNORG) { FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n"); }
- if (cxDesired == 0) cxDesired = ds.dsBm.bmWidth; - if (cyDesired == 0) cyDesired = ds.dsBm.bmHeight; + if (desiredx == 0) desiredx = ds.dsBm.bmWidth; + if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
/* Allocate memory for a BITMAPINFOHEADER structure and a color table. The maximum number of colors in a color table @@ -945,7 +1153,7 @@ bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel; bi->bmiHeader.biCompression = BI_RGB;
- if (fuFlags & LR_CREATEDIBSECTION) + if (flags & LR_CREATEDIBSECTION) { /* Create a DIB section. LR_MONOCHROME is ignored */ void * bits; @@ -958,12 +1166,11 @@ memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); }
+ bi->bmiHeader.biWidth = desiredx; + bi->bmiHeader.biHeight = desiredy; + /* Get the color table or the color masks */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); - - bi->bmiHeader.biWidth = cxDesired; - bi->bmiHeader.biHeight = cyDesired; - bi->bmiHeader.biSizeImage = 0; + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0); DeleteDC(dc); @@ -972,16 +1179,16 @@ { /* Create a device-dependent bitmap */
- BOOL monochrome = (fuFlags & LR_MONOCHROME); + BOOL monochrome = (flags & LR_MONOCHROME);
if (objSize == sizeof(DIBSECTION)) { /* The source bitmap is a DIB section. Get its attributes */ HDC dc = CreateCompatibleDC(NULL); - bi->bmiHeader.biSize = sizeof(bi->bmiHeader); - bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel; - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); + bi->bmiHeader.biWidth = ds.dsBm.bmWidth; + bi->bmiHeader.biHeight = ds.dsBm.bmHeight; + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); DeleteDC(dc);
if (!monochrome && ds.dsBm.bmBitsPixel == 1) @@ -1015,12 +1222,12 @@
if (monochrome) { - res = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL); + res = CreateBitmap(desiredx, desiredy, 1, 1, NULL); } else { HDC screenDC = GetDC(NULL); - res = CreateCompatibleBitmap(screenDC, cxDesired, cyDesired); + res = CreateCompatibleBitmap(screenDC, desiredx, desiredy); ReleaseDC(NULL, screenDC); } } @@ -1061,7 +1268,7 @@ bi->bmiHeader.biClrImportant = 0;
/* Fill in biSizeImage */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
if (bits) @@ -1069,11 +1276,11 @@ HBITMAP oldBmp;
/* Get the image bits of the source bitmap */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS); + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
/* Copy it to the destination bitmap */ oldBmp = SelectObject(dc, res); - StretchDIBits(dc, 0, 0, cxDesired, cyDesired, + StretchDIBits(dc, 0, 0, desiredx, desiredy, 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS, SRCCOPY); SelectObject(dc, oldBmp); @@ -1084,9 +1291,9 @@ DeleteDC(dc); }
- if (fuFlags & LR_COPYDELETEORG) - { - DeleteObject(hbmp); + if (flags & LR_COPYDELETEORG) + { + DeleteObject(hnd); } } HeapFree(GetProcessHeap(), 0, bi); @@ -1114,17 +1321,17 @@ PVOID pvBuf; HMODULE hModule;
- ustrModule.MaximumLength = MAX_PATH; + ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR); ustrRsrc.MaximumLength = 256;
- ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength * sizeof(WCHAR)); + ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength); if(!ustrModule.Buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } /* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */ - pvBuf = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WCHAR)); + pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength); if(!pvBuf) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); @@ -1153,7 +1360,7 @@ { PWSTR newBuffer; ustrModule.MaximumLength *= 2; - newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength * sizeof(WCHAR)); + newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength); if(!ustrModule.Buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1165,7 +1372,7 @@ if(ustrRsrc.Length == ustrRsrc.MaximumLength) { ustrRsrc.MaximumLength *= 2; - pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength * sizeof(WCHAR)); + pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength); if(!pvBuf) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1176,14 +1383,15 @@ } while(TRUE);
/* NULL-terminate our strings */ - ustrModule.Buffer[ustrModule.Length] = 0; + ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0; if(!IS_INTRESOURCE(ustrRsrc.Buffer)) - ustrRsrc.Buffer[ustrRsrc.Length] = 0; + ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = 0;
/* Get the module handle */ if(!GetModuleHandleExW(0, ustrModule.Buffer, &hModule)) { /* This hould never happen */ + ERR("Invalid handle?.\n"); SetLastError(ERROR_INVALID_PARAMETER); goto leave; } @@ -1197,6 +1405,8 @@ leave: HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); HeapFree(GetProcessHeap(), 0, pvBuf); + + TRACE("Returning 0x%08x.\n", ret);
return ret; } @@ -1499,21 +1709,6 @@ return 0; }
- /* idType == 2 is for cursors, 1 for icons */ - /*if(fIcon) - { - if(dir->idType == 2) - { - WARN("An icon was asked for a cursor resource.\n"); - return 0; - } - } - else if(dir->idType == 1) - { - WARN("A cursor was asked for an icon resource.\n"); - return 0; - }*/ - if(Flags & LR_MONOCHROME) bppDesired = 1; else @@ -1526,6 +1721,11 @@ bppDesired = GetDeviceCaps(icScreen, BITSPIXEL); DeleteDC(icScreen); } + + if(!cxDesired) + cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR); + if(!cyDesired) + cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
/* Find the best match for the desired size */ cxyDiff = 0xFFFFFFFF; @@ -1658,7 +1858,7 @@ _In_ DWORD dwVer ) { - return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0,0,0); + return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED); }
HICON WINAPI CreateIconFromResourceEx( @@ -1671,34 +1871,60 @@ _In_ UINT uFlags ) { - ICONINFO ii; + CURSORDATA cursorData; HICON hIcon;
- if(uFlags) - FIXME("uFlags 0x%08x ignored.\n", uFlags); - - if(fIcon) - { - ii.xHotspot = cxDesired/2; - ii.yHotspot = cyDesired/2; - } - else + TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags); + + if(uFlags & ~LR_DEFAULTSIZE) + FIXME("uFlags 0x%08x ignored.\n", uFlags & ~LR_DEFAULTSIZE); + + if(uFlags & LR_DEFAULTSIZE) + { + if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR); + if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR); + } + + /* Check if this is an animated cursor */ + if(!memcmp(pbIconBits, "RIFF", 4)) + { + UNIMPLEMENTED; + return NULL; + } + + ZeroMemory(&cursorData, sizeof(cursorData)); + cursorData.cx = cxDesired; + cursorData.cy = cyDesired; + cursorData.rt = (USHORT)((ULONG_PTR)(fIcon ? RT_ICON : RT_CURSOR)); + if(!fIcon) { WORD* pt = (WORD*)pbIconBits; - ii.xHotspot = *pt++; - ii.yHotspot = *pt++; + cursorData.xHotspot = *pt++; + cursorData.yHotspot = *pt++; pbIconBits = (PBYTE)pt; } - ii.fIcon = fIcon; - - if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)pbIconBits, cxDesired, cyDesired)) + + if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)pbIconBits)) + { + ERR("Couldn't fill the CURSORDATA structure.\n"); return NULL; - - hIcon = CreateIconIndirect(&ii); + } + + hIcon = NtUserxCreateEmptyCurObject(fIcon ? 0 : 1); + if(!hIcon) + return NULL; + + if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData)) + { + ERR("NtUserSetCursorIconData failed.\n"); + NtUserDestroyCursor(hIcon, TRUE); + hIcon = NULL; + }
/* Clean up */ - DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return hIcon; } @@ -1709,18 +1935,27 @@ { /* As simple as creating a handle, and let win32k deal with the bitmaps */ HICON hiconRet; + CURSORDATA cursorData;
TRACE("%p.\n", piconinfo); + + if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo)) + return NULL;
hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1); if(!hiconRet) return NULL;
- if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, piconinfo)) + if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData)) { NtUserDestroyCursor(hiconRet, FALSE); hiconRet = NULL; } + + /* Clean up */ + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
TRACE("Returning 0x%08x.\n", hiconRet);
@@ -1768,8 +2003,7 @@ _In_ int Y ) { - UNIMPLEMENTED; - return FALSE; + return NtUserxSetCursorPos(X,Y); }
BOOL WINAPI GetCursorPos( @@ -1783,14 +2017,12 @@ _In_ BOOL bShow ) { - UNIMPLEMENTED; - return -1; + return NtUserxShowCursor(bShow); }
HCURSOR WINAPI GetCursor(void) { - UNIMPLEMENTED; - return NULL; + return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR); }
BOOL WINAPI DestroyCursor(
Modified: trunk/reactos/win32ss/w32ksvc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/w32ksvc.h?rev=57692... ============================================================================== --- trunk/reactos/win32ss/w32ksvc.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/w32ksvc.h [iso-8859-1] Thu Nov 8 12:51:24 2012 @@ -380,8 +380,11 @@ SVC_(UserEvent, 1) SVC_(UserExcludeUpdateRgn, 2) SVC_(UserFillWindow, 4) -// SVC_(UserFindExistingCursorIcon, 3, Wrong, number, of, param, ?) +#ifdef NEW_CURSORICON +SVC_(UserFindExistingCursorIcon, 3) +#else SVC_(UserFindExistingCursorIcon, 4) +#endif SVC_(UserFindWindowEx, 5) SVC_(UserFlashWindowEx, 1) SVC_(UserGetAltTabInfo, 6)