Synchronize up to trunk's revision r57756.

svn path=/branches/ros-csrss/; revision=57757
This commit is contained in:
Hermès Bélusca-Maïto 2012-11-24 13:02:15 +00:00
commit 2d18c1a929
61 changed files with 2214 additions and 931 deletions

View file

@ -232,29 +232,51 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
{
IntEngBitBlt(psoDest,
&pgp->psurfMask->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP4_FROM_INDEX(R3_OPINDEX_SRCAND));
if(!(pgp->flags & SPS_ALPHA))
{
IntEngBitBlt(psoDest,
&pgp->psurfMask->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP4_SRCAND);
IntEngBitBlt(psoDest,
&pgp->psurfColor->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT));
IntEngBitBlt(psoDest,
&pgp->psurfColor->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP4_SRCINVERT);
}
else
{
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
EXLATEOBJ exlo;
EXLATEOBJ_vInitialize(&exlo,
pgp->psurfColor->ppal,
ppdev->ppalSurf,
0xFFFFFFFF,
0xFFFFFFFF,
0);
IntEngAlphaBlend(psoDest,
&pgp->psurfColor->SurfObj,
NULL,
&exlo.xlo,
&rclSurf,
&rclPointer,
&blendobj);
EXLATEOBJ_vCleanup(&exlo);
}
}
else
{
@ -352,7 +374,15 @@ EngSetPointerShape(
if (psoColor)
{
/* Color bitmap must have the same format as the dest surface */
if (psoColor->iBitmapFormat != pso->iBitmapFormat) goto failure;
if (psoColor->iBitmapFormat != pso->iBitmapFormat)
{
/* It's OK if we have an alpha bitmap */
if(!(fl & SPS_ALPHA))
{
DPRINT1("Screen surface and cursor color bitmap format don't match!.\n");
goto failure;
}
}
/* Create a bitmap to copy the color bitmap to */
hbmColor = EngCreateBitmap(psoColor->sizlBitmap,
@ -452,6 +482,7 @@ EngSetPointerShape(
pgp->HotSpot.x = xHot;
pgp->HotSpot.y = yHot;
pgp->Size = sizel;
pgp->flags = fl;
if (x != -1)
{
@ -598,12 +629,12 @@ GreSetPointerShape(
LONG xHot,
LONG yHot,
LONG x,
LONG y)
LONG y,
FLONG fl)
{
PDC pdc;
PSURFACE psurf, psurfMask, psurfColor;
EXLATEOBJ exlo;
FLONG fl = 0;
ULONG ulResult = 0;
pdc = DC_LockDc(hdc);
@ -629,7 +660,10 @@ GreSetPointerShape(
if (hbmMask)
psurfMask = SURFACE_ShareLockSurface(hbmMask);
else
{
ASSERT(fl & SPS_ALPHA);
psurfMask = NULL;
}
/* Check for color bitmap */
if (hbmColor)
@ -645,6 +679,9 @@ GreSetPointerShape(
}
else
psurfColor = NULL;
/* We must have a valid surface in case of alpha bitmap */
ASSERT(((fl & SPS_ALPHA) && psurfColor) || !(fl & SPS_ALPHA));
/* Call the driver or eng function */
ulResult = IntEngSetPointerShape(&psurf->SurfObj,

View file

@ -12,7 +12,8 @@ GreSetPointerShape(
LONG xHot,
LONG yHot,
LONG x,
LONG y);
LONG y,
FLONG fl);
VOID
NTAPI

View file

@ -34,6 +34,7 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
SURFACE *psurfColor;
SURFACE *psurfMask;
SURFACE *psurfSave;
FLONG flags;
/* Public pointer information */
RECTL Exclude; /* Required publicly for SPS_ACCEPT_EXCLUDE */

View file

@ -173,6 +173,7 @@ UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
BOOL FASTCALL IntSetDefaultRegion(PDC);
ULONG TranslateCOLORREF(PDC pdc, COLORREF crColor);
int FASTCALL GreSetStretchBltMode(HDC hdc, int iStretchMode);

View file

@ -96,6 +96,29 @@ IntGdiSetTextColor(HDC hDC,
return crOldColor;
}
int
FASTCALL
GreSetStretchBltMode(HDC hDC, int iStretchMode)
{
PDC pdc;
PDC_ATTR pdcattr;
INT oSMode = 0;
pdc = DC_LockDc(hDC);
if (pdc)
{
pdcattr = pdc->pdcattr;
oSMode = pdcattr->lStretchBltMode;
pdcattr->lStretchBltMode = iStretchMode;
// Wine returns an error here. We set the default.
if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
pdcattr->jStretchBltMode = iStretchMode;
}
return oSMode;
}
VOID
FASTCALL
DCU_SetDcUndeletable(HDC hDC)

View file

@ -7,8 +7,11 @@ int FASTCALL DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
INT APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth);
HPALETTE FASTCALL DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi);
HPALETTE FASTCALL BuildDIBPalette (CONST BITMAPINFO *bmi);
/* Those functions permit to tranparently work with a BITMAPCOREINFO structure */
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
/* Pass Usage = -1 if you don't want to convert the BITMAPINFO back to BITMAPCOREINFO */
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD Usage);
INT
APIENTRY

View file

@ -584,7 +584,6 @@ GreGetDIBitsInternal(
DWORD compr, size ;
USHORT i;
int bitmap_type;
RGBTRIPLE* rgbTriples;
RGBQUAD* rgbQuads;
VOID* colorPtr;
@ -594,7 +593,6 @@ GreGetDIBitsInternal(
return 0;
colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
rgbTriples = colorPtr;
rgbQuads = colorPtr;
bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
@ -643,15 +641,6 @@ GreGetDIBitsInternal(
switch(bpp)
{
case 0: /* Only info */
if(pbmci)
{
pbmci->bmciHeader.bcWidth = (WORD)psurf->SurfObj.sizlBitmap.cx;
pbmci->bmciHeader.bcHeight = (WORD)((psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
-psurf->SurfObj.sizlBitmap.cy :
psurf->SurfObj.sizlBitmap.cy);
pbmci->bmciHeader.bcPlanes = 1;
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
}
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
-psurf->SurfObj.sizlBitmap.cy :
@ -702,31 +691,19 @@ GreGetDIBitsInternal(
if(Usage == DIB_RGB_COLORS)
{
ULONG colors = min(psurf->ppal->NumColors, 256);
if(pbmci)
{
for(i = 0; i < colors; i++)
{
rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
}
}
if(colors != 256) Info->bmiHeader.biClrUsed = colors;
for(i = 0; i < colors; i++)
{
rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
rgbQuads[i].rgbReserved = 0;
}
}
else
{
for(i = 0; i < 256; i++)
{
if(pbmci) ((WORD*)rgbTriples)[i] = i;
((WORD*)rgbQuads)[i] = i;
}
}
}
else
@ -735,7 +712,6 @@ GreGetDIBitsInternal(
{
for(i = 0; i < 256; i++)
{
if(pbmci) ((WORD*)rgbTriples)[i] = i;
((WORD*)rgbQuads)[i] = i;
}
}
@ -752,13 +728,6 @@ GreGetDIBitsInternal(
}
for (i = 0; i < pDcPal->NumColors; i++)
{
if (pbmci)
{
rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
@ -771,55 +740,20 @@ GreGetDIBitsInternal(
switch (bpp)
{
case 1:
if (pbmci)
{
rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
rgbTriples[0].rgbtBlue = 0;
rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
rgbTriples[1].rgbtBlue = 0xff;
}
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
rgbQuads[0].rgbBlue = 0;
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
rgbQuads[0].rgbReserved = 0;
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
rgbQuads[1].rgbBlue = 0xff;
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
rgbQuads[1].rgbReserved = 0;
break;
case 4:
if (pbmci)
RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
break;
case 8:
{
INT r, g, b;
RGBQUAD *color;
if (pbmci)
{
RGBTRIPLE *colorTriple;
RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
10 * sizeof(RGBTRIPLE));
RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
10 * sizeof(RGBTRIPLE));
colorTriple = rgbTriples + 10;
for(r = 0; r <= 5; r++) /* FIXME */
{
for(g = 0; g <= 5; g++)
{
for(b = 0; b <= 5; b++)
{
colorTriple->rgbtRed = (r * 0xff) / 5;
colorTriple->rgbtGreen = (g * 0xff) / 5;
colorTriple->rgbtBlue = (b * 0xff) / 5;
colorTriple++;
}
}
}
}
memcpy(rgbQuads, DefLogPaletteQuads,
10 * sizeof(RGBQUAD));
memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
@ -933,11 +867,8 @@ GreGetDIBitsInternal(
}
psurfDest = SURFACE_ShareLockSurface(hBmpDest);
rcDest.left = 0;
rcDest.top = 0;
rcDest.bottom = ScanLines;
rcDest.right = psurf->SurfObj.sizlBitmap.cx;
RECTL_vSetRect(&rcDest, 0, 0, ScanLines, psurf->SurfObj.sizlBitmap.cx);
srcPoint.x = 0;
@ -987,7 +918,7 @@ done:
if(pDC) DC_UnlockDc(pDC);
if(psurf) SURFACE_ShareUnlockSurface(psurf);
if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage);
return ScanLines;
}
@ -1926,10 +1857,51 @@ DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
VOID
FASTCALL
DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD usage)
{
if(converted != orig)
BITMAPCOREINFO* pbmci;
if(converted == orig)
return;
if(usage == -1)
{
/* Caller don't want any conversion */
ExFreePoolWithTag(converted, TAG_DIB);
return;
}
/* Perform inverse conversion */
pbmci = (BITMAPCOREINFO*)orig;
ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
if(pbmci->bmciHeader.bcBitCount <= 8)
{
UINT numColors = converted->bmiHeader.biClrUsed;
if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
if(usage == DIB_PAL_COLORS)
{
RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
}
else
{
UINT i;
RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
for(i=0; i<numColors; i++)
{
pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
}
}
}
/* Now free it, it's not needed anymore */
ExFreePoolWithTag(converted, TAG_DIB);
}
/* EOF */

View file

@ -976,6 +976,43 @@ typedef struct tagSETCLIPBDATA
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
NtUserAssociateInputContext(
@ -2737,15 +2774,21 @@ NtUserSetCursorIconData(
_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

View file

@ -149,17 +149,33 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
/* make console active, and insert into console list */
Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
/*
* If we are not in GUI-mode, start the text-mode console. If we fail,
* try to start the GUI-mode console (win32k will automatically switch
* to graphical mode, therefore no additional code is needed).
*/
if (!GuiMode)
{
DPRINT1("WIN32CSR: Opening text-mode console\n");
Status = TuiInitConsole(Console);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
GuiMode = TRUE;
}
}
else /* GuiMode */
/*
* Try to open the GUI-mode console. Two cases are possible:
* - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
* failed and we start GUI-mode console.
* - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
* succeeded BUT we failed at starting text-mode console. Then GuiMode
* was switched to TRUE in order to try to open the console in GUI-mode.
*/
if (GuiMode)
{
DPRINT1("WIN32CSR: Opening GUI-mode console\n");
Status = GuiInitConsole(Console, ShowCmd);
if (!NT_SUCCESS(Status))
{
@ -167,13 +183,13 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
DPRINT1("GuiInitConsole: failed\n");
DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
return Status;
}
}
Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
if (! NT_SUCCESS(Status))
if (!NT_SUCCESS(Status))
{
ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);

View file

@ -276,7 +276,7 @@ cleanup:
UserReleaseDC(NULL, hdc, FALSE);
if (pConvertedBmi)
DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi);
DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi, -1);
}
VOID static NTAPI

View file

@ -1154,6 +1154,12 @@ UserDrawIconEx(
return FALSE;
}
if (!psurfColor)
{
ERR("Attention HAX FIX API DrawIconEx TEST Line 37: psurfColor is NULL going with Mask!\n");
psurfColor = SURFACE_ShareLockSurface(hbmMask);
}
psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
0, 0, NULL);

View file

@ -9,26 +9,29 @@ typedef struct tagCURICON_PROCESS
} 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

View file

@ -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 @@ InitCursorImpl()
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;
}
@ -66,6 +66,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! */
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
{
@ -182,23 +189,23 @@ IntFindExistingCurIconObject(
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 @@ PCURICON_OBJECT
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 @@ IntCreateCurIconHandle(DWORD dwNumber)
}
CurIcon->Self = hCurIcon;
CurIcon->bIcon = bIcon;
InitializeListHead(&CurIcon->ProcessList);
if (! ReferenceCurIconByProcess(CurIcon))
{
ERR("Failed to add process\n");
UserDeleteObject(hCurIcon, otCursorIcon);
UserDereferenceObject(CurIcon);
UserDeleteObject(hCurIcon, otCursorIcon);
return NULL;
}
@ -251,11 +256,17 @@ IntCreateCurIconHandle(DWORD dwNumber)
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))
goto emptyList;
@ -308,40 +319,32 @@ emptyList:
/* 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;
CurIcon->hbmAlpha = NULL;
}
if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
if(!IS_INTRESOURCE(CurIcon->strName.Buffer))
ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
if(CurIcon->ustrModule.Buffer)
ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
@ -408,27 +411,16 @@ NtUserGetIconInfo(
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 @@ NtUserGetIconInfo(
if(lpResName)
{
if(!CurIcon->ustrRsrc.Buffer)
if(!CurIcon->strName.Buffer)
{
EngSetLastError(ERROR_INVALID_HANDLE);
goto leave;
@ -496,15 +488,15 @@ NtUserGetIconInfo(
_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 @@ NtUserGetIconSize(
_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 @@ NtUserFindExistingCursorIcon(
_SEH2_TRY
{
ProbeForRead(param, sizeof(*param), 1);
paramSafe = *param;
RtlCopyMemory(&paramSafe, param, sizeof(paramSafe));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -882,6 +874,7 @@ NtUserSetCursor(
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
goto leave;
}
pcurNew->CURSORF_flags |= CURSORF_CURRENT;
}
else
{
@ -892,6 +885,7 @@ NtUserSetCursor(
if (pcurOld)
{
hOldCursor = (HCURSOR)pcurOld->Self;
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
UserDereferenceObject(pcurOld);
}
@ -902,7 +896,7 @@ leave:
/*
* @implemented
* @unimplemented
*/
BOOL
APIENTRY
@ -910,150 +904,8 @@ NtUserSetCursorContents(
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,11 @@ NtUserSetCursorIconData(
_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;
TRACE("Enter NtUserSetCursorIconData\n");
@ -1091,8 +941,16 @@ NtUserSetCursorIconData(
_SEH2_TRY
{
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
ii = *pIconInfo;
ProbeForRead(pCursorData, sizeof(*pCursorData), 1);
CurIcon->xHotspot = pCursorData->xHotspot;
CurIcon->yHotspot = pCursorData->yHotspot;
CurIcon->cx = pCursorData->cx;
CurIcon->cy = pCursorData->cy;
CurIcon->rt = pCursorData->rt;
CurIcon->bpp = pCursorData->bpp;
CurIcon->hbmMask = pCursorData->hbmMask;
CurIcon->hbmColor = pCursorData->hbmColor;
CurIcon->hbmAlpha = pCursorData->hbmAlpha;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -1106,90 +964,44 @@ NtUserSetCursorIconData(
goto done;
}
/* This is probably not what windows does, but consistency checks can't hurt */
if(CurIcon->bIcon != ii.fIcon)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto done;
}
CurIcon->ptlHotspot.x = ii.xHotspot;
CurIcon->ptlHotspot.y = ii.yHotspot;
if(!ii.hbmMask)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
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)
goto done;
}
if (CurIcon->aFrame[0].hbmColor)
{
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
if(!psurfBmp)
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);
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);
if(!NT_SUCCESS(Status))
goto done;
}
if(!CurIcon->hbmMask)
{
ERR("NtUserSetCursorIconData was got no hbmMask.\n");
EngSetLastError(ERROR_INVALID_PARAMETER);
goto done;
}
GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC);
if(CurIcon->hbmColor)
GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC);
if(CurIcon->hbmAlpha)
GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
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(!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 +1044,9 @@ UserDrawIconEx(
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 +1066,7 @@ UserDrawIconEx(
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 +1106,26 @@ UserDrawIconEx(
}
/* 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 +1222,7 @@ UserDrawIconEx(
}
/* 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 +1313,7 @@ NoAlpha:
{
/* 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);

View file

@ -173,7 +173,7 @@ InitVideo()
if (NT_SUCCESS(Status))
{
/* Check if VGA mode is requested. */
if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0)
if (wcsstr(awcBuffer, L"BASEVIDEO") != 0)
{
ERR("VGA mode requested.\n");
gbBaseVideo = TRUE;

View file

@ -900,7 +900,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
/* Post a keyboard message */
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY);
MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY, 0);
}
return TRUE;
@ -1121,7 +1121,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
NewMsg.wParam = HIWORD(lpMsg->lParam);
NewMsg.lParam = LOWORD(lpMsg->lParam);
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
return TRUE;
}
@ -1150,7 +1150,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
{
TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
NewMsg.wParam = wch[i];
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
}
bResult = TRUE;
}

