2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: cursoricon.c,v 1.3 2004/12/18 23:55:26 royce Exp $ */
22 PCURICON_OBJECT FASTCALL
23 IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject
, HANDLE Handle
)
25 PCURICON_OBJECT Object
;
28 Status
= ObmReferenceObjectByHandle(WinStaObject
->HandleTable
,
29 Handle
, otCursorIcon
, (PVOID
*)&Object
);
30 if (!NT_SUCCESS(Status
))
37 #define COLORCURSORS_ALLOWED FALSE
39 IntSetCursor(PWINSTATION_OBJECT WinStaObject
, PCURICON_OBJECT NewCursor
,
45 PBITMAPOBJ MaskBmpObj
= NULL
;
46 PSYSTEM_CURSORINFO CurInfo
;
47 PCURICON_OBJECT OldCursor
;
48 HCURSOR Ret
= (HCURSOR
)0;
49 HBITMAP dcbmp
, hColor
= (HBITMAP
)0;
51 SURFOBJ
*soMask
= NULL
, *soColor
= NULL
;
52 XLATEOBJ
*XlateObj
= NULL
;
55 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
56 OldCursor
= CurInfo
->CurrentCursorObject
;
59 Ret
= (HCURSOR
)OldCursor
->Self
;
62 if (!ForceChange
&& OldCursor
== NewCursor
)
68 if(!(Screen
= IntGetScreenDC()))
72 /* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
73 PDC dc
= DC_LockDc(Screen
);
79 dcbmp
= dc
->w
.hBitmap
;
80 DevInfo
= dc
->DevInfo
;
83 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
86 SurfObj
= &BitmapObj
->SurfObj
;
90 if (!NewCursor
&& (CurInfo
->CurrentCursorObject
|| ForceChange
))
92 if (NULL
!= CurInfo
->CurrentCursorObject
&& CurInfo
->ShowingCursor
)
94 /* Remove the cursor if it was displayed */
95 if (GDIDEV(SurfObj
)->Pointer
.MovePointer
)
96 GDIDEV(SurfObj
)->Pointer
.MovePointer(SurfObj
, -1, -1, NULL
);
98 EngMovePointer(SurfObj
, -1, -1, NULL
);
99 GDIDEV(SurfObj
)->Pointer
.Exclude
.right
= -1;
102 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_ACCEPT_NOEXCLUDE
;
104 CurInfo
->CurrentCursorObject
= NewCursor
; /* i.e. CurrentCursorObject = NULL */
105 CurInfo
->ShowingCursor
= 0;
106 BITMAPOBJ_UnlockBitmap(dcbmp
);
112 BITMAPOBJ_UnlockBitmap(dcbmp
);
116 /* TODO: Fixme. Logic is screwed above */
119 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
122 const int maskBpp
= BitsPerFormat(MaskBmpObj
->SurfObj
.iBitmapFormat
);
123 BITMAPOBJ_UnlockBitmap(NewCursor
->IconInfo
.hbmMask
);
126 DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
127 BITMAPOBJ_UnlockBitmap(dcbmp
);
131 if ((DevInfo
->flGraphicsCaps2
& GCAPS2_ALPHACURSOR
) &&
132 SurfObj
->iBitmapFormat
>= BMF_16BPP
&&
133 SurfObj
->iBitmapFormat
<= BMF_32BPP
&&
134 NewCursor
->Shadow
&& COLORCURSORS_ALLOWED
)
136 /* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
137 Do not pass a mask bitmap to DrvSetPointerShape()!
138 Create a XLATEOBJ that describes the colors of the bitmap. */
139 DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
143 if(NewCursor
->IconInfo
.hbmColor
144 && COLORCURSORS_ALLOWED
)
146 /* FIXME - Create a color pointer, create only one 32bit bitmap!
147 Do not pass a mask bitmap to DrvSetPointerShape()!
148 Create a XLATEOBJ that describes the colors of the bitmap.
149 (16bit bitmaps are propably allowed) */
150 DPRINT1("SetCursor: Cursors with colors are not supported!\n");
154 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
157 RECTL DestRect
= {0, 0, MaskBmpObj
->SurfObj
.sizlBitmap
.cx
, MaskBmpObj
->SurfObj
.sizlBitmap
.cy
};
158 POINTL SourcePoint
= {0, 0};
161 * NOTE: For now we create the cursor in top-down bitmap,
162 * because VMware driver rejects it otherwise. This should
165 hMask
= EngCreateBitmap(
166 MaskBmpObj
->SurfObj
.sizlBitmap
, abs(MaskBmpObj
->SurfObj
.lDelta
),
167 MaskBmpObj
->SurfObj
.iBitmapFormat
, BMF_TOPDOWN
,
171 BITMAPOBJ_UnlockBitmap(NewCursor
->IconInfo
.hbmMask
);
172 BITMAPOBJ_UnlockBitmap(dcbmp
);
175 soMask
= EngLockSurface((HSURF
)hMask
);
176 EngCopyBits(soMask
, &MaskBmpObj
->SurfObj
, NULL
, NULL
,
177 &DestRect
, &SourcePoint
);
178 BITMAPOBJ_UnlockBitmap(NewCursor
->IconInfo
.hbmMask
);
182 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
183 CurInfo
->CurrentCursorObject
= NewCursor
;
187 CurInfo
->ShowingCursor
= 0;
188 CurInfo
->CurrentCursorObject
= NULL
;
191 if (GDIDEVFUNCS(SurfObj
).SetPointerShape
)
193 GDIDEV(SurfObj
)->Pointer
.Status
=
194 GDIDEVFUNCS(SurfObj
).SetPointerShape(
195 SurfObj
, soMask
, soColor
, XlateObj
,
196 NewCursor
->IconInfo
.xHotspot
,
197 NewCursor
->IconInfo
.yHotspot
,
202 DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
203 GDIDEV(SurfObj
)->Pointer
.Status
);
207 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_DECLINE
;
210 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_DECLINE
)
212 GDIDEV(SurfObj
)->Pointer
.Status
= EngSetPointerShape(
213 SurfObj
, soMask
, soColor
, XlateObj
,
214 NewCursor
->IconInfo
.xHotspot
,
215 NewCursor
->IconInfo
.yHotspot
,
220 GDIDEV(SurfObj
)->Pointer
.MovePointer
= EngMovePointer
;
224 GDIDEV(SurfObj
)->Pointer
.MovePointer
= GDIDEVFUNCS(SurfObj
).MovePointer
;
227 BITMAPOBJ_UnlockBitmap(dcbmp
);
230 EngUnlockSurface(soMask
);
231 EngDeleteSurface((HSURF
)hMask
);
235 EngDeleteSurface((HSURF
)hColor
);
239 EngDeleteXlate(XlateObj
);
242 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_ERROR
)
243 DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
249 IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject
)
254 PCURICON_OBJECT FASTCALL
255 IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject
, HMODULE hModule
,
256 HRSRC hRsrc
, LONG cx
, LONG cy
)
258 PUSER_HANDLE_TABLE HandleTable
;
259 PLIST_ENTRY CurrentEntry
;
260 PUSER_HANDLE_BLOCK Current
;
261 PCURICON_OBJECT Object
;
264 HandleTable
= (PUSER_HANDLE_TABLE
)WinStaObject
->HandleTable
;
265 ObmpLockHandleTable(HandleTable
);
267 CurrentEntry
= HandleTable
->ListHead
.Flink
;
268 while(CurrentEntry
!= &HandleTable
->ListHead
)
270 Current
= CONTAINING_RECORD(CurrentEntry
, USER_HANDLE_BLOCK
, ListEntry
);
271 for(i
= 0; i
< HANDLE_BLOCK_ENTRIES
; i
++)
273 Object
= (PCURICON_OBJECT
)Current
->Handles
[i
].ObjectBody
;
274 if(Object
&& (ObmReferenceObjectByPointer(Object
, otCursorIcon
) == STATUS_SUCCESS
))
276 if((Object
->hModule
== hModule
) && (Object
->hRsrc
== hRsrc
))
278 if(cx
&& ((cx
!= Object
->Size
.cx
) || (cy
!= Object
->Size
.cy
)))
280 ObmDereferenceObject(Object
);
283 ObmpUnlockHandleTable(HandleTable
);
286 ObmDereferenceObject(Object
);
289 CurrentEntry
= CurrentEntry
->Flink
;
292 ObmpUnlockHandleTable(HandleTable
);
296 PCURICON_OBJECT FASTCALL
297 IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject
)
299 PCURICON_OBJECT Object
;
301 PW32PROCESS Win32Process
;
303 Object
= ObmCreateObject(WinStaObject
->HandleTable
, &Handle
, otCursorIcon
, sizeof(CURICON_OBJECT
));
307 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
311 Win32Process
= PsGetWin32Process();
313 IntLockProcessCursorIcons(Win32Process
);
314 InsertTailList(&Win32Process
->CursorIconListHead
, &Object
->ListEntry
);
315 IntUnLockProcessCursorIcons(Win32Process
);
317 Object
->Self
= Handle
;
318 Object
->Process
= PsGetWin32Process();
324 IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject
, HANDLE Handle
, BOOL RemoveFromProcess
)
326 PSYSTEM_CURSORINFO CurInfo
;
327 PCURICON_OBJECT Object
;
328 HBITMAP bmpMask
, bmpColor
;
332 Status
= ObmReferenceObjectByHandle(WinStaObject
->HandleTable
, Handle
, otCursorIcon
, (PVOID
*)&Object
);
333 if(!NT_SUCCESS(Status
))
338 if (Object
->Process
!= PsGetWin32Process())
340 ObmDereferenceObject(Object
);
344 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
346 if (CurInfo
->CurrentCursorObject
== Object
)
348 /* Hide the cursor if we're destroying the current cursor */
349 IntSetCursor(WinStaObject
, NULL
, TRUE
);
352 bmpMask
= Object
->IconInfo
.hbmMask
;
353 bmpColor
= Object
->IconInfo
.hbmColor
;
355 if (Object
->Process
&& RemoveFromProcess
)
357 IntLockProcessCursorIcons(Object
->Process
);
358 RemoveEntryList(&Object
->ListEntry
);
359 IntUnLockProcessCursorIcons(Object
->Process
);
362 Ret
= NT_SUCCESS(ObmCloseHandle(WinStaObject
->HandleTable
, Handle
));
367 GDIOBJ_SetOwnership(bmpMask
, PsGetCurrentProcess());
368 NtGdiDeleteObject(bmpMask
);
372 GDIOBJ_SetOwnership(bmpColor
, PsGetCurrentProcess());
373 NtGdiDeleteObject(bmpColor
);
376 ObmDereferenceObject(Object
);
382 IntCleanupCurIcons(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
384 PWINSTATION_OBJECT WinStaObject
;
385 PCURICON_OBJECT Current
;
386 PLIST_ENTRY CurrentEntry
, NextEntry
;
388 WinStaObject
= IntGetWinStaObj();
389 if(WinStaObject
!= NULL
)
391 CurrentEntry
= Win32Process
->CursorIconListHead
.Flink
;
392 while(CurrentEntry
!= &Win32Process
->CursorIconListHead
)
394 NextEntry
= CurrentEntry
->Flink
;
395 Current
= CONTAINING_RECORD(CurrentEntry
, CURICON_OBJECT
, ListEntry
);
396 RemoveEntryList(&Current
->ListEntry
);
397 IntDestroyCurIconObject(WinStaObject
, Current
->Self
, FALSE
);
398 CurrentEntry
= NextEntry
;
400 ObDereferenceObject(WinStaObject
);
409 NtUserCreateCursorIconHandle(PICONINFO IconInfo
, BOOL Indirect
)
411 PCURICON_OBJECT CurIconObject
;
412 PWINSTATION_OBJECT WinStaObject
;
417 WinStaObject
= IntGetWinStaObj();
418 if(WinStaObject
== NULL
)
423 CurIconObject
= IntCreateCurIconHandle(WinStaObject
);
426 Ret
= CurIconObject
->Self
;
430 Status
= MmCopyFromCaller(&CurIconObject
->IconInfo
, IconInfo
, sizeof(ICONINFO
));
431 if(NT_SUCCESS(Status
))
435 CurIconObject
->IconInfo
.hbmMask
= BITMAPOBJ_CopyBitmap(CurIconObject
->IconInfo
.hbmMask
);
436 CurIconObject
->IconInfo
.hbmColor
= BITMAPOBJ_CopyBitmap(CurIconObject
->IconInfo
.hbmColor
);
438 if(CurIconObject
->IconInfo
.hbmColor
&&
439 (bmp
= BITMAPOBJ_LockBitmap(CurIconObject
->IconInfo
.hbmColor
)))
441 CurIconObject
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
442 CurIconObject
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
443 BITMAPOBJ_UnlockBitmap(CurIconObject
->IconInfo
.hbmColor
);
444 GDIOBJ_SetOwnership(CurIconObject
->IconInfo
.hbmColor
, NULL
);
448 if(CurIconObject
->IconInfo
.hbmMask
&&
449 (bmp
= BITMAPOBJ_LockBitmap(CurIconObject
->IconInfo
.hbmMask
)))
451 CurIconObject
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
452 CurIconObject
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
453 BITMAPOBJ_UnlockBitmap(CurIconObject
->IconInfo
.hbmMask
);
454 GDIOBJ_SetOwnership(CurIconObject
->IconInfo
.hbmMask
, NULL
);
460 SetLastNtError(Status
);
461 /* FIXME - Don't exit here */
465 ObDereferenceObject(WinStaObject
);
469 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
470 ObDereferenceObject(WinStaObject
);
479 NtUserGetCursorIconInfo(
484 PCURICON_OBJECT CurIconObject
;
485 PWINSTATION_OBJECT WinStaObject
;
489 WinStaObject
= IntGetWinStaObj();
490 if(WinStaObject
== NULL
)
495 CurIconObject
= IntGetCurIconObject(WinStaObject
, Handle
);
500 RtlCopyMemory(&ii
, &CurIconObject
->IconInfo
, sizeof(ICONINFO
));
503 ii
.hbmMask
= BITMAPOBJ_CopyBitmap(ii
.hbmMask
);
504 ii
.hbmColor
= BITMAPOBJ_CopyBitmap(ii
.hbmColor
);
507 Status
= MmCopyToCaller(IconInfo
, &ii
, sizeof(ICONINFO
));
508 if(NT_SUCCESS(Status
))
511 SetLastNtError(Status
);
515 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
518 IntReleaseCurIconObject(CurIconObject
);
519 ObDereferenceObject(WinStaObject
);
523 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
524 ObDereferenceObject(WinStaObject
);
534 NtUserGetCursorIconSize(
539 PCURICON_OBJECT CurIconObject
;
541 PWINSTATION_OBJECT WinStaObject
;
546 WinStaObject
= IntGetWinStaObj();
547 if(WinStaObject
== NULL
)
552 CurIconObject
= IntGetCurIconObject(WinStaObject
, Handle
);
556 Status
= MmCopyToCaller(fIcon
, &CurIconObject
->IconInfo
.fIcon
, sizeof(BOOL
));
557 if(!NT_SUCCESS(Status
))
559 SetLastNtError(Status
);
563 bmp
= BITMAPOBJ_LockBitmap(CurIconObject
->IconInfo
.hbmColor
);
567 SafeSize
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
568 SafeSize
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
569 Status
= MmCopyToCaller(Size
, &SafeSize
, sizeof(SIZE
));
570 if(NT_SUCCESS(Status
))
573 SetLastNtError(Status
);
575 BITMAPOBJ_UnlockBitmap(CurIconObject
->IconInfo
.hbmColor
);
578 IntReleaseCurIconObject(CurIconObject
);
579 ObDereferenceObject(WinStaObject
);
583 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
584 ObDereferenceObject(WinStaObject
);
594 NtUserGetCursorFrameInfo(
615 PSYSTEM_CURSORINFO CurInfo
;
616 PWINSTATION_OBJECT WinStaObject
;
618 PCURICON_OBJECT CursorObject
;
620 Status
= MmCopyFromCaller(&SafeCi
.cbSize
, pci
, sizeof(DWORD
));
621 if(!NT_SUCCESS(Status
))
623 SetLastNtError(Status
);
627 if(SafeCi
.cbSize
!= sizeof(CURSORINFO
))
629 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
633 WinStaObject
= IntGetWinStaObj();
634 if(WinStaObject
== NULL
)
639 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
640 CursorObject
= (PCURICON_OBJECT
)CurInfo
->CurrentCursorObject
;
642 SafeCi
.flags
= ((CurInfo
->ShowingCursor
&& CursorObject
) ? CURSOR_SHOWING
: 0);
643 SafeCi
.hCursor
= (CursorObject
? (HCURSOR
)CursorObject
->Self
: (HCURSOR
)0);
644 SafeCi
.ptScreenPos
.x
= CurInfo
->x
;
645 SafeCi
.ptScreenPos
.y
= CurInfo
->y
;
647 Status
= MmCopyToCaller(pci
, &SafeCi
, sizeof(CURSORINFO
));
648 if(!NT_SUCCESS(Status
))
650 ObDereferenceObject(WinStaObject
);
651 SetLastNtError(Status
);
655 ObDereferenceObject(WinStaObject
);
668 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
670 PWINSTATION_OBJECT WinStaObject
;
671 PSYSTEM_CURSORINFO CurInfo
;
673 PWINDOW_OBJECT DesktopWindow
= NULL
;
675 WinStaObject
= IntGetWinStaObj();
676 if (WinStaObject
== NULL
)
681 if (NULL
!= UnsafeRect
&& ! NT_SUCCESS(MmCopyFromCaller(&Rect
, UnsafeRect
, sizeof(RECT
))))
683 ObDereferenceObject(WinStaObject
);
684 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
688 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
689 if(WinStaObject
->ActiveDesktop
)
690 DesktopWindow
= IntGetWindowObject(WinStaObject
->ActiveDesktop
->DesktopWindow
);
692 if((Rect
.right
> Rect
.left
) && (Rect
.bottom
> Rect
.top
)
693 && DesktopWindow
&& UnsafeRect
!= NULL
)
697 CurInfo
->CursorClipInfo
.IsClipped
= TRUE
;
698 CurInfo
->CursorClipInfo
.Left
= max(Rect
.left
, DesktopWindow
->WindowRect
.left
);
699 CurInfo
->CursorClipInfo
.Top
= max(Rect
.top
, DesktopWindow
->WindowRect
.top
);
700 CurInfo
->CursorClipInfo
.Right
= min(Rect
.right
- 1, DesktopWindow
->WindowRect
.right
- 1);
701 CurInfo
->CursorClipInfo
.Bottom
= min(Rect
.bottom
- 1, DesktopWindow
->WindowRect
.bottom
- 1);
702 IntReleaseWindowObject(DesktopWindow
);
707 mi
.dwFlags
= MOUSEEVENTF_ABSOLUTE
| MOUSEEVENTF_MOVE
;
715 CurInfo
->CursorClipInfo
.IsClipped
= FALSE
;
716 ObDereferenceObject(WinStaObject
);
727 NtUserDestroyCursorIcon(
731 PWINSTATION_OBJECT WinStaObject
;
733 WinStaObject
= IntGetWinStaObj();
734 if(WinStaObject
== NULL
)
739 if(IntDestroyCurIconObject(WinStaObject
, Handle
, TRUE
))
741 ObDereferenceObject(WinStaObject
);
745 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
746 ObDereferenceObject(WinStaObject
);
756 NtUserFindExistingCursorIcon(
762 PCURICON_OBJECT CurIconObject
;
763 PWINSTATION_OBJECT WinStaObject
;
764 HANDLE Ret
= (HANDLE
)0;
766 WinStaObject
= IntGetWinStaObj();
767 if(WinStaObject
== NULL
)
772 CurIconObject
= IntFindExistingCurIconObject(WinStaObject
, hModule
, hRsrc
, cx
, cy
);
775 Ret
= CurIconObject
->Self
;
777 IntReleaseCurIconObject(CurIconObject
);
778 ObDereferenceObject(WinStaObject
);
782 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
783 ObDereferenceObject(WinStaObject
);
796 /* FIXME - check if process has WINSTA_READATTRIBUTES */
797 PSYSTEM_CURSORINFO CurInfo
;
798 PWINSTATION_OBJECT WinStaObject
;
805 WinStaObject
= IntGetWinStaObj();
806 if (WinStaObject
== NULL
)
808 DPRINT("Validation of window station handle (0x%X) failed\n",
809 PROCESS_WINDOW_STATION());
813 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
814 if(CurInfo
->CursorClipInfo
.IsClipped
)
816 Rect
.left
= CurInfo
->CursorClipInfo
.Left
;
817 Rect
.top
= CurInfo
->CursorClipInfo
.Top
;
818 Rect
.right
= CurInfo
->CursorClipInfo
.Right
;
819 Rect
.bottom
= CurInfo
->CursorClipInfo
.Bottom
;
825 Rect
.right
= NtUserGetSystemMetrics(SM_CXSCREEN
);
826 Rect
.bottom
= NtUserGetSystemMetrics(SM_CYSCREEN
);
829 Status
= MmCopyToCaller((PRECT
)lpRect
, &Rect
, sizeof(RECT
));
830 if(!NT_SUCCESS(Status
))
832 ObDereferenceObject(WinStaObject
);
833 SetLastNtError(Status
);
837 ObDereferenceObject(WinStaObject
);
851 PCURICON_OBJECT CurIconObject
;
852 HICON OldCursor
= (HCURSOR
)0;
853 PWINSTATION_OBJECT WinStaObject
;
855 WinStaObject
= IntGetWinStaObj();
856 if(WinStaObject
== NULL
)
861 CurIconObject
= IntGetCurIconObject(WinStaObject
, hCursor
);
864 OldCursor
= IntSetCursor(WinStaObject
, CurIconObject
, FALSE
);
865 IntReleaseCurIconObject(CurIconObject
);
868 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
870 ObDereferenceObject(WinStaObject
);
880 NtUserSetCursorIconContents(
884 PCURICON_OBJECT CurIconObject
;
886 PWINSTATION_OBJECT WinStaObject
;
890 WinStaObject
= IntGetWinStaObj();
891 if(WinStaObject
== NULL
)
896 CurIconObject
= IntGetCurIconObject(WinStaObject
, Handle
);
900 Status
= MmCopyFromCaller(&CurIconObject
->IconInfo
, IconInfo
, sizeof(ICONINFO
));
901 if(!NT_SUCCESS(Status
))
903 SetLastNtError(Status
);
907 bmp
= BITMAPOBJ_LockBitmap(CurIconObject
->IconInfo
.hbmColor
);
910 CurIconObject
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
911 CurIconObject
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
912 BITMAPOBJ_UnlockBitmap(CurIconObject
->IconInfo
.hbmColor
);
913 GDIOBJ_SetOwnership(CurIconObject
->IconInfo
.hbmColor
, NULL
);
917 bmp
= BITMAPOBJ_LockBitmap(CurIconObject
->IconInfo
.hbmMask
);
921 CurIconObject
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
922 CurIconObject
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
924 BITMAPOBJ_UnlockBitmap(CurIconObject
->IconInfo
.hbmMask
);
925 GDIOBJ_SetOwnership(CurIconObject
->IconInfo
.hbmMask
, NULL
);
931 IntReleaseCurIconObject(CurIconObject
);
932 ObDereferenceObject(WinStaObject
);
936 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
937 ObDereferenceObject(WinStaObject
);
947 NtUserSetCursorIconData(
955 PCURICON_OBJECT CurIconObject
;
956 PWINSTATION_OBJECT WinStaObject
;
961 WinStaObject
= IntGetWinStaObj();
962 if(WinStaObject
== NULL
)
967 CurIconObject
= IntGetCurIconObject(WinStaObject
, Handle
);
970 CurIconObject
->hModule
= hModule
;
971 CurIconObject
->hRsrc
= hRsrc
;
972 CurIconObject
->hGroupRsrc
= hGroupRsrc
;
977 Status
= MmCopyFromCaller(&CurIconObject
->IconInfo
.fIcon
, fIcon
, sizeof(BOOL
));
978 if(!NT_SUCCESS(Status
))
980 SetLastNtError(Status
);
992 Status
= MmCopyFromCaller(&SafeHotspot
, Hotspot
, sizeof(POINT
));
993 if(NT_SUCCESS(Status
))
995 CurIconObject
->IconInfo
.xHotspot
= SafeHotspot
.x
;
996 CurIconObject
->IconInfo
.yHotspot
= SafeHotspot
.y
;
1001 SetLastNtError(Status
);
1004 if(!fIcon
&& !Hotspot
)
1010 IntReleaseCurIconObject(CurIconObject
);
1011 ObDereferenceObject(WinStaObject
);
1015 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
1016 ObDereferenceObject(WinStaObject
);
1026 NtUserSetSystemCursor(
1034 #define CANSTRETCHBLT 0
1048 HBRUSH hbrFlickerFreeDraw
,
1053 PCURICON_OBJECT CurIconObject
;
1054 PWINSTATION_OBJECT WinStaObject
;
1055 HBITMAP hbmMask
, hbmColor
;
1056 BITMAP bmpMask
, bmpColor
;
1059 COLORREF oldFg
, oldBg
;
1060 HDC hdcMem
, hdcOff
= (HDC
)0;
1061 HBITMAP hbmOff
= (HBITMAP
)0;
1062 HGDIOBJ hOldOffBrush
= 0, hOldOffBmp
= 0, hOldMem
;
1068 WinStaObject
= IntGetWinStaObj();
1069 if(WinStaObject
== NULL
)
1074 CurIconObject
= IntGetCurIconObject(WinStaObject
, hIcon
);
1077 hbmMask
= CurIconObject
->IconInfo
.hbmMask
;
1078 hbmColor
= CurIconObject
->IconInfo
.hbmColor
;
1079 IntReleaseCurIconObject(CurIconObject
);
1082 DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
1084 if(!hbmMask
|| !IntGdiGetObject(hbmMask
, sizeof(BITMAP
), &bmpMask
))
1087 if(hbmColor
&& !IntGdiGetObject(hbmColor
, sizeof(BITMAP
), &bmpColor
))
1092 IconSize
.cx
= bmpColor
.bmWidth
;
1093 IconSize
.cy
= bmpColor
.bmHeight
;
1097 IconSize
.cx
= bmpMask
.bmWidth
;
1098 IconSize
.cy
= bmpMask
.bmHeight
/ 2;
1102 diFlags
= DI_NORMAL
;
1105 cxWidth
= ((diFlags
& DI_DEFAULTSIZE
) ? NtUserGetSystemMetrics(SM_CXICON
) : IconSize
.cx
);
1107 cyWidth
= ((diFlags
& DI_DEFAULTSIZE
) ? NtUserGetSystemMetrics(SM_CYICON
) : IconSize
.cy
);
1109 DoFlickerFree
= (hbrFlickerFreeDraw
&& (NtGdiGetObjectType(hbrFlickerFreeDraw
) == OBJ_BRUSH
));
1117 hdcOff
= NtGdiCreateCompatableDC(hdc
);
1121 hbmOff
= NtGdiCreateCompatibleBitmap(hdc
, cxWidth
, cyWidth
);
1124 NtGdiDeleteDC(hdcOff
);
1127 hOldOffBrush
= NtGdiSelectObject(hdcOff
, hbrFlickerFreeDraw
);
1128 hOldOffBmp
= NtGdiSelectObject(hdcOff
, hbmOff
);
1129 NtGdiPatBlt(hdcOff
, 0, 0, r
.right
, r
.bottom
, PATCOPY
);
1130 NtGdiSelectObject(hdcOff
, hbmOff
);
1133 hdcMem
= NtGdiCreateCompatableDC(hdc
);
1141 nStretchMode
= NtGdiSetStretchBltMode(hdcOff
, STRETCH_DELETESCANS
);
1143 oldFg
= NtGdiSetTextColor(hdcOff
, RGB(0, 0, 0));
1144 oldBg
= NtGdiSetBkColor(hdcOff
, RGB(255, 255, 255));
1146 if(diFlags
& DI_MASK
)
1148 hOldMem
= NtGdiSelectObject(hdcMem
, hbmMask
);
1150 NtGdiStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1151 cxWidth
, cyWidth
, hdcMem
, 0, 0, IconSize
.cx
, IconSize
.cy
,
1152 ((diFlags
& DI_IMAGE
) ? SRCAND
: SRCCOPY
));
1154 NtGdiBitBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1155 cxWidth
, cyWidth
, hdcMem
, 0, 0, ((diFlags
& DI_IMAGE
) ? SRCAND
: SRCCOPY
));
1157 if(!hbmColor
&& (bmpMask
.bmHeight
== 2 * bmpMask
.bmWidth
) && (diFlags
& DI_IMAGE
))
1160 NtGdiStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1161 cxWidth
, cyWidth
, hdcMem
, 0, IconSize
.cy
, IconSize
.cx
, IconSize
.cy
, SRCINVERT
);
1163 NtGdiBitBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1164 cxWidth
, cyWidth
, hdcMem
, 0, IconSize
.cy
, SRCINVERT
);
1166 diFlags
&= ~DI_IMAGE
;
1168 NtGdiSelectObject(hdcMem
, hOldMem
);
1171 if(diFlags
& DI_IMAGE
)
1173 hOldMem
= NtGdiSelectObject(hdcMem
, (hbmColor
? hbmColor
: hbmMask
));
1175 NtGdiStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1176 cxWidth
, cyWidth
, hdcMem
, 0, (hbmColor
? 0 : IconSize
.cy
),
1177 IconSize
.cx
, IconSize
.cy
, ((diFlags
& DI_MASK
) ? SRCINVERT
: SRCCOPY
));
1179 NtGdiBitBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
), (DoFlickerFree
? 0 : yTop
),
1180 cxWidth
, cyWidth
, hdcMem
, 0, (hbmColor
? 0 : IconSize
.cy
),
1181 ((diFlags
& DI_MASK
) ? SRCINVERT
: SRCCOPY
));
1183 NtGdiSelectObject(hdcMem
, hOldMem
);
1187 NtGdiBitBlt(hdc
, xLeft
, yTop
, cxWidth
, cyWidth
, hdcOff
, 0, 0, SRCCOPY
);
1189 NtGdiSetTextColor(hdcOff
, oldFg
);
1190 NtGdiSetBkColor(hdcOff
, oldBg
);
1192 SetStretchBltMode(hdcOff
, nStretchMode
);
1201 NtGdiSelectObject(hdcOff
, hOldOffBmp
);
1202 NtGdiSelectObject(hdcOff
, hOldOffBrush
);
1203 NtGdiDeleteObject(hbmOff
);
1204 NtGdiDeleteDC(hdcOff
);
1207 NtGdiDeleteDC(hdcMem
);
1210 ObDereferenceObject(WinStaObject
);
1215 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
1216 ObDereferenceObject(WinStaObject
);