2003-11-10 17:44:50 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2005-01-03 00:46:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We handle two types of cursors/icons:
|
|
|
|
* - Private
|
|
|
|
* Loaded without LR_SHARED flag
|
|
|
|
* Private to a process
|
|
|
|
* Can be deleted by calling NtDestroyCursorIcon()
|
|
|
|
* CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc set to NULL
|
|
|
|
* - Shared
|
|
|
|
* Loaded with LR_SHARED flag
|
|
|
|
* Possibly shared by multiple processes
|
|
|
|
* Immune to NtDestroyCursorIcon()
|
|
|
|
* CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc are valid
|
|
|
|
* There's a M:N relationship between processes and (shared) cursor/icons.
|
|
|
|
* A process can have multiple cursor/icons and a cursor/icon can be used
|
|
|
|
* by multiple processes. To keep track of this we keep a list of all
|
|
|
|
* cursor/icons (CurIconList) and per cursor/icon we keep a list of
|
|
|
|
* CURICON_PROCESS structs starting at CurIcon->ProcessList.
|
|
|
|
*/
|
|
|
|
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2005-06-29 07:09:25 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
static PAGED_LOOKASIDE_LIST gProcessLookasideList;
|
|
|
|
static LIST_ENTRY gCurIconList;
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-01-27 00:49:24 +00:00
|
|
|
/* Look up the location of the cursor in the GDIDEVICE structure
|
|
|
|
* when all we know is the window station object
|
|
|
|
* Actually doesn't use the window station, but should... */
|
|
|
|
BOOL FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntGetCursorLocation(PWINSTATION_OBJECT WinSta, POINT *loc)
|
2005-01-27 00:49:24 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
HDC hDC;
|
|
|
|
PDC dc;
|
|
|
|
GDIDEVICE *GDIDevice;
|
2005-01-27 00:49:24 +00:00
|
|
|
|
|
|
|
#if 1
|
2005-09-07 21:25:42 +00:00
|
|
|
/* FIXME - get the screen dc from the window station or desktop */
|
|
|
|
if (!(hDC = IntGetScreenDC()))
|
|
|
|
return FALSE;
|
2005-01-27 00:49:24 +00:00
|
|
|
#endif
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (!(dc = DC_LockDc(hDC)))
|
|
|
|
return FALSE;
|
|
|
|
GDIDevice = (GDIDEVICE *)dc->GDIDevice;
|
|
|
|
DC_UnlockDc(dc);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
loc->x = GDIDevice->Pointer.Pos.x;
|
|
|
|
loc->y = GDIDevice->Pointer.Pos.y;
|
2005-01-27 00:49:24 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return TRUE;
|
2005-01-27 00:49:24 +00:00
|
|
|
}
|
|
|
|
|
2004-05-14 23:57:32 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
|
2005-09-07 20:59:26 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
2005-09-08 16:18:51 +00:00
|
|
|
|
2005-09-19 00:02:39 +00:00
|
|
|
if (!hCurIcon)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-09-08 16:18:51 +00:00
|
|
|
|
2006-04-05 08:05:55 +00:00
|
|
|
CurIcon = (PCURICON_OBJECT)UserGetObject(gHandleTable, hCurIcon, otCursorIcon);
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!CurIcon)
|
2004-05-14 23:57:32 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
/* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
|
2005-09-07 20:59:26 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
2004-05-14 23:57:32 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ASSERT(USER_BODY_TO_HEADER(CurIcon)->RefCount >= 0);
|
|
|
|
return CurIcon;
|
2005-09-07 20:59:26 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
|
2005-09-08 16:18:51 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
#define COLORCURSORS_ALLOWED FALSE
|
|
|
|
HCURSOR FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
|
2005-09-07 21:25:42 +00:00
|
|
|
BOOL ForceChange)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj;
|
2004-04-09 20:03:21 +00:00
|
|
|
SURFOBJ *SurfObj;
|
2004-01-24 19:47:05 +00:00
|
|
|
PDEVINFO DevInfo;
|
2004-07-03 13:55:37 +00:00
|
|
|
PBITMAPOBJ MaskBmpObj = NULL;
|
2004-01-24 19:47:05 +00:00
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
PCURICON_OBJECT OldCursor;
|
|
|
|
HCURSOR Ret = (HCURSOR)0;
|
2004-12-12 01:40:39 +00:00
|
|
|
HBITMAP dcbmp, hColor = (HBITMAP)0;
|
2004-07-04 11:18:56 +00:00
|
|
|
HBITMAP hMask = 0;
|
2004-04-09 20:03:21 +00:00
|
|
|
SURFOBJ *soMask = NULL, *soColor = NULL;
|
|
|
|
XLATEOBJ *XlateObj = NULL;
|
2004-02-27 10:08:21 +00:00
|
|
|
HDC Screen;
|
2006-01-08 23:26:03 +00:00
|
|
|
PDC dc;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurInfo = IntGetSysCursorInfo(WinSta);
|
2004-01-24 19:47:05 +00:00
|
|
|
OldCursor = CurInfo->CurrentCursorObject;
|
|
|
|
if (OldCursor)
|
|
|
|
{
|
|
|
|
Ret = (HCURSOR)OldCursor->Self;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
if (!ForceChange && OldCursor == NewCursor)
|
|
|
|
{
|
|
|
|
return Ret;
|
|
|
|
}
|
2004-12-12 01:40:39 +00:00
|
|
|
else
|
2004-01-24 19:47:05 +00:00
|
|
|
{
|
2004-02-27 10:08:21 +00:00
|
|
|
if(!(Screen = IntGetScreenDC()))
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
return (HCURSOR)0;
|
2004-02-27 10:08:21 +00:00
|
|
|
}
|
2004-01-24 19:47:05 +00:00
|
|
|
/* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
|
2006-01-08 23:26:03 +00:00
|
|
|
dc = DC_LockDc(Screen);
|
2004-01-24 19:47:05 +00:00
|
|
|
|
|
|
|
if (!dc)
|
|
|
|
{
|
|
|
|
return Ret;
|
|
|
|
}
|
2004-12-12 01:40:39 +00:00
|
|
|
dcbmp = dc->w.hBitmap;
|
2004-01-24 19:47:05 +00:00
|
|
|
DevInfo = dc->DevInfo;
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-12-12 01:40:39 +00:00
|
|
|
BitmapObj = BITMAPOBJ_LockBitmap(dcbmp);
|
2004-12-18 23:55:26 +00:00
|
|
|
if ( !BitmapObj )
|
2005-09-07 21:25:42 +00:00
|
|
|
return (HCURSOR)0;
|
2004-12-12 01:40:39 +00:00
|
|
|
SurfObj = &BitmapObj->SurfObj;
|
2004-12-18 23:55:26 +00:00
|
|
|
ASSERT(SurfObj);
|
2004-01-24 19:47:05 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
if (!NewCursor && (CurInfo->CurrentCursorObject || ForceChange))
|
|
|
|
{
|
2004-02-10 23:40:01 +00:00
|
|
|
if (NULL != CurInfo->CurrentCursorObject && CurInfo->ShowingCursor)
|
|
|
|
{
|
|
|
|
/* Remove the cursor if it was displayed */
|
2005-06-20 08:31:48 +00:00
|
|
|
IntEngMovePointer(SurfObj, -1, -1, &GDIDEV(SurfObj)->Pointer.Exclude);
|
2004-02-10 23:40:01 +00:00
|
|
|
}
|
|
|
|
|
2004-12-12 01:40:39 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE;
|
2004-02-10 23:40:01 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
|
|
|
|
CurInfo->ShowingCursor = 0;
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-01-24 19:47:05 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
if (!NewCursor)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-01-24 19:47:05 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
2003-12-13 19:53:17 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
/* TODO: Fixme. Logic is screwed above */
|
2003-12-13 19:53:17 +00:00
|
|
|
|
2004-01-24 19:47:05 +00:00
|
|
|
ASSERT(NewCursor);
|
|
|
|
MaskBmpObj = BITMAPOBJ_LockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
if (MaskBmpObj)
|
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
const int maskBpp = BitsPerFormat(MaskBmpObj->SurfObj.iBitmapFormat);
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(MaskBmpObj);
|
2004-01-24 19:47:05 +00:00
|
|
|
if (maskBpp != 1)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2004-07-07 08:39:54 +00:00
|
|
|
DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-01-24 19:47:05 +00:00
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
|
|
|
if ((DevInfo->flGraphicsCaps2 & GCAPS2_ALPHACURSOR) &&
|
2005-09-07 21:25:42 +00:00
|
|
|
SurfObj->iBitmapFormat >= BMF_16BPP &&
|
|
|
|
SurfObj->iBitmapFormat <= BMF_32BPP &&
|
|
|
|
NewCursor->Shadow && COLORCURSORS_ALLOWED)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
/* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
|
|
|
|
Do not pass a mask bitmap to DrvSetPointerShape()!
|
|
|
|
Create a XLATEOBJ that describes the colors of the bitmap. */
|
|
|
|
DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
if(NewCursor->IconInfo.hbmColor
|
|
|
|
&& COLORCURSORS_ALLOWED)
|
|
|
|
{
|
|
|
|
/* FIXME - Create a color pointer, create only one 32bit bitmap!
|
|
|
|
Do not pass a mask bitmap to DrvSetPointerShape()!
|
|
|
|
Create a XLATEOBJ that describes the colors of the bitmap.
|
|
|
|
(16bit bitmaps are propably allowed) */
|
|
|
|
DPRINT1("SetCursor: Cursors with colors are not supported!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MaskBmpObj = BITMAPOBJ_LockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
if(MaskBmpObj)
|
2004-12-18 23:55:26 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
RECTL DestRect = {0, 0, MaskBmpObj->SurfObj.sizlBitmap.cx, MaskBmpObj->SurfObj.sizlBitmap.cy};
|
|
|
|
POINTL SourcePoint = {0, 0};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: For now we create the cursor in top-down bitmap,
|
|
|
|
* because VMware driver rejects it otherwise. This should
|
|
|
|
* be fixed later.
|
|
|
|
*/
|
|
|
|
hMask = EngCreateBitmap(
|
|
|
|
MaskBmpObj->SurfObj.sizlBitmap, abs(MaskBmpObj->SurfObj.lDelta),
|
|
|
|
MaskBmpObj->SurfObj.iBitmapFormat, BMF_TOPDOWN,
|
|
|
|
NULL);
|
|
|
|
if ( !hMask )
|
|
|
|
{
|
|
|
|
BITMAPOBJ_UnlockBitmap(MaskBmpObj);
|
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
|
|
|
return (HCURSOR)0;
|
|
|
|
}
|
|
|
|
soMask = EngLockSurface((HSURF)hMask);
|
|
|
|
EngCopyBits(soMask, &MaskBmpObj->SurfObj, NULL, NULL,
|
|
|
|
&DestRect, &SourcePoint);
|
|
|
|
BITMAPOBJ_UnlockBitmap(MaskBmpObj);
|
2004-12-18 23:55:26 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
CurInfo->ShowingCursor = CURSOR_SHOWING;
|
|
|
|
CurInfo->CurrentCursorObject = NewCursor;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
CurInfo->ShowingCursor = 0;
|
|
|
|
CurInfo->CurrentCursorObject = NULL;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (GDIDEVFUNCS(SurfObj).SetPointerShape)
|
|
|
|
{
|
2004-12-12 01:40:39 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.Status =
|
2004-07-03 13:55:37 +00:00
|
|
|
GDIDEVFUNCS(SurfObj).SetPointerShape(
|
2005-09-07 21:25:42 +00:00
|
|
|
SurfObj, soMask, soColor, XlateObj,
|
|
|
|
NewCursor->IconInfo.xHotspot,
|
|
|
|
NewCursor->IconInfo.yHotspot,
|
|
|
|
GDIDEV(SurfObj)->Pointer.Pos.x,
|
|
|
|
GDIDEV(SurfObj)->Pointer.Pos.y,
|
|
|
|
&(GDIDEV(SurfObj)->Pointer.Exclude),
|
|
|
|
SPS_CHANGE);
|
2004-07-04 11:18:56 +00:00
|
|
|
DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
|
2005-09-07 21:25:42 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.Status);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-12-12 01:40:39 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.Status = SPS_DECLINE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-01-17 15:21:09 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(GDIDEV(SurfObj)->Pointer.Status == SPS_DECLINE)
|
|
|
|
{
|
2004-12-12 01:40:39 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.Status = EngSetPointerShape(
|
2005-09-07 21:25:42 +00:00
|
|
|
SurfObj, soMask, soColor, XlateObj,
|
|
|
|
NewCursor->IconInfo.xHotspot,
|
|
|
|
NewCursor->IconInfo.yHotspot,
|
|
|
|
GDIDEV(SurfObj)->Pointer.Pos.x,
|
|
|
|
GDIDEV(SurfObj)->Pointer.Pos.y,
|
|
|
|
&(GDIDEV(SurfObj)->Pointer.Exclude),
|
|
|
|
SPS_CHANGE);
|
2005-06-20 08:31:48 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.MovePointer = NULL;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-12-12 01:40:39 +00:00
|
|
|
GDIDEV(SurfObj)->Pointer.MovePointer = GDIDEVFUNCS(SurfObj).MovePointer;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
|
|
|
if(hMask)
|
|
|
|
{
|
2004-07-04 11:18:56 +00:00
|
|
|
EngUnlockSurface(soMask);
|
|
|
|
EngDeleteSurface((HSURF)hMask);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
if(hColor)
|
|
|
|
{
|
2004-04-09 20:03:21 +00:00
|
|
|
EngDeleteSurface((HSURF)hColor);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
if(XlateObj)
|
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
EngDeleteXlate(XlateObj);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(GDIDEV(SurfObj)->Pointer.Status == SPS_ERROR)
|
2004-07-07 08:39:54 +00:00
|
|
|
DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntSetupCurIconHandles(PWINSTATION_OBJECT WinSta)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ExInitializePagedLookasideList(&gProcessLookasideList,
|
2005-09-07 21:25:42 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
sizeof(CURICON_PROCESS),
|
|
|
|
0,
|
|
|
|
128);
|
2005-09-09 00:25:52 +00:00
|
|
|
InitializeListHead(&gCurIconList);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2005-01-03 00:46:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We have to register that this object is in use by the current
|
|
|
|
* process. The only way to do that seems to be to walk the list
|
|
|
|
* of cursor/icon objects starting at W32Process->CursorIconListHead.
|
|
|
|
* If the object is already present in the list, we don't have to do
|
|
|
|
* anything, if it's not present we add it and inc the ProcessCount
|
|
|
|
* in the object. Having to walk the list kind of sucks, but that's
|
|
|
|
* life...
|
|
|
|
*/
|
|
|
|
static BOOLEAN FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
|
2005-01-03 00:46:42 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PW32PROCESS Win32Process;
|
|
|
|
PCURICON_PROCESS Current;
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
Win32Process = PsGetCurrentProcessWin32Process();
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-24 02:50:02 +00:00
|
|
|
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-01-03 00:46:42 +00:00
|
|
|
if (Current->Process == Win32Process)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Already registered for this process */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Not registered yet */
|
2005-09-09 00:25:52 +00:00
|
|
|
Current = ExAllocateFromPagedLookasideList(&gProcessLookasideList);
|
2005-09-07 21:25:42 +00:00
|
|
|
if (NULL == Current)
|
|
|
|
{
|
2005-01-03 00:46:42 +00:00
|
|
|
return FALSE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
InsertHeadList(&CurIcon->ProcessList, &Current->ListEntry);
|
2005-09-07 21:25:42 +00:00
|
|
|
Current->Process = Win32Process;
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return TRUE;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PCURICON_OBJECT FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
|
2003-12-09 20:58:16 +00:00
|
|
|
HRSRC hRsrc, LONG cx, LONG cy)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-24 02:50:02 +00:00
|
|
|
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
|
2005-09-09 00:25:52 +00:00
|
|
|
// ObmReferenceObject( CurIcon);
|
|
|
|
// {
|
|
|
|
if((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
|
2005-01-03 00:46:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
if(cx && ((cx != CurIcon->Size.cx) || (cy != CurIcon->Size.cy)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
// ObmDereferenceObject(CurIcon);
|
|
|
|
continue;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
if (! ReferenceCurIconByProcess(CurIcon))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CurIcon;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
// }
|
|
|
|
// ObmDereferenceObject(CurIcon);
|
2005-09-07 20:59:26 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return NULL;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PCURICON_OBJECT FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
HANDLE hCurIcon;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2006-04-05 08:05:55 +00:00
|
|
|
CurIcon = ObmCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!CurIcon)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->Self = hCurIcon;
|
|
|
|
InitializeListHead(&CurIcon->ProcessList);
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (! ReferenceCurIconByProcess(CurIcon))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Failed to add process\n");
|
2005-09-09 00:25:52 +00:00
|
|
|
ObmDeleteObject(hCurIcon, otCursorIcon);
|
|
|
|
ObmDereferenceObject(CurIcon);
|
2005-09-07 21:25:42 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
InsertHeadList(&gCurIconList, &CurIcon->ListEntry);
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObmDereferenceObject(CurIcon);
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
return CurIcon;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2005-01-03 00:46:42 +00:00
|
|
|
BOOLEAN FASTCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
HBITMAP bmpMask, bmpColor;
|
|
|
|
BOOLEAN Ret;
|
|
|
|
PCURICON_PROCESS Current = NULL;
|
2006-07-20 14:53:47 +00:00
|
|
|
PW32PROCESS W32Process = PsGetCurrentProcessWin32Process();
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* Private objects can only be destroyed by their own process */
|
2005-09-09 00:25:52 +00:00
|
|
|
if (NULL == CurIcon->hModule)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ASSERT(CurIcon->ProcessList.Flink->Flink == &CurIcon->ProcessList);
|
|
|
|
Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS, ListEntry);
|
2005-09-07 21:25:42 +00:00
|
|
|
if (Current->Process != W32Process)
|
2005-01-03 00:46:42 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT1("Trying to destroy private icon/cursor of another process\n");
|
|
|
|
return FALSE;
|
2005-01-03 00:46:42 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (! ProcessCleanup)
|
|
|
|
{
|
2005-01-03 00:46:42 +00:00
|
|
|
DPRINT("Trying to destroy shared icon/cursor\n");
|
|
|
|
return FALSE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now find this process in the list of processes referencing this object and
|
|
|
|
remove it from that list */
|
2005-09-24 02:50:02 +00:00
|
|
|
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
if (Current->Process == W32Process)
|
2005-01-03 00:46:42 +00:00
|
|
|
{
|
2005-09-24 02:50:02 +00:00
|
|
|
RemoveEntryList(&Current->ListEntry);
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
2005-01-03 00:46:42 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-24 02:50:02 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ExFreeToPagedLookasideList(&gProcessLookasideList, Current);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* If there are still processes referencing this object we can't destroy it yet */
|
2005-09-09 00:25:52 +00:00
|
|
|
if (! IsListEmpty(&CurIcon->ProcessList))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (! ProcessCleanup)
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
RemoveEntryList(&CurIcon->ListEntry);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurInfo = IntGetSysCursorInfo(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (CurInfo->CurrentCursorObject == CurIcon)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Hide the cursor if we're destroying the current cursor */
|
2005-09-09 00:25:52 +00:00
|
|
|
IntSetCursor(WinSta, NULL, TRUE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
bmpMask = CurIcon->IconInfo.hbmMask;
|
|
|
|
bmpColor = CurIcon->IconInfo.hbmColor;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
Ret = ObmDeleteObject(CurIcon->Self, otCursorIcon);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* delete bitmaps */
|
|
|
|
if(bmpMask)
|
|
|
|
{
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, bmpMask, PsGetCurrentProcess());
|
2005-09-07 21:25:42 +00:00
|
|
|
NtGdiDeleteObject(bmpMask);
|
|
|
|
}
|
|
|
|
if(bmpColor)
|
|
|
|
{
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, bmpColor, PsGetCurrentProcess());
|
2005-09-07 21:25:42 +00:00
|
|
|
NtGdiDeleteObject(bmpColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2003-12-13 22:38:29 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-24 02:50:02 +00:00
|
|
|
PCURICON_OBJECT CurIcon, tmp;
|
2005-09-07 21:25:42 +00:00
|
|
|
PCURICON_PROCESS ProcessData;
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2005-01-03 00:46:42 +00:00
|
|
|
|
2005-09-24 02:50:02 +00:00
|
|
|
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
// ObmReferenceObject(CurIcon);
|
2005-09-07 21:25:42 +00:00
|
|
|
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
|
2005-01-03 00:46:42 +00:00
|
|
|
{
|
2005-09-24 02:50:02 +00:00
|
|
|
LIST_FOR_EACH(ProcessData, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
if (Win32Process == ProcessData->Process)
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
RemoveEntryList(&CurIcon->ListEntry);
|
|
|
|
IntDestroyCurIconObject(WinSta, CurIcon, TRUE);
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-09-05 23:11:41 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
// ObmDereferenceObject(Object);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-07 20:59:26 +00:00
|
|
|
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2003-12-13 22:38:29 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE
|
2003-11-10 17:44:50 +00:00
|
|
|
STDCALL
|
2005-09-09 00:25:52 +00:00
|
|
|
NtUserCreateCursorIconHandle(PICONINFO IconInfo OPTIONAL, BOOL Indirect)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
PBITMAPOBJ bmp;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE Ret;
|
|
|
|
DECLARE_RETURN(HANDLE);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserCreateCursorIconHandle\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( (HANDLE)0);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!(CurIcon = IntCreateCurIconHandle(WinSta)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( (HANDLE)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = CurIcon->Self;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(IconInfo)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&CurIcon->IconInfo, IconInfo, sizeof(ICONINFO));
|
|
|
|
if(NT_SUCCESS(Status))
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
if(Indirect)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->IconInfo.hbmMask = BITMAPOBJ_CopyBitmap(CurIcon->IconInfo.hbmMask);
|
|
|
|
CurIcon->IconInfo.hbmColor = BITMAPOBJ_CopyBitmap(CurIcon->IconInfo.hbmColor);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
if(CurIcon->IconInfo.hbmColor &&
|
|
|
|
(bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
|
|
|
|
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy;
|
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmColor, NULL);
|
2005-09-09 00:25:52 +00:00
|
|
|
}
|
|
|
|
if(CurIcon->IconInfo.hbmMask &&
|
|
|
|
(bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmMask)))
|
|
|
|
{
|
|
|
|
if (CurIcon->IconInfo.hbmColor == NULL)
|
|
|
|
{
|
|
|
|
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
|
|
|
|
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2;
|
|
|
|
}
|
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
/* FIXME - Don't exit here */
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( Ret);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserCreateCursorIconHandle, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
2003-12-09 20:58:16 +00:00
|
|
|
NtUserGetCursorIconInfo(
|
2005-09-09 00:25:52 +00:00
|
|
|
HANDLE hCurIcon,
|
2005-09-07 21:25:42 +00:00
|
|
|
PICONINFO IconInfo)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ICONINFO ii;
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetCursorIconInfo\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!IconInfo)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
RETURN(FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
|
|
|
{
|
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
/* Copy bitmaps */
|
|
|
|
ii.hbmMask = BITMAPOBJ_CopyBitmap(ii.hbmMask);
|
|
|
|
ii.hbmColor = BITMAPOBJ_CopyBitmap(ii.hbmColor);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyToCaller(IconInfo, &ii, sizeof(ICONINFO));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
Ret = TRUE;
|
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( Ret);
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetCursorIconInfo, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
2003-12-09 20:58:16 +00:00
|
|
|
NtUserGetCursorIconSize(
|
2005-09-09 00:25:52 +00:00
|
|
|
HANDLE hCurIcon,
|
2005-09-07 21:25:42 +00:00
|
|
|
BOOL *fIcon,
|
|
|
|
SIZE *Size)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
2005-09-07 21:25:42 +00:00
|
|
|
PBITMAPOBJ bmp;
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
SIZE SafeSize;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetCursorIconSize\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyToCaller(fIcon, &CurIcon->IconInfo.fIcon, sizeof(BOOL));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor);
|
|
|
|
if(!bmp)
|
|
|
|
goto done;
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
SafeSize.cx = bmp->SurfObj.sizlBitmap.cx;
|
|
|
|
SafeSize.cy = bmp->SurfObj.sizlBitmap.cy;
|
|
|
|
Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
Ret = TRUE;
|
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
done:
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( Ret);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetCursorIconSize, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2003-06-03 22:26:52 +00:00
|
|
|
DWORD
|
|
|
|
STDCALL
|
|
|
|
NtUserGetCursorFrameInfo(
|
2005-09-07 21:25:42 +00:00
|
|
|
DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
UNIMPLEMENTED
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return 0;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserGetCursorInfo(
|
2005-09-07 21:25:42 +00:00
|
|
|
PCURSORINFO pci)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
CURSORINFO SafeCi;
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
2006-01-08 23:26:03 +00:00
|
|
|
HDC hDC;
|
2005-09-07 21:25:42 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
2005-09-05 21:19:23 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Enter NtUserGetCursorInfo\n");
|
|
|
|
UserEnterExclusive();
|
2005-01-27 00:49:24 +00:00
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* FIXME - get the screen dc from the window station or desktop */
|
|
|
|
if (!(hDC = IntGetScreenDC()))
|
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
2005-01-27 00:49:24 +00:00
|
|
|
#endif
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Status = MmCopyFromCaller(&SafeCi.cbSize, pci, sizeof(DWORD));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(SafeCi.cbSize != sizeof(CURSORINFO))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurInfo = IntGetSysCursorInfo(WinSta);
|
|
|
|
CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
SafeCi.flags = ((CurInfo->ShowingCursor && CurIcon) ? CURSOR_SHOWING : 0);
|
|
|
|
SafeCi.hCursor = (CurIcon ? (HCURSOR)CurIcon->Self : (HCURSOR)0);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
IntGetCursorLocation(WinSta, &SafeCi.ptScreenPos);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
Status = MmCopyToCaller(pci, &SafeCi, sizeof(CURSORINFO));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
RETURN( TRUE);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetCursorInfo, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-08-24 01:12:16 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserClipCursor(
|
2005-09-07 21:25:42 +00:00
|
|
|
RECT *UnsafeRect)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
/* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
RECT Rect;
|
|
|
|
PWINDOW_OBJECT DesktopWindow = NULL;
|
2005-09-27 10:52:10 +00:00
|
|
|
POINT MousePos = {0};
|
2005-09-07 21:25:42 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserClipCursor\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if (WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurInfo = IntGetSysCursorInfo(WinSta);
|
|
|
|
IntGetCursorLocation(WinSta, &MousePos);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(WinSta->ActiveDesktop)
|
|
|
|
DesktopWindow = UserGetWindowObject(WinSta->ActiveDesktop->DesktopWindow);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
if((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
|
|
|
|
&& DesktopWindow && UnsafeRect != NULL)
|
|
|
|
{
|
|
|
|
MOUSEINPUT mi;
|
|
|
|
|
|
|
|
CurInfo->CursorClipInfo.IsClipped = TRUE;
|
|
|
|
CurInfo->CursorClipInfo.Left = max(Rect.left, DesktopWindow->WindowRect.left);
|
|
|
|
CurInfo->CursorClipInfo.Top = max(Rect.top, DesktopWindow->WindowRect.top);
|
|
|
|
CurInfo->CursorClipInfo.Right = min(Rect.right - 1, DesktopWindow->WindowRect.right - 1);
|
|
|
|
CurInfo->CursorClipInfo.Bottom = min(Rect.bottom - 1, DesktopWindow->WindowRect.bottom - 1);
|
|
|
|
|
|
|
|
mi.dx = MousePos.x;
|
|
|
|
mi.dy = MousePos.y;
|
|
|
|
mi.mouseData = 0;
|
|
|
|
mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
|
|
|
mi.time = 0;
|
|
|
|
mi.dwExtraInfo = 0;
|
|
|
|
IntMouseInput(&mi);
|
|
|
|
|
|
|
|
RETURN( TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
CurInfo->CursorClipInfo.IsClipped = FALSE;
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
RETURN( TRUE);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
2003-12-09 20:58:16 +00:00
|
|
|
NtUserDestroyCursorIcon(
|
2005-09-09 00:25:52 +00:00
|
|
|
HANDLE hCurIcon,
|
2005-09-07 21:25:42 +00:00
|
|
|
DWORD Unknown)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
BOOL ret;
|
2005-09-07 21:25:42 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserDestroyCursorIcon\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
RETURN(FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ret = IntDestroyCurIconObject(WinSta, CurIcon, FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN(ret);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
2004-04-09 20:03:21 +00:00
|
|
|
HICON
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserFindExistingCursorIcon(
|
2005-09-07 21:25:42 +00:00
|
|
|
HMODULE hModule,
|
|
|
|
HRSRC hRsrc,
|
|
|
|
LONG cx,
|
|
|
|
LONG cy)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
HANDLE Ret = (HANDLE)0;
|
|
|
|
DECLARE_RETURN(HICON);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserFindExistingCursorIcon\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( Ret);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon = IntFindExistingCurIconObject(WinSta, hModule, hRsrc, cx, cy);
|
|
|
|
if(CurIcon)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
Ret = CurIcon->Self;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
// IntReleaseCurIconObject(CurIcon);//faxme: is this correct? does IntFindExistingCurIconObject add a ref?
|
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
RETURN( Ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
RETURN( (HANDLE)0);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserFindExistingCursorIcon, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-08-24 01:12:16 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserGetClipCursor(
|
2005-09-07 21:25:42 +00:00
|
|
|
RECT *lpRect)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
/* FIXME - check if process has WINSTA_READATTRIBUTES */
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
RECT Rect;
|
|
|
|
NTSTATUS Status;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetClipCursor\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
if(!lpRect)
|
|
|
|
RETURN( FALSE);
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if (WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurInfo = IntGetSysCursorInfo(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
if(CurInfo->CursorClipInfo.IsClipped)
|
|
|
|
{
|
|
|
|
Rect.left = CurInfo->CursorClipInfo.Left;
|
|
|
|
Rect.top = CurInfo->CursorClipInfo.Top;
|
|
|
|
Rect.right = CurInfo->CursorClipInfo.Right;
|
|
|
|
Rect.bottom = CurInfo->CursorClipInfo.Bottom;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Rect.left = 0;
|
|
|
|
Rect.top = 0;
|
|
|
|
Rect.right = UserGetSystemMetrics(SM_CXSCREEN);
|
|
|
|
Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyToCaller((PRECT)lpRect, &Rect, sizeof(RECT));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
RETURN( TRUE);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetClipCursor, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-12-09 20:58:16 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
HCURSOR
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserSetCursor(
|
2005-09-07 21:25:42 +00:00
|
|
|
HCURSOR hCursor)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
HICON OldCursor;
|
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
DECLARE_RETURN(HCURSOR);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserSetCursor\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
RETURN(NULL);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
|
|
|
|
if(!(CurIcon = UserGetCurIconObject(hCursor)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN(NULL);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
|
|
|
|
OldCursor = IntSetCursor(WinSta, CurIcon, FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
|
|
|
|
RETURN(OldCursor);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserSetCursor, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
2003-11-10 17:44:50 +00:00
|
|
|
NtUserSetCursorIconContents(
|
2005-09-09 00:25:52 +00:00
|
|
|
HANDLE hCurIcon,
|
2005-09-07 21:25:42 +00:00
|
|
|
PICONINFO IconInfo)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
2005-09-07 21:25:42 +00:00
|
|
|
PBITMAPOBJ bmp;
|
2005-09-09 00:25:52 +00:00
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserSetCursorIconContents\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN(FALSE);
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyFromCaller(&CurIcon->IconInfo, IconInfo, sizeof(ICONINFO));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor);
|
|
|
|
if(bmp)
|
|
|
|
{
|
|
|
|
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
|
|
|
|
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy;
|
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmColor, NULL);
|
2005-09-09 00:25:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmMask);
|
|
|
|
if(!bmp)
|
|
|
|
goto done;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
|
|
|
|
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
2006-04-01 15:25:40 +00:00
|
|
|
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
|
2005-09-09 00:25:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ret = TRUE;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
done:
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( Ret);
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserSetCursorIconContents, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @implemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserSetCursorIconData(
|
2005-09-09 00:25:52 +00:00
|
|
|
HANDLE hCurIcon,
|
2005-09-07 21:25:42 +00:00
|
|
|
PBOOL fIcon,
|
|
|
|
POINT *Hotspot,
|
|
|
|
HMODULE hModule,
|
|
|
|
HRSRC hRsrc,
|
|
|
|
HRSRC hGroupRsrc)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
PCURICON_OBJECT CurIcon;
|
|
|
|
PWINSTATION_OBJECT WinSta;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
POINT SafeHotspot;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserSetCursorIconData\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
WinSta = IntGetWinStaObj();
|
|
|
|
if(WinSta == NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN(FALSE);
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->hModule = hModule;
|
|
|
|
CurIcon->hRsrc = hRsrc;
|
|
|
|
CurIcon->hGroupRsrc = hGroupRsrc;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
/* Copy fields */
|
|
|
|
if(fIcon)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
|
|
|
|
if(!NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
2003-11-18 19:59:51 +00:00
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!Hotspot)
|
|
|
|
Ret = TRUE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(Hotspot)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
|
|
|
|
if(NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-09 00:25:52 +00:00
|
|
|
CurIcon->IconInfo.xHotspot = SafeHotspot.x;
|
|
|
|
CurIcon->IconInfo.yHotspot = SafeHotspot.y;
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Ret = TRUE;
|
|
|
|
}
|
2005-09-09 00:25:52 +00:00
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!fIcon && !Hotspot)
|
|
|
|
{
|
|
|
|
Ret = TRUE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
done:
|
|
|
|
ObDereferenceObject(WinSta);
|
|
|
|
RETURN( Ret);
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
|
|
|
|
2003-08-23 20:59:08 +00:00
|
|
|
|
|
|
|
/*
|
2003-11-10 17:44:50 +00:00
|
|
|
* @unimplemented
|
2003-08-23 20:59:08 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserSetSystemCursor(
|
2005-09-07 21:25:42 +00:00
|
|
|
HCURSOR hcur,
|
|
|
|
DWORD id)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
return FALSE;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
|
2005-10-24 21:57:32 +00:00
|
|
|
#define STRETCH_CAN_SRCCOPY_ONLY
|
|
|
|
|
|
|
|
#ifdef STRETCH_CAN_SRCCOPY_ONLY
|
|
|
|
void
|
|
|
|
FASTCALL
|
|
|
|
DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest,
|
|
|
|
HDC DcSrc, int XSrc, int YSrc, int WidthSrc, int HeightSrc,
|
|
|
|
DWORD Rop3, BOOL Color)
|
|
|
|
{
|
|
|
|
HDC DcStretched;
|
|
|
|
HBITMAP BitmapStretched;
|
|
|
|
HBITMAP OldBitmap;
|
|
|
|
|
|
|
|
if (WidthDest == WidthSrc && HeightDest == HeightSrc)
|
|
|
|
{
|
|
|
|
NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
|
2005-12-28 20:31:44 +00:00
|
|
|
DcSrc, XSrc, YSrc, Rop3, 0, 0);
|
2005-10-24 21:57:32 +00:00
|
|
|
}
|
|
|
|
else if (SRCCOPY == Rop3)
|
|
|
|
{
|
|
|
|
NtGdiStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
|
|
|
|
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
|
2005-12-28 20:31:44 +00:00
|
|
|
Rop3, 0);
|
2005-10-24 21:57:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DcStretched = NtGdiCreateCompatibleDC(DcSrc);
|
|
|
|
if (NULL == DcStretched)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to create compatible DC\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Color)
|
|
|
|
{
|
|
|
|
BitmapStretched = NtGdiCreateCompatibleBitmap(DcDest, WidthDest,
|
|
|
|
HeightDest);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-14 23:22:07 +00:00
|
|
|
BitmapStretched = IntGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
|
2005-10-24 21:57:32 +00:00
|
|
|
}
|
|
|
|
if (NULL == BitmapStretched)
|
|
|
|
{
|
2006-01-07 01:06:48 +00:00
|
|
|
NtGdiDeleteObjectApp(DcStretched);
|
2005-10-24 21:57:32 +00:00
|
|
|
DPRINT1("Failed to create temporary bitmap\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
OldBitmap = NtGdiSelectObject(DcStretched, BitmapStretched);
|
|
|
|
if (NULL == OldBitmap)
|
|
|
|
{
|
|
|
|
NtGdiDeleteObject(BitmapStretched);
|
2006-01-07 01:06:48 +00:00
|
|
|
NtGdiDeleteObjectApp(DcStretched);
|
2005-10-24 21:57:32 +00:00
|
|
|
DPRINT1("Failed to create temporary bitmap\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (! NtGdiStretchBlt(DcStretched, 0, 0, WidthDest, HeightDest,
|
|
|
|
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
|
2005-12-28 20:31:44 +00:00
|
|
|
SRCCOPY, 0) ||
|
2005-10-24 21:57:32 +00:00
|
|
|
! NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
|
2005-12-28 20:31:44 +00:00
|
|
|
DcStretched, 0, 0, Rop3, 0, 0))
|
2005-10-24 21:57:32 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Failed to blt\n");
|
|
|
|
}
|
|
|
|
NtGdiSelectObject(DcStretched, OldBitmap);
|
|
|
|
NtGdiDeleteObject(BitmapStretched);
|
2006-01-07 01:06:48 +00:00
|
|
|
NtGdiDeleteObjectApp(DcStretched);
|
2005-10-24 21:57:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \
|
|
|
|
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \
|
|
|
|
NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \
|
|
|
|
(DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \
|
2005-12-28 20:31:44 +00:00
|
|
|
(Rop3), 0)
|
2005-10-24 21:57:32 +00:00
|
|
|
#endif /* STRETCH_CAN_SRCCOPY_ONLY */
|
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
BOOL
|
|
|
|
UserDrawIconEx(
|
|
|
|
HDC hDc,
|
|
|
|
INT xLeft,
|
|
|
|
INT yTop,
|
|
|
|
PCURICON_OBJECT pIcon,
|
|
|
|
INT cxWidth,
|
|
|
|
INT cyHeight,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT istepIfAniCur,
|
|
|
|
HBRUSH hbrFlickerFreeDraw,
|
2006-08-08 20:00:53 +00:00
|
|
|
UINT diFlags)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2006-08-08 20:00:53 +00:00
|
|
|
BOOL Ret = FALSE;
|
2005-09-07 21:25:42 +00:00
|
|
|
HBITMAP hbmMask, hbmColor;
|
|
|
|
BITMAP bmpMask, bmpColor;
|
|
|
|
COLORREF oldFg, oldBg;
|
2006-08-08 20:00:53 +00:00
|
|
|
BOOL DoFlickerFree;
|
2005-09-07 21:25:42 +00:00
|
|
|
INT nStretchMode;
|
2006-08-08 20:00:53 +00:00
|
|
|
SIZE IconSize;
|
|
|
|
|
|
|
|
HDC hdcOff;
|
|
|
|
HGDIOBJ hOldOffBrush = 0;
|
|
|
|
HGDIOBJ hOldOffBmp = 0;
|
|
|
|
HBITMAP hbmOff = 0;
|
|
|
|
HDC hdcMem = 0;
|
|
|
|
HGDIOBJ hOldMem;
|
2006-12-21 19:43:13 +00:00
|
|
|
BOOL bAlpha = FALSE;
|
2005-09-09 00:25:52 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
hbmMask = pIcon->IconInfo.hbmMask;
|
|
|
|
hbmColor = pIcon->IconInfo.hbmColor;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(istepIfAniCur)
|
|
|
|
DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
|
2006-08-08 20:00:53 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
|
2006-08-08 20:00:53 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(hbmColor)
|
|
|
|
{
|
|
|
|
IconSize.cx = bmpColor.bmWidth;
|
|
|
|
IconSize.cy = bmpColor.bmHeight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconSize.cx = bmpMask.bmWidth;
|
|
|
|
IconSize.cy = bmpMask.bmHeight / 2;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2007-01-15 23:25:35 +00:00
|
|
|
if (bmpColor.bmBitsPixel == 32)
|
2006-12-21 19:43:13 +00:00
|
|
|
{
|
|
|
|
bAlpha = TRUE;
|
2007-01-15 23:25:35 +00:00
|
|
|
}
|
2006-12-21 19:43:13 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!diFlags)
|
|
|
|
diFlags = DI_NORMAL;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!cxWidth)
|
2006-08-08 20:00:53 +00:00
|
|
|
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
|
|
|
|
UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
|
|
|
|
|
2005-10-24 21:57:32 +00:00
|
|
|
if(!cyHeight)
|
2006-08-08 20:00:53 +00:00
|
|
|
cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
|
|
|
|
UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
DoFlickerFree = (hbrFlickerFreeDraw &&
|
2007-04-21 22:23:19 +00:00
|
|
|
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(DoFlickerFree)
|
|
|
|
{
|
|
|
|
RECT r;
|
|
|
|
r.right = cxWidth;
|
2005-10-24 21:57:32 +00:00
|
|
|
r.bottom = cyHeight;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
hdcOff = NtGdiCreateCompatibleDC(hDc);
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!hdcOff)
|
2006-08-08 20:00:53 +00:00
|
|
|
{
|
|
|
|
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!hbmOff)
|
|
|
|
{
|
2006-08-08 20:00:53 +00:00
|
|
|
DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
|
|
|
|
goto cleanup;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
|
2006-08-08 20:00:53 +00:00
|
|
|
if(!hOldOffBrush)
|
|
|
|
{
|
|
|
|
DPRINT1("NtGdiSelectObject() failed!\n");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
|
2006-08-08 20:00:53 +00:00
|
|
|
if(!hOldOffBmp)
|
|
|
|
{
|
|
|
|
DPRINT1("NtGdiSelectObject() failed!\n");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
|
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
else hdcOff = hDc;
|
|
|
|
|
|
|
|
hdcMem = NtGdiCreateCompatibleDC(hDc);
|
2005-09-09 00:25:52 +00:00
|
|
|
if(!hdcMem)
|
2006-08-08 20:00:53 +00:00
|
|
|
{
|
|
|
|
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
|
2005-09-09 00:25:52 +00:00
|
|
|
goto cleanup;
|
2006-08-08 20:00:53 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
|
|
|
|
oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(diFlags & DI_MASK)
|
|
|
|
{
|
|
|
|
hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
|
2006-08-08 20:00:53 +00:00
|
|
|
if(!hOldMem)
|
|
|
|
{
|
|
|
|
DPRINT("NtGdiSelectObject() failed!\n");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-10-24 21:57:32 +00:00
|
|
|
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
|
|
|
|
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
|
|
|
|
0, 0, IconSize.cx, IconSize.cy,
|
|
|
|
((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth)
|
|
|
|
&& (diFlags & DI_IMAGE))
|
2005-09-09 00:25:52 +00:00
|
|
|
{
|
2005-10-24 21:57:32 +00:00
|
|
|
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
|
|
|
|
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
|
|
|
|
0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT,
|
|
|
|
FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
diFlags &= ~DI_IMAGE;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
NtGdiSelectObject(hdcMem, hOldMem);
|
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(diFlags & DI_IMAGE)
|
|
|
|
{
|
|
|
|
hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-10-24 21:57:32 +00:00
|
|
|
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
|
|
|
|
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
|
|
|
|
0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy,
|
|
|
|
((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
|
|
|
|
NULL != hbmColor);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
NtGdiSelectObject(hdcMem, hOldMem);
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
if(DoFlickerFree)
|
2006-08-08 20:00:53 +00:00
|
|
|
{
|
2006-12-21 19:43:13 +00:00
|
|
|
if (bAlpha)
|
|
|
|
{
|
2007-01-15 23:25:35 +00:00
|
|
|
BITMAPINFO bi;
|
|
|
|
BITMAP bm;
|
2007-01-16 00:08:41 +00:00
|
|
|
BITMAPOBJ *Bitmap = NULL;
|
|
|
|
PBYTE pBits = NULL;
|
2006-12-21 19:43:13 +00:00
|
|
|
BLENDFUNCTION BlendFunc;
|
2007-01-15 23:25:35 +00:00
|
|
|
BYTE Red, Green, Blue, Alpha;
|
|
|
|
DWORD Count = 0;
|
|
|
|
INT i, j;
|
|
|
|
|
|
|
|
/* Bitmap header */
|
|
|
|
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
|
|
|
bi.bmiHeader.biWidth = cxWidth;
|
|
|
|
bi.bmiHeader.biHeight = cyHeight;
|
|
|
|
bi.bmiHeader.biPlanes = 1;
|
|
|
|
bi.bmiHeader.biBitCount = 32;
|
|
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
|
|
bi.bmiHeader.biSizeImage = cxWidth * cyHeight * 4;
|
|
|
|
bi.bmiHeader.biClrUsed = 0;
|
|
|
|
bi.bmiHeader.biClrImportant = 0;
|
|
|
|
|
|
|
|
Bitmap = GDIOBJ_LockObj(GdiHandleTable, hbmOff, GDI_OBJECT_TYPE_BITMAP);
|
|
|
|
if (Bitmap == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("GDIOBJ_LockObj() failed!\n");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
BITMAP_GetObject(Bitmap, sizeof(BITMAP), &bm);
|
|
|
|
|
|
|
|
/* Buffer */
|
|
|
|
pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
|
|
|
|
if (pBits == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("ExAllocatePoolWithTag() failed!\n");
|
2007-01-16 00:08:41 +00:00
|
|
|
GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
|
2007-01-15 23:25:35 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get icon bits */
|
2007-08-02 22:14:32 +00:00
|
|
|
IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
|
2007-01-15 23:25:35 +00:00
|
|
|
|
|
|
|
/* premultiply with the alpha channel value */
|
|
|
|
for (i = 0; i < cyHeight; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < cxWidth; j++)
|
|
|
|
{
|
|
|
|
DWORD OrigPixel = 0;
|
|
|
|
DWORD AlphaPixel = 0;
|
|
|
|
|
|
|
|
OrigPixel = *(DWORD *)(pBits + Count);
|
|
|
|
|
|
|
|
Red = (BYTE)((OrigPixel >> 0) & 0xff);
|
|
|
|
Green = (BYTE)((OrigPixel >> 8) & 0xff);
|
|
|
|
Blue = (BYTE)((OrigPixel >> 16) & 0xff);
|
|
|
|
Alpha = (BYTE)((OrigPixel >> 24) & 0xff);
|
|
|
|
|
|
|
|
Red = (Red * Alpha) / 0xff;
|
|
|
|
Green = (Green * Alpha) / 0xff;
|
|
|
|
Blue = (Blue * Alpha) / 0xff;
|
|
|
|
|
|
|
|
AlphaPixel = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
|
|
|
|
|
|
|
|
*(DWORD *)(pBits + Count) = AlphaPixel;
|
|
|
|
Count += sizeof (DWORD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set icon bits */
|
2007-08-02 22:14:32 +00:00
|
|
|
IntSetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
|
2007-01-15 23:25:35 +00:00
|
|
|
ExFreePool(pBits);
|
|
|
|
|
|
|
|
GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
|
|
|
|
|
|
|
|
BlendFunc.BlendOp = AC_SRC_OVER;
|
2006-12-21 19:43:13 +00:00
|
|
|
BlendFunc.BlendFlags = 0;
|
|
|
|
BlendFunc.SourceConstantAlpha = 255;
|
|
|
|
BlendFunc.AlphaFormat = AC_SRC_ALPHA;
|
2007-01-15 23:25:35 +00:00
|
|
|
|
2006-12-21 19:43:13 +00:00
|
|
|
NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight,
|
2007-08-09 06:48:07 +00:00
|
|
|
hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0);
|
2006-12-21 19:43:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
|
|
|
|
cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
|
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
}
|
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
NtGdiSetTextColor(hdcOff, oldFg);
|
|
|
|
NtGdiSetBkColor(hdcOff, oldBg);
|
2005-10-24 21:57:32 +00:00
|
|
|
NtGdiSetStretchBltMode(hdcOff, nStretchMode);
|
2006-08-08 20:00:53 +00:00
|
|
|
|
2005-09-09 00:25:52 +00:00
|
|
|
Ret = TRUE;
|
2006-08-08 20:00:53 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
cleanup:
|
2005-09-09 00:25:52 +00:00
|
|
|
if(DoFlickerFree)
|
|
|
|
{
|
2006-08-08 20:00:53 +00:00
|
|
|
if(hOldOffBmp) NtGdiSelectObject(hdcOff, hOldOffBmp);
|
|
|
|
if(hOldOffBrush) NtGdiSelectObject(hdcOff, hOldOffBrush);
|
|
|
|
if(hbmOff) NtGdiDeleteObject(hbmOff);
|
|
|
|
if(hdcOff) NtGdiDeleteObjectApp(hdcOff);
|
2005-09-09 00:25:52 +00:00
|
|
|
}
|
2006-08-08 20:00:53 +00:00
|
|
|
|
|
|
|
if(hdcMem) NtGdiDeleteObjectApp(hdcMem);
|
|
|
|
return Ret;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserDrawIconEx(
|
|
|
|
HDC hdc,
|
|
|
|
int xLeft,
|
|
|
|
int yTop,
|
|
|
|
HICON hIcon,
|
|
|
|
int cxWidth,
|
|
|
|
int cyHeight,
|
|
|
|
UINT istepIfAniCur,
|
|
|
|
HBRUSH hbrFlickerFreeDraw,
|
|
|
|
UINT diFlags,
|
|
|
|
DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
|
|
|
{
|
|
|
|
PCURICON_OBJECT pIcon;
|
|
|
|
BOOL Ret;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2006-08-08 20:00:53 +00:00
|
|
|
DPRINT("Enter NtUserDrawIconEx\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
if(!(pIcon = UserGetCurIconObject(hIcon)))
|
|
|
|
{
|
|
|
|
DPRINT1("UserGetCurIconObject() failed!\n");
|
|
|
|
UserLeave();
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = UserDrawIconEx(hdc,
|
|
|
|
xLeft,
|
|
|
|
yTop,
|
|
|
|
pIcon,
|
|
|
|
cxWidth,
|
|
|
|
cyHeight,
|
|
|
|
istepIfAniCur,
|
|
|
|
hbrFlickerFreeDraw,
|
|
|
|
diFlags);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
UserLeave();
|
2006-08-08 20:00:53 +00:00
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|