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.
|
|
|
|
*/
|
2004-01-16 19:32:00 +00:00
|
|
|
/* $Id: cursoricon.c,v 1.43 2004/01/16 19:32:00 gvg Exp $ */
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-06-03 22:26:52 +00:00
|
|
|
#undef WIN32_LEAN_AND_MEAN
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-08-24 23:52:29 +00:00
|
|
|
#include <ddk/ntddk.h>
|
|
|
|
#include <ddk/ntddmou.h>
|
2003-08-24 01:12:16 +00:00
|
|
|
#include <win32k/win32k.h>
|
2003-06-03 22:26:52 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <win32k/bitmaps.h>
|
2003-11-10 17:44:50 +00:00
|
|
|
#include <win32k/dc.h>
|
2003-08-24 01:12:16 +00:00
|
|
|
#include <include/winsta.h>
|
2003-12-07 19:29:33 +00:00
|
|
|
#include <include/desktop.h>
|
2003-08-24 01:12:16 +00:00
|
|
|
#include <include/error.h>
|
2003-08-24 23:52:29 +00:00
|
|
|
#include <include/mouse.h>
|
2003-09-09 20:10:38 +00:00
|
|
|
#include <include/window.h>
|
2003-11-10 17:44:50 +00:00
|
|
|
#include <include/cursoricon.h>
|
|
|
|
#include <include/inteng.h>
|
|
|
|
#include <include/surface.h>
|
|
|
|
#include <include/palette.h>
|
|
|
|
#include <include/eng.h>
|
2003-12-13 13:45:18 +00:00
|
|
|
#include <include/intgdi.h>
|
2003-11-21 16:36:26 +00:00
|
|
|
#include <include/callback.h>
|
2003-11-10 17:44:50 +00:00
|
|
|
#include "include/object.h"
|
2003-09-09 20:10:38 +00:00
|
|
|
#include <internal/safe.h>
|
2003-06-03 22:26:52 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <win32k/debug1.h>
|
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
PCURICON_OBJECT FASTCALL
|
|
|
|
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
|
|
|
|
{
|
|
|
|
PCURICON_OBJECT Object;
|
|
|
|
PUSER_HANDLE_TABLE HandleTable;
|
|
|
|
|
|
|
|
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
|
|
|
|
if(!NT_SUCCESS(ObmReferenceObjectByHandle(HandleTable, Handle, otCursorIcon,
|
|
|
|
(PVOID*)&Object)))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Object;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID FASTCALL
|
|
|
|
IntReleaseCurIconObject(PCURICON_OBJECT Object)
|
|
|
|
{
|
|
|
|
ObmDereferenceObject(Object);
|
|
|
|
}
|
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
HBITMAP FASTCALL
|
|
|
|
IntCopyBitmap(HBITMAP bmp)
|
|
|
|
{
|
|
|
|
PBITMAPOBJ src;
|
|
|
|
HBITMAP ret = (HBITMAP)0;
|
|
|
|
|
|
|
|
if(!bmp)
|
|
|
|
return (HBITMAP)0;
|
|
|
|
|
|
|
|
src = BITMAPOBJ_LockBitmap(bmp);
|
|
|
|
if(src)
|
|
|
|
{
|
|
|
|
ret = NtGdiCreateBitmap(src->bitmap.bmWidth, src->bitmap.bmHeight, src->bitmap.bmPlanes,
|
|
|
|
src->bitmap.bmBitsPixel, src->bitmap.bmBits);
|
|
|
|
BITMAPOBJ_UnlockBitmap(bmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-01-16 15:39:28 +00:00
|
|
|
STATIC VOID FASTCALL
|
|
|
|
SetPointerRect(PSYSTEM_CURSORINFO CurInfo, PRECTL PointerRect)
|
|
|
|
{
|
|
|
|
CurInfo->PointerRectLeft = PointerRect->left;
|
|
|
|
CurInfo->PointerRectRight = PointerRect->right;
|
|
|
|
CurInfo->PointerRectTop = PointerRect->top;
|
|
|
|
CurInfo->PointerRectBottom = PointerRect->bottom;
|
|
|
|
}
|
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
#define COLORCURSORS_ALLOWED FALSE
|
|
|
|
HCURSOR FASTCALL
|
|
|
|
IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange)
|
|
|
|
{
|
|
|
|
PSURFOBJ SurfObj;
|
|
|
|
PSURFGDI SurfGDI;
|
|
|
|
SIZEL MouseSize;
|
|
|
|
PDEVINFO DevInfo;
|
|
|
|
PBITMAPOBJ MaskBmpObj;
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
PCURICON_OBJECT OldCursor;
|
|
|
|
HCURSOR Ret = (HCURSOR)0;
|
|
|
|
HBITMAP hMask = (HBITMAP)0, hColor = (HBITMAP)0;
|
|
|
|
PSURFOBJ soMask = NULL, soColor = NULL;
|
|
|
|
PXLATEOBJ XlateObj = NULL;
|
2004-01-16 15:39:28 +00:00
|
|
|
RECTL PointerRect;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
CurInfo = &WinStaObject->SystemCursor;
|
|
|
|
OldCursor = CurInfo->CurrentCursorObject;
|
|
|
|
if(OldCursor)
|
2003-12-13 19:53:17 +00:00
|
|
|
{
|
2003-12-13 22:38:29 +00:00
|
|
|
Ret = (HCURSOR)OldCursor->Self;
|
2003-12-13 19:53:17 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
if(!ForceChange && (OldCursor == NewCursor))
|
2003-12-13 19:53:17 +00:00
|
|
|
{
|
|
|
|
return Ret;
|
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-13 19:53:17 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
/* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
|
2003-12-13 19:53:17 +00:00
|
|
|
PDC dc = DC_LockDc(IntGetScreenDC());
|
2003-11-21 22:46:27 +00:00
|
|
|
if(!dc)
|
2003-12-14 13:26:20 +00:00
|
|
|
{
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
|
|
|
|
SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface);
|
|
|
|
DevInfo = dc->DevInfo;
|
2003-11-23 11:39:48 +00:00
|
|
|
DC_UnlockDc(IntGetScreenDC());
|
2003-12-13 19:53:17 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
if(!NewCursor && (CurInfo->CurrentCursorObject || ForceChange))
|
|
|
|
{
|
2004-01-16 19:32:00 +00:00
|
|
|
ExAcquireFastMutex(SurfGDI->DriverLock);
|
2003-11-10 17:44:50 +00:00
|
|
|
SurfGDI->PointerStatus = SurfGDI->SetPointerShape(SurfObj, NULL, NULL, NULL,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
CurInfo->x,
|
|
|
|
CurInfo->y,
|
2004-01-16 15:39:28 +00:00
|
|
|
&PointerRect,
|
2003-11-10 17:44:50 +00:00
|
|
|
SPS_CHANGE);
|
2004-01-16 19:32:00 +00:00
|
|
|
ExReleaseFastMutex(SurfGDI->DriverLock);
|
2004-01-16 15:39:28 +00:00
|
|
|
SetPointerRect(CurInfo, &PointerRect);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-13 19:53:17 +00:00
|
|
|
CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
|
2003-11-10 17:44:50 +00:00
|
|
|
CurInfo->ShowingCursor = 0;
|
2003-12-13 19:53:17 +00:00
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2003-12-13 19:53:17 +00:00
|
|
|
if (!NewCursor)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-13 19:53:17 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: Fixme. Logic is screwed above */
|
|
|
|
|
2003-12-14 13:26:20 +00:00
|
|
|
ASSERT(NewCursor);
|
2003-11-10 17:44:50 +00:00
|
|
|
MaskBmpObj = BITMAPOBJ_LockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
if(MaskBmpObj)
|
|
|
|
{
|
2003-12-13 19:53:17 +00:00
|
|
|
const int maskBpp = MaskBmpObj->bitmap.bmBitsPixel;
|
|
|
|
BITMAPOBJ_UnlockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
if(maskBpp != 1)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
|
|
|
DbgPrint("SetCursor: The Mask bitmap must have 1BPP!\n");
|
2003-12-13 19:53:17 +00:00
|
|
|
return Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if((DevInfo->flGraphicsCaps2 & GCAPS2_ALPHACURSOR) &&
|
|
|
|
(SurfGDI->BitsPerPixel >= 16) && NewCursor->Shadow
|
|
|
|
&& COLORCURSORS_ALLOWED)
|
|
|
|
{
|
|
|
|
/* 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. */
|
|
|
|
DbgPrint("SetCursor: (Colored) alpha cursors are not supported!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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) */
|
|
|
|
DbgPrint("SetCursor: Cursors with colors are not supported!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MaskBmpObj = BITMAPOBJ_LockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
if(MaskBmpObj)
|
|
|
|
{
|
|
|
|
MouseSize.cx = MaskBmpObj->bitmap.bmWidth;
|
|
|
|
MouseSize.cy = MaskBmpObj->bitmap.bmHeight;
|
|
|
|
hMask = EngCreateBitmap(MouseSize, 4, BMF_1BPP, BMF_TOPDOWN, MaskBmpObj->bitmap.bmBits);
|
|
|
|
soMask = (PSURFOBJ)AccessUserObject((ULONG)hMask);
|
|
|
|
BITMAPOBJ_UnlockBitmap(NewCursor->IconInfo.hbmMask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CurInfo->ShowingCursor = CURSOR_SHOWING;
|
|
|
|
CurInfo->CurrentCursorObject = NewCursor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CurInfo->ShowingCursor = 0;
|
|
|
|
CurInfo->CurrentCursorObject = NULL;
|
|
|
|
}
|
|
|
|
|
2004-01-16 19:32:00 +00:00
|
|
|
ExAcquireFastMutex(SurfGDI->DriverLock);
|
2003-11-10 17:44:50 +00:00
|
|
|
SurfGDI->PointerStatus = SurfGDI->SetPointerShape(SurfObj, soMask, soColor, XlateObj,
|
|
|
|
NewCursor->IconInfo.xHotspot,
|
|
|
|
NewCursor->IconInfo.yHotspot,
|
|
|
|
CurInfo->x,
|
|
|
|
CurInfo->y,
|
2004-01-16 15:39:28 +00:00
|
|
|
&PointerRect,
|
2003-11-10 17:44:50 +00:00
|
|
|
SPS_CHANGE);
|
2004-01-16 19:32:00 +00:00
|
|
|
ExReleaseFastMutex(SurfGDI->DriverLock);
|
2004-01-16 15:39:28 +00:00
|
|
|
SetPointerRect(CurInfo, &PointerRect);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
if(hMask)
|
2003-12-14 13:26:20 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
EngDeleteSurface(hMask);
|
2003-12-14 13:26:20 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
if(hColor)
|
2003-12-14 13:26:20 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
EngDeleteSurface(hColor);
|
2003-12-14 13:26:20 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
if(XlateObj)
|
2003-12-14 13:26:20 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
EngDeleteXlate(XlateObj);
|
2003-12-14 13:26:20 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
if(SurfGDI->PointerStatus == SPS_DECLINE)
|
|
|
|
DbgPrint("SetCursor: DrvSetPointerShape() returned SPS_DECLINE\n");
|
|
|
|
else if(SurfGDI->PointerStatus == SPS_ERROR)
|
|
|
|
DbgPrint("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL FASTCALL
|
|
|
|
IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject)
|
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
if((WinStaObject->SystemCursor.CurIconHandleTable = (PVOID)ObmCreateHandleTable()))
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
ObmInitializeHandleTable((PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable);
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2003-12-09 19:34:33 +00:00
|
|
|
return (WinStaObject->SystemCursor.CurIconHandleTable != NULL);
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PCURICON_OBJECT FASTCALL
|
|
|
|
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule,
|
2003-12-09 20:58:16 +00:00
|
|
|
HRSRC hRsrc, LONG cx, LONG cy)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
PUSER_HANDLE_TABLE HandleTable;
|
|
|
|
PLIST_ENTRY CurrentEntry;
|
|
|
|
PUSER_HANDLE_BLOCK Current;
|
|
|
|
PCURICON_OBJECT Object;
|
|
|
|
ULONG i;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
|
|
|
|
ExAcquireFastMutex(&HandleTable->ListLock);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
CurrentEntry = HandleTable->ListHead.Flink;
|
|
|
|
while(CurrentEntry != &HandleTable->ListHead)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
Current = CONTAINING_RECORD(CurrentEntry, USER_HANDLE_BLOCK, ListEntry);
|
|
|
|
for(i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
Object = (PCURICON_OBJECT)Current->Handles[i].ObjectBody;
|
|
|
|
if(Object && (Object->hModule == hModule) && (Object->hRsrc == hRsrc))
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 20:58:16 +00:00
|
|
|
if(cx && ((cx != Object->Size.cx) || (cy != Object->Size.cy)))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2003-12-09 19:38:47 +00:00
|
|
|
ObmReferenceObject(Object);
|
2003-12-09 19:34:33 +00:00
|
|
|
ExReleaseFastMutex(&HandleTable->ListLock);
|
|
|
|
return Object;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
}
|
2003-12-10 17:33:42 +00:00
|
|
|
CurrentEntry = CurrentEntry->Flink;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
ExReleaseFastMutex(&HandleTable->ListLock);
|
2003-11-10 17:44:50 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PCURICON_OBJECT FASTCALL
|
|
|
|
IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
|
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
PUSER_HANDLE_TABLE HandleTable;
|
|
|
|
PCURICON_OBJECT Object;
|
|
|
|
HANDLE Handle;
|
2003-12-13 22:38:29 +00:00
|
|
|
PW32PROCESS Win32Process;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
Object = ObmCreateObject(HandleTable, &Handle, otCursorIcon, sizeof(CURICON_OBJECT));
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
if(!Object)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
2003-12-09 19:34:33 +00:00
|
|
|
return FALSE;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2003-12-13 22:38:29 +00:00
|
|
|
Win32Process = PsGetWin32Process();
|
|
|
|
|
|
|
|
ExAcquireFastMutex(&Win32Process->CursorIconListLock);
|
|
|
|
InsertTailList(&Win32Process->CursorIconListHead, &Object->ListEntry);
|
|
|
|
ExReleaseFastMutex(&Win32Process->CursorIconListLock);
|
|
|
|
|
|
|
|
Object->Self = Handle;
|
2003-12-09 19:34:33 +00:00
|
|
|
Object->Process = PsGetWin32Process();
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
return Object;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL FASTCALL
|
2003-12-13 22:38:29 +00:00
|
|
|
IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL RemoveFromProcess)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
PUSER_HANDLE_TABLE HandleTable;
|
|
|
|
PCURICON_OBJECT Object;
|
2003-12-10 22:09:56 +00:00
|
|
|
HBITMAP bmpMask, bmpColor;
|
2003-12-09 19:34:33 +00:00
|
|
|
NTSTATUS Status;
|
2003-12-10 22:09:56 +00:00
|
|
|
BOOL Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
Status = ObmReferenceObjectByHandle(HandleTable, Handle, otCursorIcon, (PVOID*)&Object);
|
|
|
|
if(!NT_SUCCESS(Status))
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
return FALSE;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
2003-12-10 22:47:11 +00:00
|
|
|
if(WinStaObject->SystemCursor.CurrentCursorObject == Object)
|
|
|
|
{
|
2003-12-13 22:38:29 +00:00
|
|
|
/* Hide the cursor if we're destroying the current cursor */
|
|
|
|
IntSetCursor(WinStaObject, NULL, TRUE);
|
2003-12-10 22:47:11 +00:00
|
|
|
}
|
|
|
|
|
2003-12-10 22:09:56 +00:00
|
|
|
bmpMask = Object->IconInfo.hbmMask;
|
|
|
|
bmpColor = Object->IconInfo.hbmColor;
|
2003-12-09 19:34:33 +00:00
|
|
|
|
2003-12-13 22:38:29 +00:00
|
|
|
|
|
|
|
if(Object->Process && RemoveFromProcess)
|
|
|
|
{
|
|
|
|
ExAcquireFastMutex(&Object->Process->CursorIconListLock);
|
|
|
|
RemoveEntryList(&Object->ListEntry);
|
|
|
|
ExReleaseFastMutex(&Object->Process->CursorIconListLock);
|
|
|
|
}
|
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
ObmDereferenceObject(Object);
|
|
|
|
|
2003-12-10 22:09:56 +00:00
|
|
|
Ret = NT_SUCCESS(ObmCloseHandle(HandleTable, Handle));
|
|
|
|
|
|
|
|
/* delete bitmaps */
|
|
|
|
if(bmpMask)
|
|
|
|
NtGdiDeleteObject(bmpMask);
|
|
|
|
if(bmpColor)
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
PCURICON_OBJECT Current;
|
|
|
|
PLIST_ENTRY CurrentEntry, NextEntry;
|
|
|
|
|
|
|
|
if(!(WinStaObject = Win32Process->WindowStation))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ExAcquireFastMutex(&Win32Process->CursorIconListLock);
|
|
|
|
CurrentEntry = Win32Process->CursorIconListHead.Flink;
|
|
|
|
while(CurrentEntry != &Win32Process->CursorIconListHead)
|
|
|
|
{
|
|
|
|
NextEntry = CurrentEntry->Flink;
|
|
|
|
Current = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
|
|
|
RemoveEntryList(&Current->ListEntry);
|
|
|
|
IntDestroyCurIconObject(WinStaObject, Current->Self, FALSE);
|
|
|
|
CurrentEntry = NextEntry;
|
|
|
|
}
|
|
|
|
ExReleaseFastMutex(&Win32Process->CursorIconListLock);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect)
|
|
|
|
{
|
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
2003-11-15 12:43:25 +00:00
|
|
|
PBITMAPOBJ bmp;
|
2003-11-10 17:44:50 +00:00
|
|
|
NTSTATUS Status;
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE Ret;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
2003-12-09 20:58:16 +00:00
|
|
|
return (HANDLE)0;
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CurIconObject = IntCreateCurIconHandle(WinStaObject);
|
|
|
|
if(CurIconObject)
|
|
|
|
{
|
2003-12-13 22:38:29 +00:00
|
|
|
Ret = CurIconObject->Self;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
if(IconInfo)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&CurIconObject->IconInfo, IconInfo, sizeof(ICONINFO));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if(Indirect)
|
|
|
|
{
|
|
|
|
CurIconObject->IconInfo.hbmMask = IntCopyBitmap(CurIconObject->IconInfo.hbmMask);
|
|
|
|
CurIconObject->IconInfo.hbmColor = IntCopyBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
}
|
2003-11-18 19:59:51 +00:00
|
|
|
if(CurIconObject->IconInfo.hbmColor &&
|
|
|
|
(bmp = BITMAPOBJ_LockBitmap(CurIconObject->IconInfo.hbmColor)))
|
2003-11-15 12:43:25 +00:00
|
|
|
{
|
|
|
|
CurIconObject->Size.cx = bmp->size.cx;
|
|
|
|
CurIconObject->Size.cy = bmp->size.cy;
|
|
|
|
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-11-18 19:59:51 +00:00
|
|
|
if(CurIconObject->IconInfo.hbmMask &&
|
|
|
|
(bmp = BITMAPOBJ_LockBitmap(CurIconObject->IconInfo.hbmMask)))
|
2003-11-15 12:43:25 +00:00
|
|
|
{
|
|
|
|
CurIconObject->Size.cx = bmp->size.cx;
|
|
|
|
CurIconObject->Size.cy = bmp->size.cy / 2;
|
|
|
|
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmMask);
|
|
|
|
}
|
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
/* FIXME - Don't exit here */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
2003-12-09 20:58:16 +00:00
|
|
|
return (HANDLE)0;
|
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(
|
|
|
|
HANDLE Handle,
|
2003-11-10 17:44:50 +00:00
|
|
|
PICONINFO IconInfo)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
ICONINFO ii;
|
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, Handle);
|
2003-11-10 17:44:50 +00:00
|
|
|
if(CurIconObject)
|
|
|
|
{
|
|
|
|
if(IconInfo)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(&ii, &CurIconObject->IconInfo, sizeof(ICONINFO));
|
|
|
|
|
|
|
|
/* Copy bitmaps */
|
|
|
|
ii.hbmMask = IntCopyBitmap(ii.hbmMask);
|
|
|
|
ii.hbmColor = IntCopyBitmap(ii.hbmColor);
|
|
|
|
|
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyToCaller(IconInfo, &ii, sizeof(ICONINFO));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
Ret = TRUE;
|
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
}
|
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
2003-10-06 16:25:53 +00:00
|
|
|
return FALSE;
|
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(
|
|
|
|
HANDLE Handle,
|
2003-08-23 20:59:08 +00:00
|
|
|
BOOL *fIcon,
|
2003-11-10 17:44:50 +00:00
|
|
|
SIZE *Size)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PBITMAPOBJ bmp;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, Handle);
|
2003-11-10 17:44:50 +00:00
|
|
|
if(CurIconObject)
|
|
|
|
{
|
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyToCaller(fIcon, &CurIconObject->IconInfo.fIcon, sizeof(BOOL));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
if(!bmp)
|
|
|
|
goto done;
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
Status = MmCopyToCaller(Size, &bmp->size, sizeof(SIZE));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
Ret = TRUE;
|
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
|
|
|
|
|
|
|
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
|
|
|
|
done:
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
2003-10-06 16:25:53 +00:00
|
|
|
return FALSE;
|
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(
|
|
|
|
DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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(
|
2003-08-23 20:59:08 +00:00
|
|
|
PCURSORINFO pci)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
CURSORINFO SafeCi;
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCURICON_OBJECT CursorObject;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurInfo = &WinStaObject->SystemCursor;
|
|
|
|
CursorObject = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;
|
|
|
|
|
|
|
|
SafeCi.flags = ((CurInfo->ShowingCursor && CursorObject) ? CURSOR_SHOWING : 0);
|
2003-12-13 22:38:29 +00:00
|
|
|
SafeCi.hCursor = (CursorObject ? (HCURSOR)CursorObject->Self : (HCURSOR)0);
|
2003-11-10 17:44:50 +00:00
|
|
|
SafeCi.ptScreenPos.x = CurInfo->x;
|
|
|
|
SafeCi.ptScreenPos.y = CurInfo->y;
|
|
|
|
|
|
|
|
Status = MmCopyToCaller(pci, &SafeCi, sizeof(CURSORINFO));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return TRUE;
|
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(
|
2003-09-09 20:10:38 +00:00
|
|
|
RECT *UnsafeRect)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-08-24 18:52:18 +00:00
|
|
|
/* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
|
|
|
|
|
2003-08-24 01:12:16 +00:00
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
2003-08-24 23:52:29 +00:00
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
2003-09-09 20:10:38 +00:00
|
|
|
RECT Rect;
|
2003-09-21 16:00:24 +00:00
|
|
|
PWINDOW_OBJECT DesktopWindow = NULL;
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
NTSTATUS Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-08-24 01:12:16 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-09-09 20:10:38 +00:00
|
|
|
DPRINT1("Validation of window station handle (0x%X) failed\n",
|
2003-08-24 01:12:16 +00:00
|
|
|
PROCESS_WINDOW_STATION());
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastNtError(Status);
|
2003-08-24 01:12:16 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2003-09-09 20:10:38 +00:00
|
|
|
|
|
|
|
if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
|
|
|
|
{
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-08-24 23:52:29 +00:00
|
|
|
|
|
|
|
CurInfo = &WinStaObject->SystemCursor;
|
2003-09-21 16:00:24 +00:00
|
|
|
if(WinStaObject->ActiveDesktop)
|
|
|
|
DesktopWindow = IntGetWindowObject(WinStaObject->ActiveDesktop->DesktopWindow);
|
|
|
|
|
|
|
|
if((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
|
|
|
|
&& DesktopWindow)
|
2003-08-24 01:12:16 +00:00
|
|
|
{
|
2003-09-21 16:00:24 +00:00
|
|
|
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);
|
|
|
|
IntReleaseWindowObject(DesktopWindow);
|
2003-08-24 23:52:29 +00:00
|
|
|
|
2003-09-21 16:00:24 +00:00
|
|
|
MouseMoveCursor(CurInfo->x, CurInfo->y);
|
2003-08-24 01:12:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE;
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
|
|
|
|
return TRUE;
|
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(
|
|
|
|
HANDLE Handle,
|
2003-08-23 20:59:08 +00:00
|
|
|
DWORD Unknown)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-13 22:38:29 +00:00
|
|
|
if(IntDestroyCurIconObject(WinStaObject, Handle, TRUE))
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return FALSE;
|
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
|
|
|
*/
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE
|
2003-06-03 22:26:52 +00:00
|
|
|
STDCALL
|
|
|
|
NtUserFindExistingCursorIcon(
|
2003-11-10 17:44:50 +00:00
|
|
|
HMODULE hModule,
|
2003-12-09 20:58:16 +00:00
|
|
|
HRSRC hRsrc,
|
|
|
|
LONG cx,
|
|
|
|
LONG cy)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE Ret = (HANDLE)0;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject = IntFindExistingCurIconObject(WinStaObject, hModule, hRsrc, cx, cy);
|
2003-11-10 17:44:50 +00:00
|
|
|
if(CurIconObject)
|
|
|
|
{
|
2003-12-13 22:38:29 +00:00
|
|
|
Ret = CurIconObject->Self;
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
2003-11-18 19:59:51 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
2003-12-09 20:58:16 +00:00
|
|
|
return (HANDLE)0;
|
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(
|
2003-08-23 20:59:08 +00:00
|
|
|
RECT *lpRect)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-08-24 18:52:18 +00:00
|
|
|
/* FIXME - check if process has WINSTA_READATTRIBUTES */
|
|
|
|
|
2003-08-24 01:12:16 +00:00
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
2003-09-24 21:09:22 +00:00
|
|
|
RECT Rect;
|
|
|
|
NTSTATUS Status;
|
2003-08-24 01:12:16 +00:00
|
|
|
|
|
|
|
if(!lpRect)
|
|
|
|
return FALSE;
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-09-24 21:09:22 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
2003-08-24 01:12:16 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
|
|
|
PROCESS_WINDOW_STATION());
|
2003-10-04 22:36:37 +00:00
|
|
|
SetLastNtError(Status);
|
2003-08-24 01:12:16 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(WinStaObject->SystemCursor.CursorClipInfo.IsClipped)
|
|
|
|
{
|
2003-09-24 21:09:22 +00:00
|
|
|
Rect.left = WinStaObject->SystemCursor.CursorClipInfo.Left;
|
|
|
|
Rect.top = WinStaObject->SystemCursor.CursorClipInfo.Top;
|
|
|
|
Rect.right = WinStaObject->SystemCursor.CursorClipInfo.Right;
|
|
|
|
Rect.bottom = WinStaObject->SystemCursor.CursorClipInfo.Bottom;
|
2003-08-24 01:12:16 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-09-24 21:09:22 +00:00
|
|
|
Rect.left = 0;
|
|
|
|
Rect.top = 0;
|
|
|
|
Rect.right = NtUserGetSystemMetrics(SM_CXSCREEN);
|
|
|
|
Rect.bottom = NtUserGetSystemMetrics(SM_CYSCREEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyToCaller((PRECT)lpRect, &Rect, sizeof(RECT));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
2003-08-24 01:12:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
|
|
|
|
return TRUE;
|
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(
|
2003-08-23 20:59:08 +00:00
|
|
|
HCURSOR hCursor)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
HICON OldCursor = (HCURSOR)0;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return (HCURSOR)0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, hCursor);
|
|
|
|
if(CurIconObject)
|
|
|
|
{
|
|
|
|
OldCursor = IntSetCursor(WinStaObject, CurIconObject, FALSE);
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return OldCursor;
|
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(
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE Handle,
|
2003-11-10 17:44:50 +00:00
|
|
|
PICONINFO IconInfo)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PBITMAPOBJ bmp;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, Handle);
|
2003-11-10 17:44:50 +00:00
|
|
|
if(CurIconObject)
|
|
|
|
{
|
|
|
|
/* Copy fields */
|
|
|
|
Status = MmCopyFromCaller(&CurIconObject->IconInfo, IconInfo, sizeof(ICONINFO));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2003-11-15 12:43:25 +00:00
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
if(bmp)
|
|
|
|
{
|
|
|
|
CurIconObject->Size.cx = bmp->size.cx;
|
|
|
|
CurIconObject->Size.cy = bmp->size.cy;
|
|
|
|
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bmp = BITMAPOBJ_LockBitmap(CurIconObject->IconInfo.hbmMask);
|
|
|
|
if(!bmp)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
CurIconObject->Size.cx = bmp->size.cx;
|
|
|
|
CurIconObject->Size.cy = bmp->size.cy / 2;
|
|
|
|
|
|
|
|
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmMask);
|
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
Ret = TRUE;
|
|
|
|
|
|
|
|
done:
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return FALSE;
|
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(
|
2003-12-09 20:58:16 +00:00
|
|
|
HANDLE Handle,
|
2003-08-23 20:59:08 +00:00
|
|
|
PBOOL fIcon,
|
2003-11-10 17:44:50 +00:00
|
|
|
POINT *Hotspot,
|
|
|
|
HMODULE hModule,
|
|
|
|
HRSRC hRsrc,
|
|
|
|
HRSRC hGroupRsrc)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-11-10 17:44:50 +00:00
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
POINT SafeHotspot;
|
|
|
|
BOOL Ret = FALSE;
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, Handle);
|
2003-11-10 17:44:50 +00:00
|
|
|
if(CurIconObject)
|
|
|
|
{
|
2003-12-09 20:58:16 +00:00
|
|
|
CurIconObject->hModule = hModule;
|
|
|
|
CurIconObject->hRsrc = hRsrc;
|
|
|
|
CurIconObject->hGroupRsrc = hGroupRsrc;
|
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
/* Copy fields */
|
2003-11-18 19:59:51 +00:00
|
|
|
if(fIcon)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-11-18 19:59:51 +00:00
|
|
|
Status = MmCopyFromCaller(&CurIconObject->IconInfo.fIcon, fIcon, sizeof(BOOL));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
goto done;
|
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
}
|
2003-11-18 19:59:51 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!Hotspot)
|
|
|
|
Ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Hotspot)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
CurIconObject->IconInfo.xHotspot = SafeHotspot.x;
|
|
|
|
CurIconObject->IconInfo.yHotspot = SafeHotspot.y;
|
|
|
|
|
|
|
|
Ret = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastNtError(Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!fIcon && !Hotspot)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
|
|
|
Ret = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return Ret;
|
|
|
|
}
|
2003-06-03 22:26:52 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return FALSE;
|
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(
|
2003-08-23 20:59:08 +00:00
|
|
|
HCURSOR hcur,
|
|
|
|
DWORD id)
|
2003-06-03 22:26:52 +00:00
|
|
|
{
|
2003-12-09 19:34:33 +00:00
|
|
|
return FALSE;
|
2003-06-03 22:26:52 +00:00
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define CANSTRETCHBLT 0
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserDrawIconEx(
|
|
|
|
HDC hdc,
|
|
|
|
int xLeft,
|
|
|
|
int yTop,
|
|
|
|
HICON hIcon,
|
|
|
|
int cxWidth,
|
|
|
|
int cyWidth,
|
|
|
|
UINT istepIfAniCur,
|
|
|
|
HBRUSH hbrFlickerFreeDraw,
|
|
|
|
UINT diFlags,
|
|
|
|
DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
|
|
|
{
|
|
|
|
PCURICON_OBJECT CurIconObject;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HBITMAP hbmMask, hbmColor;
|
|
|
|
BITMAP bmpMask, bmpColor;
|
|
|
|
BOOL DoFlickerFree;
|
|
|
|
SIZE IconSize;
|
|
|
|
COLORREF oldFg, oldBg;
|
|
|
|
HDC hdcMem, hdcOff = (HDC)0;
|
|
|
|
HBITMAP hbmOff = (HBITMAP)0;
|
2003-12-18 23:04:54 +00:00
|
|
|
HGDIOBJ hOldOffBrush, hOldOffBmp, hOldMem;
|
2003-11-10 17:44:50 +00:00
|
|
|
BOOL Ret = FALSE;
|
|
|
|
#if CANSTRETCHBLT
|
|
|
|
INT nStretchMode;
|
|
|
|
#endif
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
2003-11-10 17:44:50 +00:00
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurIconObject = IntGetCurIconObject(WinStaObject, hIcon);
|
|
|
|
if(CurIconObject)
|
|
|
|
{
|
|
|
|
hbmMask = CurIconObject->IconInfo.hbmMask;
|
|
|
|
hbmColor = CurIconObject->IconInfo.hbmColor;
|
2003-12-09 19:34:33 +00:00
|
|
|
IntReleaseCurIconObject(CurIconObject);
|
2003-11-10 17:44:50 +00:00
|
|
|
|
2003-11-11 17:50:58 +00:00
|
|
|
if(istepIfAniCur)
|
|
|
|
DbgPrint("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
|
|
|
|
|
2003-12-13 13:45:18 +00:00
|
|
|
if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
|
2003-11-10 17:44:50 +00:00
|
|
|
goto done;
|
|
|
|
|
2003-12-13 13:45:18 +00:00
|
|
|
if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
|
2003-11-10 17:44:50 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
if(hbmColor)
|
|
|
|
{
|
|
|
|
IconSize.cx = bmpColor.bmWidth;
|
|
|
|
IconSize.cy = bmpColor.bmHeight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconSize.cx = bmpMask.bmWidth;
|
|
|
|
IconSize.cy = bmpMask.bmHeight / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!diFlags)
|
|
|
|
diFlags = DI_NORMAL;
|
|
|
|
|
|
|
|
if(!cxWidth)
|
|
|
|
cxWidth = ((diFlags & DI_DEFAULTSIZE) ? NtUserGetSystemMetrics(SM_CXICON) : IconSize.cx);
|
|
|
|
if(!cyWidth)
|
|
|
|
cyWidth = ((diFlags & DI_DEFAULTSIZE) ? NtUserGetSystemMetrics(SM_CYICON) : IconSize.cy);
|
|
|
|
|
|
|
|
DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
|
|
|
|
|
|
|
|
if(DoFlickerFree)
|
|
|
|
{
|
|
|
|
RECT r;
|
|
|
|
r.right = cxWidth;
|
|
|
|
r.bottom = cyWidth;
|
|
|
|
|
|
|
|
hdcOff = NtGdiCreateCompatableDC(hdc);
|
|
|
|
if(!hdcOff)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyWidth);
|
|
|
|
if(!hbmOff)
|
|
|
|
{
|
|
|
|
NtGdiDeleteDC(hdcOff);
|
|
|
|
goto done;
|
|
|
|
}
|
2003-12-18 23:04:54 +00:00
|
|
|
hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
|
|
|
|
hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
|
2003-11-10 17:44:50 +00:00
|
|
|
NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
|
|
|
|
NtGdiSelectObject(hdcOff, hbmOff);
|
|
|
|
}
|
|
|
|
|
|
|
|
hdcMem = NtGdiCreateCompatableDC(hdc);
|
|
|
|
if(!hdcMem)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if(!DoFlickerFree)
|
|
|
|
hdcOff = hdc;
|
|
|
|
|
|
|
|
#if CANSTRETCHBLT
|
|
|
|
nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
|
|
|
|
#endif
|
|
|
|
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
|
|
|
|
oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
|
|
|
|
|
|
|
|
if(diFlags & DI_MASK)
|
|
|
|
{
|
|
|
|
hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
|
|
|
|
#if CANSTRETCHBLT
|
|
|
|
NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
2003-11-11 17:50:58 +00:00
|
|
|
cxWidth, cyWidth, hdcMem, 0, 0, IconSize.cx, IconSize.cy,
|
|
|
|
((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY));
|
2003-11-10 17:44:50 +00:00
|
|
|
#else
|
|
|
|
NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
2003-11-11 17:50:58 +00:00
|
|
|
cxWidth, cyWidth, hdcMem, 0, 0, ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY));
|
2003-11-10 17:44:50 +00:00
|
|
|
#endif
|
|
|
|
if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) && (diFlags & DI_IMAGE))
|
|
|
|
{
|
|
|
|
#if CANSTRETCHBLT
|
|
|
|
NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
|
|
|
cxWidth, cyWidth, hdcMem, 0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT);
|
|
|
|
#else
|
|
|
|
NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
|
|
|
cxWidth, cyWidth, hdcMem, 0, IconSize.cy, SRCINVERT);
|
|
|
|
#endif
|
|
|
|
diFlags &= ~DI_IMAGE;
|
|
|
|
}
|
|
|
|
NtGdiSelectObject(hdcMem, hOldMem);
|
|
|
|
}
|
|
|
|
|
2003-11-11 17:50:58 +00:00
|
|
|
if(diFlags & DI_IMAGE)
|
2003-11-10 17:44:50 +00:00
|
|
|
{
|
2003-11-11 17:50:58 +00:00
|
|
|
hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
|
2003-11-10 17:44:50 +00:00
|
|
|
#if CANSTRETCHBLT
|
|
|
|
NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
2003-11-11 17:50:58 +00:00
|
|
|
cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy),
|
|
|
|
IconSize.cx, IconSize.cy, ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY));
|
2003-11-10 17:44:50 +00:00
|
|
|
#else
|
|
|
|
NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop),
|
2003-11-11 17:50:58 +00:00
|
|
|
cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy),
|
|
|
|
((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY));
|
2003-11-10 17:44:50 +00:00
|
|
|
#endif
|
|
|
|
NtGdiSelectObject(hdcMem, hOldMem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(DoFlickerFree)
|
|
|
|
NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyWidth, hdcOff, 0, 0, SRCCOPY);
|
|
|
|
|
|
|
|
NtGdiSetTextColor(hdcOff, oldFg);
|
|
|
|
NtGdiSetBkColor(hdcOff, oldBg);
|
|
|
|
#if CANSTRETCHBLT
|
|
|
|
SetStretchBltMode(hdcOff, nStretchMode);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if(DoFlickerFree)
|
|
|
|
{
|
|
|
|
|
2003-12-18 23:04:54 +00:00
|
|
|
NtGdiSelectObject(hdcOff, hOldOffBmp);
|
|
|
|
NtGdiSelectObject(hdcOff, hOldOffBrush);
|
2003-11-10 17:44:50 +00:00
|
|
|
NtGdiDeleteObject(hbmOff);
|
|
|
|
NtGdiDeleteDC(hdcOff);
|
|
|
|
}
|
|
|
|
if(hdcMem)
|
|
|
|
NtGdiDeleteDC(hdcMem);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|