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.
21 * We handle two types of cursors/icons:
23 * Loaded without LR_SHARED flag
24 * Private to a process
25 * Can be deleted by calling NtDestroyCursorIcon()
26 * CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc set to NULL
28 * Loaded with LR_SHARED flag
29 * Possibly shared by multiple processes
30 * Immune to NtDestroyCursorIcon()
31 * CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc are valid
32 * There's a M:N relationship between processes and (shared) cursor/icons.
33 * A process can have multiple cursor/icons and a cursor/icon can be used
34 * by multiple processes. To keep track of this we keep a list of all
35 * cursor/icons (CurIconList) and per cursor/icon we keep a list of
36 * CURICON_PROCESS structs starting at CurIcon->ProcessList.
44 static PAGED_LOOKASIDE_LIST gProcessLookasideList
;
45 static LIST_ENTRY gCurIconList
;
48 IntGetCursorLocation(PWINSTATION_OBJECT WinSta
, POINT
*loc
)
50 loc
->x
= gpsi
->ptCursor
.x
;
51 loc
->y
= gpsi
->ptCursor
.y
;
56 /* This function creates a reference for the object! */
57 PCURICON_OBJECT FASTCALL
UserGetCurIconObject(HCURSOR hCurIcon
)
59 PCURICON_OBJECT CurIcon
;
63 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
67 CurIcon
= (PCURICON_OBJECT
)UserReferenceObjectByHandle(hCurIcon
, otCursorIcon
);
70 /* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
71 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
75 ASSERT(USER_BODY_TO_HEADER(CurIcon
)->RefCount
>= 1);
80 #define COLORCURSORS_ALLOWED FALSE
82 IntSetCursor(PWINSTATION_OBJECT WinSta
, PCURICON_OBJECT NewCursor
,
88 PBITMAPOBJ MaskBmpObj
= NULL
;
89 PSYSTEM_CURSORINFO CurInfo
;
90 PCURICON_OBJECT OldCursor
;
91 HCURSOR Ret
= (HCURSOR
)0;
94 SURFOBJ
*soMask
= NULL
, *soColor
= NULL
;
95 XLATEOBJ
*XlateObj
= NULL
;
99 CurInfo
= IntGetSysCursorInfo(WinSta
);
100 OldCursor
= CurInfo
->CurrentCursorObject
;
103 Ret
= (HCURSOR
)OldCursor
->Self
;
106 if (!ForceChange
&& OldCursor
== NewCursor
)
111 if(!(Screen
= IntGetScreenDC()))
115 /* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
116 dc
= DC_LockDc(Screen
);
122 dcbmp
= dc
->w
.hBitmap
;
123 DevInfo
= (PDEVINFO
)&((GDIDEVICE
*)dc
->pPDev
)->DevInfo
;
126 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
129 SurfObj
= &BitmapObj
->SurfObj
;
133 if (CurInfo
->CurrentCursorObject
|| ForceChange
)
135 if (CurInfo
->CurrentCursorObject
)
137 UserDereferenceObject(CurInfo
->CurrentCursorObject
);
138 if (CurInfo
->ShowingCursor
)
140 DPRINT1("Removing pointer!\n");
141 /* Remove the cursor if it was displayed */
142 IntEngMovePointer(SurfObj
, -1, -1, &GDIDEV(SurfObj
)->Pointer
.Exclude
);
146 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_ACCEPT_NOEXCLUDE
;
148 CurInfo
->CurrentCursorObject
= NewCursor
; /* i.e. CurrentCursorObject = NULL */
149 CurInfo
->ShowingCursor
= 0;
152 BITMAPOBJ_UnlockBitmap(BitmapObj
);
156 /* TODO: Fixme. Logic is screwed above */
158 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
161 const int maskBpp
= BitsPerFormat(MaskBmpObj
->SurfObj
.iBitmapFormat
);
162 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
165 DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
166 BITMAPOBJ_UnlockBitmap(BitmapObj
);
170 if ((DevInfo
->flGraphicsCaps2
& GCAPS2_ALPHACURSOR
) &&
171 SurfObj
->iBitmapFormat
>= BMF_16BPP
&&
172 SurfObj
->iBitmapFormat
<= BMF_32BPP
&&
173 NewCursor
->Shadow
&& COLORCURSORS_ALLOWED
)
175 /* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
176 Do not pass a mask bitmap to DrvSetPointerShape()!
177 Create a XLATEOBJ that describes the colors of the bitmap. */
178 DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
182 if(NewCursor
->IconInfo
.hbmColor
183 && COLORCURSORS_ALLOWED
)
185 /* FIXME - Create a color pointer, create only one 32bit bitmap!
186 Do not pass a mask bitmap to DrvSetPointerShape()!
187 Create a XLATEOBJ that describes the colors of the bitmap.
188 (16bit bitmaps are propably allowed) */
189 DPRINT1("SetCursor: Cursors with colors are not supported!\n");
193 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
196 RECTL DestRect
= {0, 0, MaskBmpObj
->SurfObj
.sizlBitmap
.cx
, MaskBmpObj
->SurfObj
.sizlBitmap
.cy
};
197 POINTL SourcePoint
= {0, 0};
200 * NOTE: For now we create the cursor in top-down bitmap,
201 * because VMware driver rejects it otherwise. This should
204 hMask
= EngCreateBitmap(
205 MaskBmpObj
->SurfObj
.sizlBitmap
, abs(MaskBmpObj
->SurfObj
.lDelta
),
206 MaskBmpObj
->SurfObj
.iBitmapFormat
, BMF_TOPDOWN
,
210 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
211 BITMAPOBJ_UnlockBitmap(BitmapObj
);
214 soMask
= EngLockSurface((HSURF
)hMask
);
215 EngCopyBits(soMask
, &MaskBmpObj
->SurfObj
, NULL
, NULL
,
216 &DestRect
, &SourcePoint
);
217 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
221 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
222 CurInfo
->CurrentCursorObject
= NewCursor
;
223 UserReferenceObject(NewCursor
);
227 CurInfo
->ShowingCursor
= 0;
228 CurInfo
->CurrentCursorObject
= NULL
;
231 /* OldCursor is not in use anymore */
234 UserDereferenceObject(OldCursor
);
237 if (GDIDEVFUNCS(SurfObj
).SetPointerShape
)
239 GDIDEV(SurfObj
)->Pointer
.Status
=
240 GDIDEVFUNCS(SurfObj
).SetPointerShape(
241 SurfObj
, soMask
, soColor
, XlateObj
,
242 NewCursor
->IconInfo
.xHotspot
,
243 NewCursor
->IconInfo
.yHotspot
,
246 &(GDIDEV(SurfObj
)->Pointer
.Exclude
),
248 DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
249 GDIDEV(SurfObj
)->Pointer
.Status
);
253 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_DECLINE
;
256 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_DECLINE
)
258 GDIDEV(SurfObj
)->Pointer
.Status
= EngSetPointerShape(
259 SurfObj
, soMask
, soColor
, XlateObj
,
260 NewCursor
->IconInfo
.xHotspot
,
261 NewCursor
->IconInfo
.yHotspot
,
264 &(GDIDEV(SurfObj
)->Pointer
.Exclude
),
266 GDIDEV(SurfObj
)->Pointer
.MovePointer
= NULL
;
270 GDIDEV(SurfObj
)->Pointer
.MovePointer
= GDIDEVFUNCS(SurfObj
).MovePointer
;
273 BITMAPOBJ_UnlockBitmap(BitmapObj
);
276 EngUnlockSurface(soMask
);
277 EngDeleteSurface((HSURF
)hMask
);
281 EngDeleteXlate(XlateObj
);
284 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_ERROR
)
285 DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
291 IntSetupCurIconHandles(PWINSTATION_OBJECT WinSta
)
293 ExInitializePagedLookasideList(&gProcessLookasideList
,
297 sizeof(CURICON_PROCESS
),
300 InitializeListHead(&gCurIconList
);
306 * We have to register that this object is in use by the current
307 * process. The only way to do that seems to be to walk the list
308 * of cursor/icon objects starting at W32Process->CursorIconListHead.
309 * If the object is already present in the list, we don't have to do
310 * anything, if it's not present we add it and inc the ProcessCount
311 * in the object. Having to walk the list kind of sucks, but that's
314 static BOOLEAN FASTCALL
315 ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon
)
317 PW32PROCESS Win32Process
;
318 PCURICON_PROCESS Current
;
320 Win32Process
= PsGetCurrentProcessWin32Process();
322 LIST_FOR_EACH(Current
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
324 if (Current
->Process
== Win32Process
)
326 /* Already registered for this process */
331 /* Not registered yet */
332 Current
= ExAllocateFromPagedLookasideList(&gProcessLookasideList
);
337 InsertHeadList(&CurIcon
->ProcessList
, &Current
->ListEntry
);
338 Current
->Process
= Win32Process
;
343 PCURICON_OBJECT FASTCALL
344 IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta
, HMODULE hModule
,
345 HRSRC hRsrc
, LONG cx
, LONG cy
)
347 PCURICON_OBJECT CurIcon
;
349 LIST_FOR_EACH(CurIcon
, &gCurIconList
, CURICON_OBJECT
, ListEntry
)
352 // if(NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
353 // UserReferenceObject( CurIcon);
355 if((CurIcon
->hModule
== hModule
) && (CurIcon
->hRsrc
== hRsrc
))
357 if(cx
&& ((cx
!= CurIcon
->Size
.cx
) || (cy
!= CurIcon
->Size
.cy
)))
359 // UserDereferenceObject(CurIcon);
362 if (! ReferenceCurIconByProcess(CurIcon
))
370 // UserDereferenceObject(CurIcon);
377 PCURICON_OBJECT FASTCALL
378 IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta
)
380 PCURICON_OBJECT CurIcon
;
383 CurIcon
= UserCreateObject(gHandleTable
, &hCurIcon
, otCursorIcon
, sizeof(CURICON_OBJECT
));
387 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
391 CurIcon
->Self
= hCurIcon
;
392 InitializeListHead(&CurIcon
->ProcessList
);
394 if (! ReferenceCurIconByProcess(CurIcon
))
396 DPRINT1("Failed to add process\n");
397 UserDeleteObject(hCurIcon
, otCursorIcon
);
398 UserDereferenceObject(CurIcon
);
402 InsertHeadList(&gCurIconList
, &CurIcon
->ListEntry
);
408 IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta
, PCURICON_OBJECT CurIcon
, BOOL ProcessCleanup
)
410 PSYSTEM_CURSORINFO CurInfo
;
411 HBITMAP bmpMask
, bmpColor
;
413 PCURICON_PROCESS Current
= NULL
;
414 PW32PROCESS W32Process
= PsGetCurrentProcessWin32Process();
416 /* Private objects can only be destroyed by their own process */
417 if (NULL
== CurIcon
->hModule
)
419 ASSERT(CurIcon
->ProcessList
.Flink
->Flink
== &CurIcon
->ProcessList
);
420 Current
= CONTAINING_RECORD(CurIcon
->ProcessList
.Flink
, CURICON_PROCESS
, ListEntry
);
421 if (Current
->Process
!= W32Process
)
423 DPRINT1("Trying to destroy private icon/cursor of another process\n");
427 else if (! ProcessCleanup
)
429 DPRINT("Trying to destroy shared icon/cursor\n");
433 /* Now find this process in the list of processes referencing this object and
434 remove it from that list */
435 LIST_FOR_EACH(Current
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
437 if (Current
->Process
== W32Process
)
439 RemoveEntryList(&Current
->ListEntry
);
444 ExFreeToPagedLookasideList(&gProcessLookasideList
, Current
);
446 /* If there are still processes referencing this object we can't destroy it yet */
447 if (! IsListEmpty(&CurIcon
->ProcessList
))
453 if (! ProcessCleanup
)
455 RemoveEntryList(&CurIcon
->ListEntry
);
458 CurInfo
= IntGetSysCursorInfo(WinSta
);
460 if (CurInfo
->CurrentCursorObject
== CurIcon
)
462 /* Hide the cursor if we're destroying the current cursor */
463 IntSetCursor(WinSta
, NULL
, TRUE
);
466 bmpMask
= CurIcon
->IconInfo
.hbmMask
;
467 bmpColor
= CurIcon
->IconInfo
.hbmColor
;
472 GDIOBJ_SetOwnership(bmpMask
, PsGetCurrentProcess());
473 NtGdiDeleteObject(bmpMask
);
474 CurIcon
->IconInfo
.hbmMask
= NULL
;
478 GDIOBJ_SetOwnership(bmpColor
, PsGetCurrentProcess());
479 NtGdiDeleteObject(bmpColor
);
480 CurIcon
->IconInfo
.hbmColor
= NULL
;
483 /* We were given a pointer, no need to keep the reference anylonger! */
484 UserDereferenceObject(CurIcon
);
485 Ret
= UserDeleteObject(CurIcon
->Self
, otCursorIcon
);
491 IntCleanupCurIcons(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
493 PWINSTATION_OBJECT WinSta
;
494 PCURICON_OBJECT CurIcon
, tmp
;
495 PCURICON_PROCESS ProcessData
;
497 WinSta
= IntGetWinStaObj();
503 LIST_FOR_EACH_SAFE(CurIcon
, tmp
, &gCurIconList
, CURICON_OBJECT
, ListEntry
)
505 UserReferenceObject(CurIcon
);
506 // if(NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon)))
508 LIST_FOR_EACH(ProcessData
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
510 if (Win32Process
== ProcessData
->Process
)
512 RemoveEntryList(&CurIcon
->ListEntry
);
513 IntDestroyCurIconObject(WinSta
, CurIcon
, TRUE
);
519 // UserDereferenceObject(Object);
524 UserDereferenceObject(CurIcon
);
528 ObDereferenceObject(WinSta
);
536 NtUserCreateCursorIconHandle(PICONINFO IconInfo OPTIONAL
, BOOL Indirect
)
538 PCURICON_OBJECT CurIcon
;
539 PWINSTATION_OBJECT WinSta
;
543 DECLARE_RETURN(HANDLE
);
545 DPRINT("Enter NtUserCreateCursorIconHandle\n");
546 UserEnterExclusive();
548 WinSta
= IntGetWinStaObj();
554 if (!(CurIcon
= IntCreateCurIconHandle(WinSta
)))
556 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
557 ObDereferenceObject(WinSta
);
565 Status
= MmCopyFromCaller(&CurIcon
->IconInfo
, IconInfo
, sizeof(ICONINFO
));
566 if(NT_SUCCESS(Status
))
570 CurIcon
->IconInfo
.hbmMask
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmMask
);
571 CurIcon
->IconInfo
.hbmColor
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmColor
);
573 if(CurIcon
->IconInfo
.hbmColor
&&
574 (bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
)))
576 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
577 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
578 BITMAPOBJ_UnlockBitmap(bmp
);
579 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmColor
, NULL
);
581 if(CurIcon
->IconInfo
.hbmMask
&&
582 (bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
)))
584 if (CurIcon
->IconInfo
.hbmColor
== NULL
)
586 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
587 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
589 BITMAPOBJ_UnlockBitmap(bmp
);
590 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmMask
, NULL
);
595 SetLastNtError(Status
);
596 /* FIXME - Don't exit here */
600 UserDereferenceObject(CurIcon
);
601 ObDereferenceObject(WinSta
);
605 DPRINT("Leave NtUserCreateCursorIconHandle, ret=%i\n",_ret_
);
618 PUNICODE_STRING lpInstName
, // optional
619 PUNICODE_STRING lpResName
, // optional
620 LPDWORD pbpp
, // optional
624 PCURICON_OBJECT CurIcon
;
625 PWINSTATION_OBJECT WinSta
;
626 NTSTATUS Status
= STATUS_SUCCESS
;
628 DECLARE_RETURN(BOOL
);
630 DPRINT("Enter NtUserGetIconInfo\n");
631 UserEnterExclusive();
635 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
639 WinSta
= IntGetWinStaObj();
645 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
647 ObDereferenceObject(WinSta
);
651 RtlCopyMemory(&ii
, &CurIcon
->IconInfo
, sizeof(ICONINFO
));
654 ii
.hbmMask
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmMask
);
655 ii
.hbmColor
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmColor
);
660 ProbeForWrite(IconInfo
, sizeof(ICONINFO
), 1);
661 RtlCopyMemory(IconInfo
, &ii
, sizeof(ICONINFO
));
668 ProbeForWrite(pbpp
, sizeof(DWORD
), 1);
670 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
);
673 colorBpp
= BitsPerFormat(bmp
->SurfObj
.iBitmapFormat
);
674 BITMAPOBJ_UnlockBitmap(bmp
);
677 RtlCopyMemory(pbpp
, &colorBpp
, sizeof(DWORD
));
681 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
683 Status
= _SEH2_GetExceptionCode();
687 if (NT_SUCCESS(Status
))
690 SetLastNtError(Status
);
692 UserDereferenceObject(CurIcon
);
693 ObDereferenceObject(WinSta
);
697 DPRINT("Leave NtUserGetIconInfo, ret=%i\n",_ret_
);
711 PLONG plcx
, // &size.cx
712 PLONG plcy
) // &size.cy
714 PCURICON_OBJECT CurIcon
;
715 NTSTATUS Status
= STATUS_SUCCESS
;
718 DPRINT("Enter NtUserGetIconSize\n");
719 UserEnterExclusive();
721 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
728 ProbeForWrite(plcx
, sizeof(LONG
), 1);
729 RtlCopyMemory(plcx
, &CurIcon
->Size
.cx
, sizeof(LONG
));
730 ProbeForWrite(plcy
, sizeof(LONG
), 1);
731 RtlCopyMemory(plcy
, &CurIcon
->Size
.cy
, sizeof(LONG
));
733 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
735 Status
= _SEH2_GetExceptionCode();
739 if(NT_SUCCESS(Status
))
742 SetLastNtError(Status
); // maybe not, test this
744 UserDereferenceObject(CurIcon
);
747 DPRINT("Leave NtUserGetIconSize, ret=%i\n", bRet
);
758 NtUserGetCursorFrameInfo(
779 PSYSTEM_CURSORINFO CurInfo
;
780 PWINSTATION_OBJECT WinSta
;
781 NTSTATUS Status
= STATUS_SUCCESS
;
782 PCURICON_OBJECT CurIcon
;
784 DECLARE_RETURN(BOOL
);
786 DPRINT("Enter NtUserGetCursorInfo\n");
787 UserEnterExclusive();
789 WinSta
= IntGetWinStaObj();
795 CurInfo
= IntGetSysCursorInfo(WinSta
);
796 CurIcon
= (PCURICON_OBJECT
)CurInfo
->CurrentCursorObject
;
798 SafeCi
.cbSize
= sizeof(CURSORINFO
);
799 SafeCi
.flags
= ((CurInfo
->ShowingCursor
&& CurIcon
) ? CURSOR_SHOWING
: 0);
800 SafeCi
.hCursor
= (CurIcon
? (HCURSOR
)CurIcon
->Self
: (HCURSOR
)0);
802 IntGetCursorLocation(WinSta
, &SafeCi
.ptScreenPos
);
806 if (pci
->cbSize
== sizeof(CURSORINFO
))
808 ProbeForWrite(pci
, sizeof(CURSORINFO
), 1);
809 RtlCopyMemory(pci
, &SafeCi
, sizeof(CURSORINFO
));
814 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
817 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
819 Status
= _SEH2_GetExceptionCode();
822 if (!NT_SUCCESS(Status
))
824 SetLastNtError(Status
);
827 ObDereferenceObject(WinSta
);
831 DPRINT("Leave NtUserGetCursorInfo, ret=%i\n",_ret_
);
845 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
847 PWINSTATION_OBJECT WinSta
;
848 PSYSTEM_CURSORINFO CurInfo
;
850 PWINDOW_OBJECT DesktopWindow
= NULL
;
851 POINT MousePos
= {0};
852 DECLARE_RETURN(BOOL
);
854 DPRINT("Enter NtUserClipCursor\n");
855 UserEnterExclusive();
857 WinSta
= IntGetWinStaObj();
863 if (NULL
!= UnsafeRect
&& ! NT_SUCCESS(MmCopyFromCaller(&Rect
, UnsafeRect
, sizeof(RECT
))))
865 ObDereferenceObject(WinSta
);
866 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
870 CurInfo
= IntGetSysCursorInfo(WinSta
);
871 IntGetCursorLocation(WinSta
, &MousePos
);
873 if(WinSta
->ActiveDesktop
)
874 DesktopWindow
= UserGetWindowObject(WinSta
->ActiveDesktop
->DesktopWindow
);
876 if((Rect
.right
> Rect
.left
) && (Rect
.bottom
> Rect
.top
)
877 && DesktopWindow
&& UnsafeRect
!= NULL
)
881 CurInfo
->CursorClipInfo
.IsClipped
= TRUE
;
882 CurInfo
->CursorClipInfo
.Left
= max(Rect
.left
, DesktopWindow
->Wnd
->WindowRect
.left
);
883 CurInfo
->CursorClipInfo
.Top
= max(Rect
.top
, DesktopWindow
->Wnd
->WindowRect
.top
);
884 CurInfo
->CursorClipInfo
.Right
= min(Rect
.right
- 1, DesktopWindow
->Wnd
->WindowRect
.right
- 1);
885 CurInfo
->CursorClipInfo
.Bottom
= min(Rect
.bottom
- 1, DesktopWindow
->Wnd
->WindowRect
.bottom
- 1);
890 mi
.dwFlags
= MOUSEEVENTF_ABSOLUTE
| MOUSEEVENTF_MOVE
;
898 CurInfo
->CursorClipInfo
.IsClipped
= FALSE
;
899 ObDereferenceObject(WinSta
);
904 DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_
);
919 PWINSTATION_OBJECT WinSta
;
920 PCURICON_OBJECT CurIcon
;
922 DECLARE_RETURN(BOOL
);
924 DPRINT("Enter NtUserDestroyCursorIcon\n");
925 UserEnterExclusive();
927 WinSta
= IntGetWinStaObj();
933 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
935 ObDereferenceObject(WinSta
);
939 ret
= IntDestroyCurIconObject(WinSta
, CurIcon
, FALSE
);
940 /* Note: IntDestroyCurIconObject will remove our reference for us! */
942 ObDereferenceObject(WinSta
);
946 DPRINT("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_
);
957 NtUserFindExistingCursorIcon(
963 PCURICON_OBJECT CurIcon
;
964 PWINSTATION_OBJECT WinSta
;
965 HANDLE Ret
= (HANDLE
)0;
966 DECLARE_RETURN(HICON
);
968 DPRINT("Enter NtUserFindExistingCursorIcon\n");
969 UserEnterExclusive();
971 WinSta
= IntGetWinStaObj();
977 CurIcon
= IntFindExistingCurIconObject(WinSta
, hModule
, hRsrc
, cx
, cy
);
982 // IntReleaseCurIconObject(CurIcon);//faxme: is this correct? does IntFindExistingCurIconObject add a ref?
983 ObDereferenceObject(WinSta
);
987 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
988 ObDereferenceObject(WinSta
);
992 DPRINT("Leave NtUserFindExistingCursorIcon, ret=%i\n",_ret_
);
1003 NtUserGetClipCursor(
1006 /* FIXME - check if process has WINSTA_READATTRIBUTES */
1007 PSYSTEM_CURSORINFO CurInfo
;
1008 PWINSTATION_OBJECT WinSta
;
1011 DECLARE_RETURN(BOOL
);
1013 DPRINT("Enter NtUserGetClipCursor\n");
1014 UserEnterExclusive();
1019 WinSta
= IntGetWinStaObj();
1025 CurInfo
= IntGetSysCursorInfo(WinSta
);
1026 if(CurInfo
->CursorClipInfo
.IsClipped
)
1028 Rect
.left
= CurInfo
->CursorClipInfo
.Left
;
1029 Rect
.top
= CurInfo
->CursorClipInfo
.Top
;
1030 Rect
.right
= CurInfo
->CursorClipInfo
.Right
;
1031 Rect
.bottom
= CurInfo
->CursorClipInfo
.Bottom
;
1037 Rect
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
1038 Rect
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
1041 Status
= MmCopyToCaller((PRECT
)lpRect
, &Rect
, sizeof(RECT
));
1042 if(!NT_SUCCESS(Status
))
1044 ObDereferenceObject(WinSta
);
1045 SetLastNtError(Status
);
1049 ObDereferenceObject(WinSta
);
1054 DPRINT("Leave NtUserGetClipCursor, ret=%i\n",_ret_
);
1068 PCURICON_OBJECT CurIcon
;
1070 PWINSTATION_OBJECT WinSta
;
1071 DECLARE_RETURN(HCURSOR
);
1073 DPRINT("Enter NtUserSetCursor\n");
1074 UserEnterExclusive();
1076 WinSta
= IntGetWinStaObj();
1084 if(!(CurIcon
= UserGetCurIconObject(hCursor
)))
1086 ObDereferenceObject(WinSta
);
1095 OldCursor
= IntSetCursor(WinSta
, CurIcon
, FALSE
);
1099 UserDereferenceObject(CurIcon
);
1101 ObDereferenceObject(WinSta
);
1106 DPRINT("Leave NtUserSetCursor, ret=%i\n",_ret_
);
1117 NtUserSetCursorContents(
1119 PICONINFO UnsafeIconInfo
)
1121 PCURICON_OBJECT CurIcon
;
1124 PWINSTATION_OBJECT WinSta
;
1127 DECLARE_RETURN(BOOL
);
1129 DPRINT("Enter NtUserSetCursorContents\n");
1130 UserEnterExclusive();
1132 WinSta
= IntGetWinStaObj();
1138 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
1140 ObDereferenceObject(WinSta
);
1145 Status
= MmCopyFromCaller(&IconInfo
, UnsafeIconInfo
, sizeof(ICONINFO
));
1146 if(!NT_SUCCESS(Status
))
1148 SetLastNtError(Status
);
1152 /* Delete old bitmaps */
1153 if (CurIcon
->IconInfo
.hbmColor
!= IconInfo
.hbmColor
)
1155 NtGdiDeleteObject(CurIcon
->IconInfo
.hbmColor
);
1157 if (CurIcon
->IconInfo
.hbmMask
!= IconInfo
.hbmMask
)
1159 NtGdiDeleteObject(CurIcon
->IconInfo
.hbmMask
);
1162 /* Copy new IconInfo field */
1163 CurIcon
->IconInfo
= IconInfo
;
1165 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
);
1168 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
1169 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
1170 BITMAPOBJ_UnlockBitmap(bmp
);
1171 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmColor
, NULL
);
1175 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
);
1179 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
1180 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
1182 BITMAPOBJ_UnlockBitmap(bmp
);
1183 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmMask
, NULL
);
1192 UserDereferenceObject(CurIcon
);
1194 ObDereferenceObject(WinSta
);
1198 DPRINT("Leave NtUserSetCursorContents, ret=%i\n",_ret_
);
1210 NtUserSetCursorIconData(
1213 PUNICODE_STRING pstrResName
,
1214 PICONINFO pIconInfo
)
1216 PCURICON_OBJECT CurIcon
;
1217 PWINSTATION_OBJECT WinSta
;
1219 NTSTATUS Status
= STATUS_SUCCESS
;
1221 DECLARE_RETURN(BOOL
);
1223 DPRINT("Enter NtUserSetCursorIconData\n");
1224 UserEnterExclusive();
1226 WinSta
= IntGetWinStaObj();
1232 if(!(CurIcon
= UserGetCurIconObject(Handle
)))
1234 ObDereferenceObject(WinSta
);
1238 CurIcon
->hModule
= hModule
;
1239 CurIcon
->hRsrc
= NULL
; //hRsrc;
1240 CurIcon
->hGroupRsrc
= NULL
; //hGroupRsrc;
1244 ProbeForRead(pIconInfo
, sizeof(ICONINFO
), 1);
1245 RtlCopyMemory(&CurIcon
->IconInfo
, pIconInfo
, sizeof(ICONINFO
));
1247 CurIcon
->IconInfo
.hbmMask
= BITMAPOBJ_CopyBitmap(pIconInfo
->hbmMask
);
1248 CurIcon
->IconInfo
.hbmColor
= BITMAPOBJ_CopyBitmap(pIconInfo
->hbmColor
);
1250 if (CurIcon
->IconInfo
.hbmColor
)
1252 if ((pBmpObj
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
)))
1254 CurIcon
->Size
.cx
= pBmpObj
->SurfObj
.sizlBitmap
.cx
;
1255 CurIcon
->Size
.cy
= pBmpObj
->SurfObj
.sizlBitmap
.cy
;
1256 BITMAPOBJ_UnlockBitmap(pBmpObj
);
1257 GDIOBJ_SetOwnership(GdiHandleTable
, CurIcon
->IconInfo
.hbmMask
, NULL
);
1260 if (CurIcon
->IconInfo
.hbmMask
)
1262 if (CurIcon
->IconInfo
.hbmColor
== NULL
)
1264 if ((pBmpObj
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
)))
1266 CurIcon
->Size
.cx
= pBmpObj
->SurfObj
.sizlBitmap
.cx
;
1267 CurIcon
->Size
.cy
= pBmpObj
->SurfObj
.sizlBitmap
.cy
;
1268 BITMAPOBJ_UnlockBitmap(pBmpObj
);
1271 GDIOBJ_SetOwnership(GdiHandleTable
, CurIcon
->IconInfo
.hbmMask
, NULL
);
1274 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1276 Status
= _SEH2_GetExceptionCode();
1280 if(!NT_SUCCESS(Status
))
1281 SetLastNtError(Status
);
1285 UserDereferenceObject(CurIcon
);
1286 ObDereferenceObject(WinSta
);
1290 DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_
);
1297 NtUserSetCursorIconData(
1305 PCURICON_OBJECT CurIcon
;
1306 PWINSTATION_OBJECT WinSta
;
1310 DECLARE_RETURN(BOOL
);
1312 DPRINT("Enter NtUserSetCursorIconData\n");
1313 UserEnterExclusive();
1315 WinSta
= IntGetWinStaObj();
1321 if(!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
1323 ObDereferenceObject(WinSta
);
1327 CurIcon
->hModule
= hModule
;
1328 CurIcon
->hRsrc
= hRsrc
;
1329 CurIcon
->hGroupRsrc
= hGroupRsrc
;
1334 Status
= MmCopyFromCaller(&CurIcon
->IconInfo
.fIcon
, fIcon
, sizeof(BOOL
));
1335 if(!NT_SUCCESS(Status
))
1337 SetLastNtError(Status
);
1349 Status
= MmCopyFromCaller(&SafeHotspot
, Hotspot
, sizeof(POINT
));
1350 if(NT_SUCCESS(Status
))
1352 CurIcon
->IconInfo
.xHotspot
= SafeHotspot
.x
;
1353 CurIcon
->IconInfo
.yHotspot
= SafeHotspot
.y
;
1358 SetLastNtError(Status
);
1361 if(!fIcon
&& !Hotspot
)
1367 UserDereferenceObject(CurIcon
);
1368 ObDereferenceObject(WinSta
);
1373 DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_
);
1384 NtUserSetSystemCursor(
1392 #define STRETCH_CAN_SRCCOPY_ONLY
1394 #ifdef STRETCH_CAN_SRCCOPY_ONLY
1397 DoStretchBlt(HDC DcDest
, int XDest
, int YDest
, int WidthDest
, int HeightDest
,
1398 HDC DcSrc
, int XSrc
, int YSrc
, int WidthSrc
, int HeightSrc
,
1399 DWORD Rop3
, BOOL Color
)
1402 HBITMAP BitmapStretched
;
1405 if (WidthDest
== WidthSrc
&& HeightDest
== HeightSrc
)
1407 NtGdiBitBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1408 DcSrc
, XSrc
, YSrc
, Rop3
, 0, 0);
1410 else if (SRCCOPY
== Rop3
)
1412 NtGdiStretchBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1413 DcSrc
, XSrc
, YSrc
, WidthSrc
, HeightSrc
,
1418 DcStretched
= NtGdiCreateCompatibleDC(DcSrc
);
1419 if (NULL
== DcStretched
)
1421 DPRINT1("Failed to create compatible DC\n");
1426 BitmapStretched
= NtGdiCreateCompatibleBitmap(DcDest
, WidthDest
,
1431 BitmapStretched
= IntGdiCreateBitmap(WidthDest
, HeightDest
, 1, 1, NULL
);
1433 if (NULL
== BitmapStretched
)
1435 NtGdiDeleteObjectApp(DcStretched
);
1436 DPRINT1("Failed to create temporary bitmap\n");
1439 OldBitmap
= NtGdiSelectBitmap(DcStretched
, BitmapStretched
);
1440 if (NULL
== OldBitmap
)
1442 NtGdiDeleteObject(BitmapStretched
);
1443 NtGdiDeleteObjectApp(DcStretched
);
1444 DPRINT1("Failed to create temporary bitmap\n");
1447 if (! NtGdiStretchBlt(DcStretched
, 0, 0, WidthDest
, HeightDest
,
1448 DcSrc
, XSrc
, YSrc
, WidthSrc
, HeightSrc
,
1450 ! NtGdiBitBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1451 DcStretched
, 0, 0, Rop3
, 0, 0))
1453 DPRINT1("Failed to blt\n");
1455 NtGdiSelectBitmap(DcStretched
, OldBitmap
);
1456 NtGdiDeleteObject(BitmapStretched
);
1457 NtGdiDeleteObjectApp(DcStretched
);
1461 #define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \
1462 DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \
1463 NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \
1464 (DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \
1466 #endif /* STRETCH_CAN_SRCCOPY_ONLY */
1473 PCURICON_OBJECT pIcon
,
1477 HBRUSH hbrFlickerFreeDraw
,
1481 HBITMAP hbmMask
, hbmColor
;
1482 BITMAP bmpMask
, bmpColor
;
1483 COLORREF oldFg
, oldBg
;
1489 HGDIOBJ hOldOffBrush
= 0;
1490 HGDIOBJ hOldOffBmp
= 0;
1494 BOOL bAlpha
= FALSE
;
1496 hbmMask
= pIcon
->IconInfo
.hbmMask
;
1497 hbmColor
= pIcon
->IconInfo
.hbmColor
;
1500 DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
1502 if (!hbmMask
|| !IntGdiGetObject(hbmMask
, sizeof(BITMAP
), (PVOID
)&bmpMask
))
1507 if (hbmColor
&& !IntGdiGetObject(hbmColor
, sizeof(BITMAP
), (PVOID
)&bmpColor
))
1514 IconSize
.cx
= bmpColor
.bmWidth
;
1515 IconSize
.cy
= bmpColor
.bmHeight
;
1519 IconSize
.cx
= bmpMask
.bmWidth
;
1520 IconSize
.cy
= bmpMask
.bmHeight
/ 2;
1523 /* NtGdiCreateCompatibleBitmap will create a monochrome bitmap
1524 when cxWidth or cyHeight is 0 */
1525 if ((bmpColor
.bmBitsPixel
== 32) && (cxWidth
!= 0) && (cyHeight
!= 0))
1531 diFlags
= DI_NORMAL
;
1534 cxWidth
= ((diFlags
& DI_DEFAULTSIZE
) ?
1535 UserGetSystemMetrics(SM_CXICON
) : IconSize
.cx
);
1538 cyHeight
= ((diFlags
& DI_DEFAULTSIZE
) ?
1539 UserGetSystemMetrics(SM_CYICON
) : IconSize
.cy
);
1541 DoFlickerFree
= (hbrFlickerFreeDraw
&&
1542 (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw
) == GDI_OBJECT_TYPE_BRUSH
));
1544 if (DoFlickerFree
|| bAlpha
)
1548 BITMAPOBJ
*BitmapObj
= NULL
;
1551 r
.bottom
= cyHeight
;
1553 hdcOff
= NtGdiCreateCompatibleDC(hDc
);
1556 DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
1560 hbmOff
= NtGdiCreateCompatibleBitmap(hDc
, cxWidth
, cyHeight
);
1563 DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
1567 /* make sure we have a 32 bit offscreen bitmap
1568 otherwise we can't do alpha blending */
1569 BitmapObj
= BITMAPOBJ_LockBitmap(hbmOff
);
1570 if (BitmapObj
== NULL
)
1572 DPRINT1("GDIOBJ_LockObj() failed!\n");
1575 BITMAP_GetObject(BitmapObj
, sizeof(BITMAP
), (PVOID
)&bm
);
1577 if (bm
.bmBitsPixel
!= 32)
1580 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1582 hOldOffBmp
= NtGdiSelectBitmap(hdcOff
, hbmOff
);
1585 DPRINT1("NtGdiSelectBitmap() failed!\n");
1591 hOldOffBrush
= NtGdiSelectBrush(hdcOff
, hbrFlickerFreeDraw
);
1594 DPRINT1("NtGdiSelectBitmap() failed!\n");
1598 NtGdiPatBlt(hdcOff
, 0, 0, r
.right
, r
.bottom
, PATCOPY
);
1604 hdcMem
= NtGdiCreateCompatibleDC(hDc
);
1607 DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
1611 nStretchMode
= IntGdiSetStretchBltMode(hdcOff
, STRETCH_DELETESCANS
);
1613 oldFg
= IntGdiSetTextColor(hdcOff
, RGB(0, 0, 0));
1614 oldBg
= IntGdiSetBkColor(hdcOff
, RGB(255, 255, 255));
1616 if (diFlags
& DI_MASK
)
1618 hOldMem
= NtGdiSelectBitmap(hdcMem
, hbmMask
);
1621 DPRINT("NtGdiSelectBitmap() failed!\n");
1625 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1626 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1627 0, 0, IconSize
.cx
, IconSize
.cy
,
1628 ((diFlags
& DI_IMAGE
) ? SRCAND
: SRCCOPY
), FALSE
);
1630 if (!hbmColor
&& (bmpMask
.bmHeight
== 2 * bmpMask
.bmWidth
)
1631 && (diFlags
& DI_IMAGE
))
1633 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1634 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1635 0, IconSize
.cy
, IconSize
.cx
, IconSize
.cy
, SRCINVERT
,
1638 diFlags
&= ~DI_IMAGE
;
1641 NtGdiSelectBitmap(hdcMem
, hOldMem
);
1644 if(diFlags
& DI_IMAGE
)
1646 hOldMem
= NtGdiSelectBitmap(hdcMem
, (hbmColor
? hbmColor
: hbmMask
));
1648 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1649 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1650 0, (hbmColor
? 0 : IconSize
.cy
), IconSize
.cx
, IconSize
.cy
,
1651 ((diFlags
& DI_MASK
) ? SRCINVERT
: SRCCOPY
),
1654 NtGdiSelectBitmap(hdcMem
, hOldMem
);
1660 BITMAPOBJ
*BitmapObj
= NULL
;
1662 BLENDFUNCTION BlendFunc
;
1664 BYTE Red
, Green
, Blue
, Alpha
;
1668 BitmapObj
= BITMAPOBJ_LockBitmap(hbmOff
);
1669 if (BitmapObj
== NULL
)
1671 DPRINT1("GDIOBJ_LockObj() failed!\n");
1674 BITMAP_GetObject(BitmapObj
, sizeof(BITMAP
), (PVOID
)&bm
);
1676 pBits
= ExAllocatePoolWithTag(PagedPool
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), TAG_BITMAP
);
1679 DPRINT1("ExAllocatePoolWithTag() failed!\n");
1680 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1685 IntGetBitmapBits(BitmapObj
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), pBits
);
1687 /* premultiply with the alpha channel value */
1688 for (i
= 0; i
< cyHeight
; i
++)
1690 for (j
= 0; j
< cxWidth
; j
++)
1692 Pixel
= *(DWORD
*)(pBits
+ Count
);
1694 Alpha
= ((BYTE
)(Pixel
>> 24) & 0xff);
1696 Red
= (((BYTE
)(Pixel
>> 0)) * Alpha
) / 0xff;
1697 Green
= (((BYTE
)(Pixel
>> 8)) * Alpha
) / 0xff;
1698 Blue
= (((BYTE
)(Pixel
>> 16)) * Alpha
) / 0xff;
1700 *(DWORD
*)(pBits
+ Count
) = (DWORD
)(Red
| (Green
<< 8) | (Blue
<< 16) | (Alpha
<< 24));
1702 Count
+= sizeof (DWORD
);
1707 IntSetBitmapBits(BitmapObj
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), pBits
);
1708 ExFreePoolWithTag(pBits
, TAG_BITMAP
);
1710 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1712 BlendFunc
.BlendOp
= AC_SRC_OVER
;
1713 BlendFunc
.BlendFlags
= 0;
1714 BlendFunc
.SourceConstantAlpha
= 255;
1715 BlendFunc
.AlphaFormat
= AC_SRC_ALPHA
;
1717 NtGdiAlphaBlend(hDc
, xLeft
, yTop
, cxWidth
, cyHeight
,
1718 hdcOff
, 0, 0, cxWidth
, cyHeight
, BlendFunc
, 0);
1720 else if (DoFlickerFree
)
1722 NtGdiBitBlt(hDc
, xLeft
, yTop
, cxWidth
,
1723 cyHeight
, hdcOff
, 0, 0, SRCCOPY
, 0, 0);
1726 IntGdiSetTextColor(hdcOff
, oldFg
);
1727 IntGdiSetBkColor(hdcOff
, oldBg
);
1728 IntGdiSetStretchBltMode(hdcOff
, nStretchMode
);
1733 if(DoFlickerFree
|| bAlpha
)
1735 if(hOldOffBmp
) NtGdiSelectBitmap(hdcOff
, hOldOffBmp
);
1736 if(hOldOffBrush
) NtGdiSelectBrush(hdcOff
, hOldOffBrush
);
1737 if(hbmOff
) NtGdiDeleteObject(hbmOff
);
1738 if(hdcOff
) NtGdiDeleteObjectApp(hdcOff
);
1741 if(hdcMem
) NtGdiDeleteObjectApp(hdcMem
);
1758 HBRUSH hbrFlickerFreeDraw
,
1763 PCURICON_OBJECT pIcon
;
1766 DPRINT("Enter NtUserDrawIconEx\n");
1767 UserEnterExclusive();
1769 if(!(pIcon
= UserGetCurIconObject(hIcon
)))
1771 DPRINT1("UserGetCurIconObject() failed!\n");
1776 Ret
= UserDrawIconEx(hdc
,
1786 UserDereferenceObject(pIcon
);
1792 /* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
1793 * User32 macro NtUserShowCursor */
1796 UserShowCursor(BOOL bShow
)
1798 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
1799 PWINSTATION_OBJECT WinSta
= pti
->Desktop
->WindowStation
;
1800 PSYSTEM_CURSORINFO CurInfo
;
1806 BITMAPOBJ
*BitmapObj
;
1811 if(!(Screen
= IntGetScreenDC()))
1813 return showpointer
; /* No mouse */
1816 dc
= DC_LockDc(Screen
);
1820 return showpointer
; /* No mouse */
1823 dcbmp
= dc
->w
.hBitmap
;
1826 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
1829 return showpointer
; /* No Mouse */
1832 SurfObj
= &BitmapObj
->SurfObj
;
1833 if (SurfObj
== NULL
)
1835 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1836 return showpointer
; /* No mouse */
1839 ppdev
= GDIDEV(SurfObj
);
1843 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1844 return showpointer
; /* No mouse */
1847 pgp
= &ppdev
->Pointer
;
1849 CurInfo
= IntGetSysCursorInfo(WinSta
);
1854 showpointer
= pgp
->ShowPointer
;
1856 if (showpointer
>= 0)
1858 //ppdev->SafetyRemoveCount = 1;
1859 //ppdev->SafetyRemoveLevel = 1;
1860 EngMovePointer(SurfObj
,-1,-1,NULL
);
1861 CurInfo
->ShowingCursor
= 0;
1868 showpointer
= pgp
->ShowPointer
;
1871 if (showpointer
< 0)
1873 //ppdev->SafetyRemoveCount = 0;
1874 //ppdev->SafetyRemoveLevel = 0;
1875 EngMovePointer(SurfObj
,-1,-1,NULL
);
1876 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
1880 BITMAPOBJ_UnlockBitmap(BitmapObj
);