View file

@ -1105,7 +1105,7 @@ UserPostThreadMessage( DWORD idThread,
KeQueryTickCount(&LargeTickCount);
Message.time = MsqCalculateMessageTime(&LargeTickCount);
MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0);
ObDereferenceObject( peThread );
return TRUE;
}
@ -1228,7 +1228,7 @@ UserPostMessage( HWND Wnd,
}
else
{
MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0);
}
}
return TRUE;

View file

@ -233,7 +233,7 @@ UserLoadImage(PCWSTR pwszName)
0);
NtGdiDeleteObjectApp(hdc);
DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi, -1);
}
else
{

View file

@ -147,12 +147,13 @@ UserSetCursor(
/* 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->hbmAlpha ? NULL : NewCursor->hbmMask,
NewCursor->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor,
NewCursor->xHotspot,
NewCursor->yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
gpsi->ptCursor.y,
NewCursor->hbmAlpha ? SPS_ALPHA : 0);
#else
GreSetPointerShape(hdcScreen,
NewCursor->IconInfo.hbmMask,
@ -160,7 +161,8 @@ UserSetCursor(
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
gpsi->ptCursor.y,
0);
#endif
}
else /* Note: OldCursor != NewCursor so we have to hide cursor */
@ -582,13 +584,16 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
{
/* 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,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
GreSetPointerShape(hdcScreen,
MessageQueue->CursorObject->hbmAlpha ?
NULL : MessageQueue->CursorObject->hbmMask,
MessageQueue->CursorObject->hbmAlpha ?
MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor,
MessageQueue->CursorObject->xHotspot,
MessageQueue->CursorObject->yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y,
MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0);
#else
GreSetPointerShape(hdcScreen,
MessageQueue->CursorObject->IconInfo.hbmMask,
@ -596,7 +601,8 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
MessageQueue->CursorObject->IconInfo.xHotspot,
MessageQueue->CursorObject->IconInfo.yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
gpsi->ptCursor.y,
0);
#endif
} else
GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
@ -616,7 +622,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
else
{
TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd));
MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON, 0);
}
}
else if (hdcScreen)
@ -669,7 +675,7 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
KeQueryTickCount(&LargeTickCount);
Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
Mesg.pt = gpsi->ptCursor;
MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type);
MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type, 0);
UserDereferenceObject(Window);
ObDereferenceObject (Thread);
@ -1246,8 +1252,11 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
}
VOID FASTCALL
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage,
DWORD MessageBits)
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
MSG* Msg,
BOOLEAN HardwareMessage,
DWORD MessageBits,
DWORD dwQEvent)
{
PUSER_MESSAGE Message;
@ -1256,7 +1265,12 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa
return;
}
if(!HardwareMessage)
if (dwQEvent)
{
InsertHeadList(&MessageQueue->PostedMessagesListHead,
&Message->ListEntry);
}
else if (!HardwareMessage)
{
InsertTailList(&MessageQueue->PostedMessagesListHead,
&Message->ListEntry);
@ -1267,7 +1281,9 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa
&Message->ListEntry);
}
Message->dwQEvent = dwQEvent;
Message->QS_Flags = MessageBits;
//Message->pti = pti; Fixed in ATI changes. See CORE-6551
MsqWakeQueue(MessageQueue, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
}

View file

@ -23,6 +23,9 @@ typedef struct _USER_MESSAGE
LIST_ENTRY ListEntry;
MSG Msg;
DWORD QS_Flags;
LONG_PTR ExtraInfo;
DWORD dwQEvent;
PTHREADINFO pti;
} USER_MESSAGE, *PUSER_MESSAGE;
struct _USER_MESSAGE_QUEUE;
@ -156,7 +159,7 @@ NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult);
PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg);
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message);
VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage, DWORD MessageBits);
VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE, MSG*, BOOLEAN, DWORD, DWORD);
VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode);
BOOLEAN APIENTRY
MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,

View file

@ -409,7 +409,7 @@ PostTimerMessages(PWND Window)
Msg.wParam = (WPARAM) pTmr->nID;
Msg.lParam = (LPARAM) pTmr->pfn;
MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER);
MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER, 0);
pTmr->flags &= ~TMRF_READY;
pti->cTimersReady++;
Hit = TRUE;

View file

@ -462,7 +462,6 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags))
{
UpdateClipOrigin = TRUE;
//bUpdateVisRgn = FALSE;
break;
}
}

View file

@ -304,6 +304,8 @@ GetUser32Handle(HANDLE handle)
INT Index;
USHORT generation;
if (!handle) return NULL;
Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
if (Index < 0 || Index >= gHandleTable->nb_handles)
@ -457,21 +459,14 @@ PWND
FASTCALL
ValidateHwnd(HWND hwnd)
{
PWND Wnd;
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
ASSERT(ClientInfo != NULL);
/* See if the window is cached */
if (hwnd == ClientInfo->CallbackWnd.hWnd)
if (hwnd && hwnd == ClientInfo->CallbackWnd.hWnd)
return ClientInfo->CallbackWnd.pWnd;
Wnd = ValidateHandle((HANDLE)hwnd, otWindow);
if (Wnd != NULL)
{
return Wnd;
}
return NULL;
return ValidateHandle((HANDLE)hwnd, otWindow);
}
//

View file

@ -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 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
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 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
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(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
{
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->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 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
((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 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
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 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
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,12 +450,65 @@ done:
/* 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
HBITMAP
BITMAP_LoadImageW(
@ -324,14 +522,17 @@ BITMAP_LoadImageW(
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 @@ BITMAP_LoadImageW(
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 @@ create_bitmap:
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 @@ end:
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 @@ CURSORICON_LoadFromFileW(
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,44 @@ CURSORICON_LoadFromFileW(
/* 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_error;
/* Clean up */
DeleteObject(ii.hbmMask);
DeleteObject(ii.hbmColor);
/* Tell win32k */
if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
{
NtUserDestroyCursor(hCurIcon, TRUE);
goto end_error;
}
end:
UnmapViewOfFile(bits);
return hRet;
return hCurIcon;
/* Clean up */
end_error:
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return NULL;
}
static
@ -733,7 +944,7 @@ CURSORICON_LoadImageW(
CURSORICONDIR* dir;
WORD wResId;
LPBYTE bits;
ICONINFO ii;
CURSORDATA cursorData;
BOOL bStatus;
UNICODE_STRING ustrRsrc;
UNICODE_STRING ustrModule = {0, 0, NULL};
@ -775,7 +986,7 @@ CURSORICON_LoadImageW(
/* 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 +994,8 @@ CURSORICON_LoadImageW(
}
if(ret < size)
{
ustrModule.Length = ret;
ustrModule.MaximumLength = size;
ustrModule.Length = ret*sizeof(WCHAR);
ustrModule.MaximumLength = size*sizeof(WCHAR);
break;
}
size *= 2;
@ -845,70 +1056,77 @@ CURSORICON_LoadImageW(
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 );
if(!bStatus)
goto done;
/* This is from resource */
cursorData.CURSORF_flags = CURSORF_FROMRESOURCE;
/* Create the handle */
hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1);
if(!hCurIcon)
{
DeleteObject(ii.hbmMask);
if(ii.hbmColor) DeleteObject(ii.hbmColor);
goto done;
goto end_error;
}
/* Tell win32k */
if(fuLoad & LR_SHARED)
bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &ii);
{
cursorData.CURSORF_flags |= CURSORF_LRSHARED;
bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData);
}
else
bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii);
bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData);
if(!bStatus)
{
NtUserDestroyCursor(hCurIcon, TRUE);
hCurIcon = NULL;
goto end_error;
}
DeleteObject(ii.hbmMask);
if(ii.hbmColor) DeleteObject(ii.hbmColor);
done:
if(ustrModule.Buffer)
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
return hCurIcon;
end_error:
if(ustrModule.Buffer)
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return NULL;
}
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 +1134,22 @@ BITMAP_CopyImage(
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 ((desiredx < 0) || (desiredy < 0)) return 0;
if (fuFlags & LR_COPYFROMRESOURCE)
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 +1163,7 @@ BITMAP_CopyImage(
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 +1176,11 @@ BITMAP_CopyImage(
memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
}
/* Get the color table or the color masks */
GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
bi->bmiHeader.biWidth = desiredx;
bi->bmiHeader.biHeight = desiredy;
bi->bmiHeader.biWidth = cxDesired;
bi->bmiHeader.biHeight = cyDesired;
bi->bmiHeader.biSizeImage = 0;
/* Get the color table or the color masks */
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 +1189,16 @@ BITMAP_CopyImage(
{
/* 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 +1232,12 @@ BITMAP_CopyImage(
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 +1278,7 @@ BITMAP_CopyImage(
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 +1286,11 @@ BITMAP_CopyImage(
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 +1301,9 @@ BITMAP_CopyImage(
DeleteDC(dc);
}
if (fuFlags & LR_COPYDELETEORG)
if (flags & LR_COPYDELETEORG)
{
DeleteObject(hbmp);
DeleteObject(hnd);
}
}
HeapFree(GetProcessHeap(), 0, bi);
@ -1114,17 +1331,17 @@ CURSORICON_CopyImage(
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 +1370,7 @@ CURSORICON_CopyImage(
{
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 +1382,7 @@ CURSORICON_CopyImage(
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 +1393,15 @@ CURSORICON_CopyImage(
} 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;
}
@ -1198,6 +1416,8 @@ CURSORICON_CopyImage(
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
HeapFree(GetProcessHeap(), 0, pvBuf);
TRACE("Returning 0x%08x.\n", ret);
return ret;
}
@ -1499,21 +1719,6 @@ int WINAPI LookupIconIdFromDirectoryEx(
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 +1731,11 @@ int WINAPI LookupIconIdFromDirectoryEx(
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 +1868,7 @@ HICON WINAPI CreateIconFromResource(
_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,36 +1881,65 @@ HICON WINAPI CreateIconFromResourceEx(
_In_ UINT uFlags
)
{
ICONINFO ii;
CURSORDATA cursorData;
HICON hIcon;
if(uFlags)
FIXME("uFlags 0x%08x ignored.\n", uFlags);
TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
if(fIcon)
if(uFlags & ~LR_DEFAULTSIZE)
FIXME("uFlags 0x%08x ignored.\n", uFlags & ~LR_DEFAULTSIZE);
if(uFlags & LR_DEFAULTSIZE)
{
ii.xHotspot = cxDesired/2;
ii.yHotspot = cyDesired/2;
if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
}
else
/* 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)
goto end_error;
/* Clean up */
DeleteObject(ii.hbmMask);
if(ii.hbmColor) DeleteObject(ii.hbmColor);
if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
{
ERR("NtUserSetCursorIconData failed.\n");
NtUserDestroyCursor(hIcon, TRUE);
goto end_error;
}
return hIcon;
/* Clean up */
end_error:
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return NULL;
}
HICON WINAPI CreateIconIndirect(
@ -1709,22 +1948,34 @@ HICON WINAPI CreateIconIndirect(
{
/* As simple as creating a handle, and let win32k deal with the bitmaps */
HICON hiconRet;
CURSORDATA cursorData;
TRACE("%p.\n", piconinfo);
hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1);
if(!hiconRet)
if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
return NULL;
if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, piconinfo))
hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1);
if(!hiconRet)
goto end_error;
if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
{
NtUserDestroyCursor(hiconRet, FALSE);
hiconRet = NULL;
goto end_error;
}
TRACE("Returning 0x%08x.\n", hiconRet);
return hiconRet;
end_error:
/* Clean up */
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return NULL;
}
HCURSOR WINAPI CreateCursor(
@ -1768,8 +2019,7 @@ BOOL WINAPI SetCursorPos(
_In_ int Y
)
{
UNIMPLEMENTED;
return FALSE;
return NtUserxSetCursorPos(X,Y);
}
BOOL WINAPI GetCursorPos(
@ -1783,14 +2033,12 @@ int WINAPI ShowCursor(
_In_ BOOL bShow
)
{
UNIMPLEMENTED;
return -1;
return NtUserxShowCursor(bShow);
}
HCURSOR WINAPI GetCursor(void)
{
UNIMPLEMENTED;
return NULL;
return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR);
}
BOOL WINAPI DestroyCursor(

View file

@ -380,8 +380,11 @@ SVC_(UserEnumDisplaySettings, 4)
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)