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
;
47 /* Look up the location of the cursor in the GDIDEVICE structure
48 * when all we know is the window station object
49 * Actually doesn't use the window station, but should... */
51 IntGetCursorLocation(PWINSTATION_OBJECT WinSta
, POINT
*loc
)
58 /* FIXME - get the screen dc from the window station or desktop */
59 if (!(hDC
= IntGetScreenDC()))
63 if (!(dc
= DC_LockDc(hDC
)))
65 GDIDevice
= (GDIDEVICE
*)dc
->pPDev
;
68 loc
->x
= GDIDevice
->Pointer
.Pos
.x
;
69 loc
->y
= GDIDevice
->Pointer
.Pos
.y
;
74 /* This function creates a reference for the object! */
75 PCURICON_OBJECT FASTCALL
UserGetCurIconObject(HCURSOR hCurIcon
)
77 PCURICON_OBJECT CurIcon
;
81 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
85 CurIcon
= (PCURICON_OBJECT
)UserReferenceObjectByHandle(hCurIcon
, otCursorIcon
);
88 /* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
89 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
93 ASSERT(USER_BODY_TO_HEADER(CurIcon
)->RefCount
>= 1);
98 #define COLORCURSORS_ALLOWED FALSE
100 IntSetCursor(PWINSTATION_OBJECT WinSta
, PCURICON_OBJECT NewCursor
,
103 BITMAPOBJ
*BitmapObj
;
106 PBITMAPOBJ MaskBmpObj
= NULL
;
107 PSYSTEM_CURSORINFO CurInfo
;
108 PCURICON_OBJECT OldCursor
;
109 HCURSOR Ret
= (HCURSOR
)0;
110 HBITMAP dcbmp
, hColor
= (HBITMAP
)0;
112 SURFOBJ
*soMask
= NULL
, *soColor
= NULL
;
113 XLATEOBJ
*XlateObj
= NULL
;
117 CurInfo
= IntGetSysCursorInfo(WinSta
);
118 OldCursor
= CurInfo
->CurrentCursorObject
;
121 Ret
= (HCURSOR
)OldCursor
->Self
;
124 if (!ForceChange
&& OldCursor
== NewCursor
)
129 if(!(Screen
= IntGetScreenDC()))
133 /* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
134 dc
= DC_LockDc(Screen
);
140 dcbmp
= dc
->w
.hBitmap
;
141 DevInfo
= (PDEVINFO
)&((GDIDEVICE
*)dc
->pPDev
)->DevInfo
;
144 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
147 SurfObj
= &BitmapObj
->SurfObj
;
151 if (CurInfo
->CurrentCursorObject
|| ForceChange
)
153 if (CurInfo
->CurrentCursorObject
)
155 UserDereferenceObject(CurInfo
->CurrentCursorObject
);
156 if (CurInfo
->ShowingCursor
)
158 DPRINT1("Removing pointer!\n");
159 /* Remove the cursor if it was displayed */
160 IntEngMovePointer(SurfObj
, -1, -1, &GDIDEV(SurfObj
)->Pointer
.Exclude
);
164 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_ACCEPT_NOEXCLUDE
;
166 CurInfo
->CurrentCursorObject
= NewCursor
; /* i.e. CurrentCursorObject = NULL */
167 CurInfo
->ShowingCursor
= 0;
170 BITMAPOBJ_UnlockBitmap(BitmapObj
);
174 /* TODO: Fixme. Logic is screwed above */
176 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
179 const int maskBpp
= BitsPerFormat(MaskBmpObj
->SurfObj
.iBitmapFormat
);
180 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
183 DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
184 BITMAPOBJ_UnlockBitmap(BitmapObj
);
188 if ((DevInfo
->flGraphicsCaps2
& GCAPS2_ALPHACURSOR
) &&
189 SurfObj
->iBitmapFormat
>= BMF_16BPP
&&
190 SurfObj
->iBitmapFormat
<= BMF_32BPP
&&
191 NewCursor
->Shadow
&& COLORCURSORS_ALLOWED
)
193 /* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
194 Do not pass a mask bitmap to DrvSetPointerShape()!
195 Create a XLATEOBJ that describes the colors of the bitmap. */
196 DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
200 if(NewCursor
->IconInfo
.hbmColor
201 && COLORCURSORS_ALLOWED
)
203 /* FIXME - Create a color pointer, create only one 32bit bitmap!
204 Do not pass a mask bitmap to DrvSetPointerShape()!
205 Create a XLATEOBJ that describes the colors of the bitmap.
206 (16bit bitmaps are propably allowed) */
207 DPRINT1("SetCursor: Cursors with colors are not supported!\n");
211 MaskBmpObj
= BITMAPOBJ_LockBitmap(NewCursor
->IconInfo
.hbmMask
);
214 RECTL DestRect
= {0, 0, MaskBmpObj
->SurfObj
.sizlBitmap
.cx
, MaskBmpObj
->SurfObj
.sizlBitmap
.cy
};
215 POINTL SourcePoint
= {0, 0};
218 * NOTE: For now we create the cursor in top-down bitmap,
219 * because VMware driver rejects it otherwise. This should
222 hMask
= EngCreateBitmap(
223 MaskBmpObj
->SurfObj
.sizlBitmap
, abs(MaskBmpObj
->SurfObj
.lDelta
),
224 MaskBmpObj
->SurfObj
.iBitmapFormat
, BMF_TOPDOWN
,
228 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
229 BITMAPOBJ_UnlockBitmap(BitmapObj
);
232 soMask
= EngLockSurface((HSURF
)hMask
);
233 EngCopyBits(soMask
, &MaskBmpObj
->SurfObj
, NULL
, NULL
,
234 &DestRect
, &SourcePoint
);
235 BITMAPOBJ_UnlockBitmap(MaskBmpObj
);
239 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
240 CurInfo
->CurrentCursorObject
= NewCursor
;
241 UserReferenceObject(NewCursor
);
245 CurInfo
->ShowingCursor
= 0;
246 CurInfo
->CurrentCursorObject
= NULL
;
249 /* OldCursor is not in use anymore */
252 UserDereferenceObject(OldCursor
);
255 if (GDIDEVFUNCS(SurfObj
).SetPointerShape
)
257 GDIDEV(SurfObj
)->Pointer
.Status
=
258 GDIDEVFUNCS(SurfObj
).SetPointerShape(
259 SurfObj
, soMask
, soColor
, XlateObj
,
260 NewCursor
->IconInfo
.xHotspot
,
261 NewCursor
->IconInfo
.yHotspot
,
262 GDIDEV(SurfObj
)->Pointer
.Pos
.x
,
263 GDIDEV(SurfObj
)->Pointer
.Pos
.y
,
264 &(GDIDEV(SurfObj
)->Pointer
.Exclude
),
266 DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
267 GDIDEV(SurfObj
)->Pointer
.Status
);
271 GDIDEV(SurfObj
)->Pointer
.Status
= SPS_DECLINE
;
274 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_DECLINE
)
276 GDIDEV(SurfObj
)->Pointer
.Status
= EngSetPointerShape(
277 SurfObj
, soMask
, soColor
, XlateObj
,
278 NewCursor
->IconInfo
.xHotspot
,
279 NewCursor
->IconInfo
.yHotspot
,
280 GDIDEV(SurfObj
)->Pointer
.Pos
.x
,
281 GDIDEV(SurfObj
)->Pointer
.Pos
.y
,
282 &(GDIDEV(SurfObj
)->Pointer
.Exclude
),
284 GDIDEV(SurfObj
)->Pointer
.MovePointer
= NULL
;
288 GDIDEV(SurfObj
)->Pointer
.MovePointer
= GDIDEVFUNCS(SurfObj
).MovePointer
;
291 BITMAPOBJ_UnlockBitmap(BitmapObj
);
294 EngUnlockSurface(soMask
);
295 EngDeleteSurface((HSURF
)hMask
);
299 EngDeleteSurface((HSURF
)hColor
);
303 EngDeleteXlate(XlateObj
);
306 if(GDIDEV(SurfObj
)->Pointer
.Status
== SPS_ERROR
)
307 DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
313 IntSetupCurIconHandles(PWINSTATION_OBJECT WinSta
)
315 ExInitializePagedLookasideList(&gProcessLookasideList
,
319 sizeof(CURICON_PROCESS
),
322 InitializeListHead(&gCurIconList
);
328 * We have to register that this object is in use by the current
329 * process. The only way to do that seems to be to walk the list
330 * of cursor/icon objects starting at W32Process->CursorIconListHead.
331 * If the object is already present in the list, we don't have to do
332 * anything, if it's not present we add it and inc the ProcessCount
333 * in the object. Having to walk the list kind of sucks, but that's
336 static BOOLEAN FASTCALL
337 ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon
)
339 PW32PROCESS Win32Process
;
340 PCURICON_PROCESS Current
;
342 Win32Process
= PsGetCurrentProcessWin32Process();
344 LIST_FOR_EACH(Current
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
346 if (Current
->Process
== Win32Process
)
348 /* Already registered for this process */
353 /* Not registered yet */
354 Current
= ExAllocateFromPagedLookasideList(&gProcessLookasideList
);
359 InsertHeadList(&CurIcon
->ProcessList
, &Current
->ListEntry
);
360 Current
->Process
= Win32Process
;
365 PCURICON_OBJECT FASTCALL
366 IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta
, HMODULE hModule
,
367 HRSRC hRsrc
, LONG cx
, LONG cy
)
369 PCURICON_OBJECT CurIcon
;
371 LIST_FOR_EACH(CurIcon
, &gCurIconList
, CURICON_OBJECT
, ListEntry
)
374 // if(NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
375 // UserReferenceObject( CurIcon);
377 if((CurIcon
->hModule
== hModule
) && (CurIcon
->hRsrc
== hRsrc
))
379 if(cx
&& ((cx
!= CurIcon
->Size
.cx
) || (cy
!= CurIcon
->Size
.cy
)))
381 // UserDereferenceObject(CurIcon);
384 if (! ReferenceCurIconByProcess(CurIcon
))
392 // UserDereferenceObject(CurIcon);
399 PCURICON_OBJECT FASTCALL
400 IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta
)
402 PCURICON_OBJECT CurIcon
;
405 CurIcon
= UserCreateObject(gHandleTable
, &hCurIcon
, otCursorIcon
, sizeof(CURICON_OBJECT
));
409 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
413 CurIcon
->Self
= hCurIcon
;
414 InitializeListHead(&CurIcon
->ProcessList
);
416 if (! ReferenceCurIconByProcess(CurIcon
))
418 DPRINT1("Failed to add process\n");
419 UserDeleteObject(hCurIcon
, otCursorIcon
);
420 UserDereferenceObject(CurIcon
);
424 InsertHeadList(&gCurIconList
, &CurIcon
->ListEntry
);
430 IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta
, PCURICON_OBJECT CurIcon
, BOOL ProcessCleanup
)
432 PSYSTEM_CURSORINFO CurInfo
;
433 HBITMAP bmpMask
, bmpColor
;
435 PCURICON_PROCESS Current
= NULL
;
436 PW32PROCESS W32Process
= PsGetCurrentProcessWin32Process();
438 /* Private objects can only be destroyed by their own process */
439 if (NULL
== CurIcon
->hModule
)
441 ASSERT(CurIcon
->ProcessList
.Flink
->Flink
== &CurIcon
->ProcessList
);
442 Current
= CONTAINING_RECORD(CurIcon
->ProcessList
.Flink
, CURICON_PROCESS
, ListEntry
);
443 if (Current
->Process
!= W32Process
)
445 DPRINT1("Trying to destroy private icon/cursor of another process\n");
449 else if (! ProcessCleanup
)
451 DPRINT("Trying to destroy shared icon/cursor\n");
455 /* Now find this process in the list of processes referencing this object and
456 remove it from that list */
457 LIST_FOR_EACH(Current
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
459 if (Current
->Process
== W32Process
)
461 RemoveEntryList(&Current
->ListEntry
);
466 ExFreeToPagedLookasideList(&gProcessLookasideList
, Current
);
468 /* If there are still processes referencing this object we can't destroy it yet */
469 if (! IsListEmpty(&CurIcon
->ProcessList
))
475 if (! ProcessCleanup
)
477 RemoveEntryList(&CurIcon
->ListEntry
);
480 CurInfo
= IntGetSysCursorInfo(WinSta
);
482 if (CurInfo
->CurrentCursorObject
== CurIcon
)
484 /* Hide the cursor if we're destroying the current cursor */
485 IntSetCursor(WinSta
, NULL
, TRUE
);
488 bmpMask
= CurIcon
->IconInfo
.hbmMask
;
489 bmpColor
= CurIcon
->IconInfo
.hbmColor
;
494 GDIOBJ_SetOwnership(bmpMask
, PsGetCurrentProcess());
495 NtGdiDeleteObject(bmpMask
);
496 CurIcon
->IconInfo
.hbmMask
= NULL
;
500 GDIOBJ_SetOwnership(bmpColor
, PsGetCurrentProcess());
501 NtGdiDeleteObject(bmpColor
);
502 CurIcon
->IconInfo
.hbmColor
= NULL
;
505 /* We were given a pointer, no need to keep the reference anylonger! */
506 UserDereferenceObject(CurIcon
);
507 Ret
= UserDeleteObject(CurIcon
->Self
, otCursorIcon
);
513 IntCleanupCurIcons(struct _EPROCESS
*Process
, PW32PROCESS Win32Process
)
515 PWINSTATION_OBJECT WinSta
;
516 PCURICON_OBJECT CurIcon
, tmp
;
517 PCURICON_PROCESS ProcessData
;
519 WinSta
= IntGetWinStaObj();
525 LIST_FOR_EACH_SAFE(CurIcon
, tmp
, &gCurIconList
, CURICON_OBJECT
, ListEntry
)
527 UserReferenceObject(CurIcon
);
528 // if(NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon)))
530 LIST_FOR_EACH(ProcessData
, &CurIcon
->ProcessList
, CURICON_PROCESS
, ListEntry
)
532 if (Win32Process
== ProcessData
->Process
)
534 RemoveEntryList(&CurIcon
->ListEntry
);
535 IntDestroyCurIconObject(WinSta
, CurIcon
, TRUE
);
541 // UserDereferenceObject(Object);
546 UserDereferenceObject(CurIcon
);
550 ObDereferenceObject(WinSta
);
558 NtUserCreateCursorIconHandle(PICONINFO IconInfo OPTIONAL
, BOOL Indirect
)
560 PCURICON_OBJECT CurIcon
;
561 PWINSTATION_OBJECT WinSta
;
565 DECLARE_RETURN(HANDLE
);
567 DPRINT("Enter NtUserCreateCursorIconHandle\n");
568 UserEnterExclusive();
570 WinSta
= IntGetWinStaObj();
576 if (!(CurIcon
= IntCreateCurIconHandle(WinSta
)))
578 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
579 ObDereferenceObject(WinSta
);
587 Status
= MmCopyFromCaller(&CurIcon
->IconInfo
, IconInfo
, sizeof(ICONINFO
));
588 if(NT_SUCCESS(Status
))
592 CurIcon
->IconInfo
.hbmMask
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmMask
);
593 CurIcon
->IconInfo
.hbmColor
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmColor
);
595 if(CurIcon
->IconInfo
.hbmColor
&&
596 (bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
)))
598 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
599 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
600 BITMAPOBJ_UnlockBitmap(bmp
);
601 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmColor
, NULL
);
603 if(CurIcon
->IconInfo
.hbmMask
&&
604 (bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
)))
606 if (CurIcon
->IconInfo
.hbmColor
== NULL
)
608 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
609 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
611 BITMAPOBJ_UnlockBitmap(bmp
);
612 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmMask
, NULL
);
617 SetLastNtError(Status
);
618 /* FIXME - Don't exit here */
622 UserDereferenceObject(CurIcon
);
623 ObDereferenceObject(WinSta
);
627 DPRINT("Leave NtUserCreateCursorIconHandle, ret=%i\n",_ret_
);
640 PUNICODE_STRING lpInstName
, // optional
641 PUNICODE_STRING lpResName
, // optional
642 LPDWORD pbpp
, // optional
646 PCURICON_OBJECT CurIcon
;
647 PWINSTATION_OBJECT WinSta
;
648 NTSTATUS Status
= STATUS_SUCCESS
;
650 DECLARE_RETURN(BOOL
);
652 DPRINT("Enter NtUserGetIconInfo\n");
653 UserEnterExclusive();
657 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
661 WinSta
= IntGetWinStaObj();
667 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
669 ObDereferenceObject(WinSta
);
673 RtlCopyMemory(&ii
, &CurIcon
->IconInfo
, sizeof(ICONINFO
));
676 ii
.hbmMask
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmMask
);
677 ii
.hbmColor
= BITMAPOBJ_CopyBitmap(CurIcon
->IconInfo
.hbmColor
);
682 ProbeForWrite(IconInfo
, sizeof(ICONINFO
), 1);
683 RtlCopyMemory(IconInfo
, &ii
, sizeof(ICONINFO
));
690 ProbeForWrite(pbpp
, sizeof(DWORD
), 1);
692 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
);
695 colorBpp
= BitsPerFormat(bmp
->SurfObj
.iBitmapFormat
);
696 BITMAPOBJ_UnlockBitmap(bmp
);
699 RtlCopyMemory(pbpp
, &colorBpp
, sizeof(DWORD
));
705 Status
= _SEH_GetExceptionCode();
709 if (NT_SUCCESS(Status
))
712 SetLastNtError(Status
);
714 UserDereferenceObject(CurIcon
);
715 ObDereferenceObject(WinSta
);
719 DPRINT("Leave NtUserGetIconInfo, ret=%i\n",_ret_
);
733 PLONG plcx
, // &size.cx
734 PLONG plcy
) // &size.cy
736 PCURICON_OBJECT CurIcon
;
737 NTSTATUS Status
= STATUS_SUCCESS
;
740 DPRINT("Enter NtUserGetIconSize\n");
741 UserEnterExclusive();
743 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
750 ProbeForWrite(plcx
, sizeof(LONG
), 1);
751 RtlCopyMemory(plcx
, &CurIcon
->Size
.cx
, sizeof(LONG
));
752 ProbeForWrite(plcy
, sizeof(LONG
), 1);
753 RtlCopyMemory(plcy
, &CurIcon
->Size
.cy
, sizeof(LONG
));
757 Status
= _SEH_GetExceptionCode();
761 if(NT_SUCCESS(Status
))
764 SetLastNtError(Status
); // maybe not, test this
766 UserDereferenceObject(CurIcon
);
769 DPRINT("Leave NtUserGetIconSize, ret=%i\n", bRet
);
780 NtUserGetCursorFrameInfo(
801 PSYSTEM_CURSORINFO CurInfo
;
802 PWINSTATION_OBJECT WinSta
;
804 PCURICON_OBJECT CurIcon
;
806 DECLARE_RETURN(BOOL
);
808 DPRINT("Enter NtUserGetCursorInfo\n");
809 UserEnterExclusive();
814 /* FIXME - get the screen dc from the window station or desktop */
815 if (!(hDC
= IntGetScreenDC()))
821 Status
= MmCopyFromCaller(&SafeCi
.cbSize
, pci
, sizeof(DWORD
));
822 if(!NT_SUCCESS(Status
))
824 SetLastNtError(Status
);
828 if(SafeCi
.cbSize
!= sizeof(CURSORINFO
))
830 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
834 WinSta
= IntGetWinStaObj();
840 CurInfo
= IntGetSysCursorInfo(WinSta
);
841 CurIcon
= (PCURICON_OBJECT
)CurInfo
->CurrentCursorObject
;
843 SafeCi
.flags
= ((CurInfo
->ShowingCursor
&& CurIcon
) ? CURSOR_SHOWING
: 0);
844 SafeCi
.hCursor
= (CurIcon
? (HCURSOR
)CurIcon
->Self
: (HCURSOR
)0);
846 IntGetCursorLocation(WinSta
, &SafeCi
.ptScreenPos
);
848 Status
= MmCopyToCaller(pci
, &SafeCi
, sizeof(CURSORINFO
));
849 if(!NT_SUCCESS(Status
))
851 ObDereferenceObject(WinSta
);
852 SetLastNtError(Status
);
856 ObDereferenceObject(WinSta
);
860 DPRINT("Leave NtUserGetCursorInfo, ret=%i\n",_ret_
);
874 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
876 PWINSTATION_OBJECT WinSta
;
877 PSYSTEM_CURSORINFO CurInfo
;
879 PWINDOW_OBJECT DesktopWindow
= NULL
;
880 POINT MousePos
= {0};
881 DECLARE_RETURN(BOOL
);
883 DPRINT("Enter NtUserClipCursor\n");
884 UserEnterExclusive();
886 WinSta
= IntGetWinStaObj();
892 if (NULL
!= UnsafeRect
&& ! NT_SUCCESS(MmCopyFromCaller(&Rect
, UnsafeRect
, sizeof(RECT
))))
894 ObDereferenceObject(WinSta
);
895 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
899 CurInfo
= IntGetSysCursorInfo(WinSta
);
900 IntGetCursorLocation(WinSta
, &MousePos
);
902 if(WinSta
->ActiveDesktop
)
903 DesktopWindow
= UserGetWindowObject(WinSta
->ActiveDesktop
->DesktopWindow
);
905 if((Rect
.right
> Rect
.left
) && (Rect
.bottom
> Rect
.top
)
906 && DesktopWindow
&& UnsafeRect
!= NULL
)
910 CurInfo
->CursorClipInfo
.IsClipped
= TRUE
;
911 CurInfo
->CursorClipInfo
.Left
= max(Rect
.left
, DesktopWindow
->Wnd
->WindowRect
.left
);
912 CurInfo
->CursorClipInfo
.Top
= max(Rect
.top
, DesktopWindow
->Wnd
->WindowRect
.top
);
913 CurInfo
->CursorClipInfo
.Right
= min(Rect
.right
- 1, DesktopWindow
->Wnd
->WindowRect
.right
- 1);
914 CurInfo
->CursorClipInfo
.Bottom
= min(Rect
.bottom
- 1, DesktopWindow
->Wnd
->WindowRect
.bottom
- 1);
919 mi
.dwFlags
= MOUSEEVENTF_ABSOLUTE
| MOUSEEVENTF_MOVE
;
927 CurInfo
->CursorClipInfo
.IsClipped
= FALSE
;
928 ObDereferenceObject(WinSta
);
933 DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_
);
948 PWINSTATION_OBJECT WinSta
;
949 PCURICON_OBJECT CurIcon
;
951 DECLARE_RETURN(BOOL
);
953 DPRINT("Enter NtUserDestroyCursorIcon\n");
954 UserEnterExclusive();
956 WinSta
= IntGetWinStaObj();
962 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
964 ObDereferenceObject(WinSta
);
968 ret
= IntDestroyCurIconObject(WinSta
, CurIcon
, FALSE
);
969 /* Note: IntDestroyCurIconObject will remove our reference for us! */
971 ObDereferenceObject(WinSta
);
975 DPRINT("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_
);
986 NtUserFindExistingCursorIcon(
992 PCURICON_OBJECT CurIcon
;
993 PWINSTATION_OBJECT WinSta
;
994 HANDLE Ret
= (HANDLE
)0;
995 DECLARE_RETURN(HICON
);
997 DPRINT("Enter NtUserFindExistingCursorIcon\n");
998 UserEnterExclusive();
1000 WinSta
= IntGetWinStaObj();
1006 CurIcon
= IntFindExistingCurIconObject(WinSta
, hModule
, hRsrc
, cx
, cy
);
1009 Ret
= CurIcon
->Self
;
1011 // IntReleaseCurIconObject(CurIcon);//faxme: is this correct? does IntFindExistingCurIconObject add a ref?
1012 ObDereferenceObject(WinSta
);
1016 SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE
);
1017 ObDereferenceObject(WinSta
);
1021 DPRINT("Leave NtUserFindExistingCursorIcon, ret=%i\n",_ret_
);
1032 NtUserGetClipCursor(
1035 /* FIXME - check if process has WINSTA_READATTRIBUTES */
1036 PSYSTEM_CURSORINFO CurInfo
;
1037 PWINSTATION_OBJECT WinSta
;
1040 DECLARE_RETURN(BOOL
);
1042 DPRINT("Enter NtUserGetClipCursor\n");
1043 UserEnterExclusive();
1048 WinSta
= IntGetWinStaObj();
1054 CurInfo
= IntGetSysCursorInfo(WinSta
);
1055 if(CurInfo
->CursorClipInfo
.IsClipped
)
1057 Rect
.left
= CurInfo
->CursorClipInfo
.Left
;
1058 Rect
.top
= CurInfo
->CursorClipInfo
.Top
;
1059 Rect
.right
= CurInfo
->CursorClipInfo
.Right
;
1060 Rect
.bottom
= CurInfo
->CursorClipInfo
.Bottom
;
1066 Rect
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
1067 Rect
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
1070 Status
= MmCopyToCaller((PRECT
)lpRect
, &Rect
, sizeof(RECT
));
1071 if(!NT_SUCCESS(Status
))
1073 ObDereferenceObject(WinSta
);
1074 SetLastNtError(Status
);
1078 ObDereferenceObject(WinSta
);
1083 DPRINT("Leave NtUserGetClipCursor, ret=%i\n",_ret_
);
1097 PCURICON_OBJECT CurIcon
;
1099 PWINSTATION_OBJECT WinSta
;
1100 DECLARE_RETURN(HCURSOR
);
1102 DPRINT("Enter NtUserSetCursor\n");
1103 UserEnterExclusive();
1105 WinSta
= IntGetWinStaObj();
1113 if(!(CurIcon
= UserGetCurIconObject(hCursor
)))
1115 ObDereferenceObject(WinSta
);
1124 OldCursor
= IntSetCursor(WinSta
, CurIcon
, FALSE
);
1128 UserDereferenceObject(CurIcon
);
1130 ObDereferenceObject(WinSta
);
1135 DPRINT("Leave NtUserSetCursor, ret=%i\n",_ret_
);
1146 NtUserSetCursorContents(
1148 PICONINFO UnsafeIconInfo
)
1150 PCURICON_OBJECT CurIcon
;
1153 PWINSTATION_OBJECT WinSta
;
1156 DECLARE_RETURN(BOOL
);
1158 DPRINT("Enter NtUserSetCursorContents\n");
1159 UserEnterExclusive();
1161 WinSta
= IntGetWinStaObj();
1167 if (!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
1169 ObDereferenceObject(WinSta
);
1174 Status
= MmCopyFromCaller(&IconInfo
, UnsafeIconInfo
, sizeof(ICONINFO
));
1175 if(!NT_SUCCESS(Status
))
1177 SetLastNtError(Status
);
1181 /* Delete old bitmaps */
1182 if (CurIcon
->IconInfo
.hbmColor
!= IconInfo
.hbmColor
)
1184 NtGdiDeleteObject(CurIcon
->IconInfo
.hbmColor
);
1186 if (CurIcon
->IconInfo
.hbmMask
!= IconInfo
.hbmMask
)
1188 NtGdiDeleteObject(CurIcon
->IconInfo
.hbmMask
);
1191 /* Copy new IconInfo field */
1192 CurIcon
->IconInfo
= IconInfo
;
1194 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
);
1197 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
1198 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
;
1199 BITMAPOBJ_UnlockBitmap(bmp
);
1200 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmColor
, NULL
);
1204 bmp
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
);
1208 CurIcon
->Size
.cx
= bmp
->SurfObj
.sizlBitmap
.cx
;
1209 CurIcon
->Size
.cy
= bmp
->SurfObj
.sizlBitmap
.cy
/ 2;
1211 BITMAPOBJ_UnlockBitmap(bmp
);
1212 GDIOBJ_SetOwnership(CurIcon
->IconInfo
.hbmMask
, NULL
);
1221 UserDereferenceObject(CurIcon
);
1223 ObDereferenceObject(WinSta
);
1227 DPRINT("Leave NtUserSetCursorContents, ret=%i\n",_ret_
);
1239 NtUserSetCursorIconData(
1242 PUNICODE_STRING pstrResName
,
1243 PICONINFO pIconInfo
)
1245 PCURICON_OBJECT CurIcon
;
1246 PWINSTATION_OBJECT WinSta
;
1248 NTSTATUS Status
= STATUS_SUCCESS
;
1250 DECLARE_RETURN(BOOL
);
1252 DPRINT("Enter NtUserSetCursorIconData\n");
1253 UserEnterExclusive();
1255 WinSta
= IntGetWinStaObj();
1261 if(!(CurIcon
= UserGetCurIconObject(Handle
)))
1263 ObDereferenceObject(WinSta
);
1267 CurIcon
->hModule
= hModule
;
1268 CurIcon
->hRsrc
= NULL
; //hRsrc;
1269 CurIcon
->hGroupRsrc
= NULL
; //hGroupRsrc;
1273 ProbeForRead(pIconInfo
, sizeof(ICONINFO
), 1);
1274 RtlCopyMemory(&CurIcon
->IconInfo
, pIconInfo
, sizeof(ICONINFO
));
1276 CurIcon
->IconInfo
.hbmMask
= BITMAPOBJ_CopyBitmap(pIconInfo
->hbmMask
);
1277 CurIcon
->IconInfo
.hbmColor
= BITMAPOBJ_CopyBitmap(pIconInfo
->hbmColor
);
1279 if (CurIcon
->IconInfo
.hbmColor
)
1281 if ((pBmpObj
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmColor
)))
1283 CurIcon
->Size
.cx
= pBmpObj
->SurfObj
.sizlBitmap
.cx
;
1284 CurIcon
->Size
.cy
= pBmpObj
->SurfObj
.sizlBitmap
.cy
;
1285 BITMAPOBJ_UnlockBitmap(pBmpObj
);
1286 GDIOBJ_SetOwnership(GdiHandleTable
, CurIcon
->IconInfo
.hbmMask
, NULL
);
1289 if (CurIcon
->IconInfo
.hbmMask
)
1291 if (CurIcon
->IconInfo
.hbmColor
== NULL
)
1293 if ((pBmpObj
= BITMAPOBJ_LockBitmap(CurIcon
->IconInfo
.hbmMask
)))
1295 CurIcon
->Size
.cx
= pBmpObj
->SurfObj
.sizlBitmap
.cx
;
1296 CurIcon
->Size
.cy
= pBmpObj
->SurfObj
.sizlBitmap
.cy
;
1297 BITMAPOBJ_UnlockBitmap(pBmpObj
);
1300 GDIOBJ_SetOwnership(GdiHandleTable
, CurIcon
->IconInfo
.hbmMask
, NULL
);
1305 Status
= _SEH_GetExceptionCode();
1309 if(!NT_SUCCESS(Status
))
1310 SetLastNtError(Status
);
1314 UserDereferenceObject(CurIcon
);
1315 ObDereferenceObject(WinSta
);
1319 DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_
);
1326 NtUserSetCursorIconData(
1334 PCURICON_OBJECT CurIcon
;
1335 PWINSTATION_OBJECT WinSta
;
1339 DECLARE_RETURN(BOOL
);
1341 DPRINT("Enter NtUserSetCursorIconData\n");
1342 UserEnterExclusive();
1344 WinSta
= IntGetWinStaObj();
1350 if(!(CurIcon
= UserGetCurIconObject(hCurIcon
)))
1352 ObDereferenceObject(WinSta
);
1356 CurIcon
->hModule
= hModule
;
1357 CurIcon
->hRsrc
= hRsrc
;
1358 CurIcon
->hGroupRsrc
= hGroupRsrc
;
1363 Status
= MmCopyFromCaller(&CurIcon
->IconInfo
.fIcon
, fIcon
, sizeof(BOOL
));
1364 if(!NT_SUCCESS(Status
))
1366 SetLastNtError(Status
);
1378 Status
= MmCopyFromCaller(&SafeHotspot
, Hotspot
, sizeof(POINT
));
1379 if(NT_SUCCESS(Status
))
1381 CurIcon
->IconInfo
.xHotspot
= SafeHotspot
.x
;
1382 CurIcon
->IconInfo
.yHotspot
= SafeHotspot
.y
;
1387 SetLastNtError(Status
);
1390 if(!fIcon
&& !Hotspot
)
1396 UserDereferenceObject(CurIcon
);
1397 ObDereferenceObject(WinSta
);
1402 DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_
);
1413 NtUserSetSystemCursor(
1421 #define STRETCH_CAN_SRCCOPY_ONLY
1423 #ifdef STRETCH_CAN_SRCCOPY_ONLY
1426 DoStretchBlt(HDC DcDest
, int XDest
, int YDest
, int WidthDest
, int HeightDest
,
1427 HDC DcSrc
, int XSrc
, int YSrc
, int WidthSrc
, int HeightSrc
,
1428 DWORD Rop3
, BOOL Color
)
1431 HBITMAP BitmapStretched
;
1434 if (WidthDest
== WidthSrc
&& HeightDest
== HeightSrc
)
1436 NtGdiBitBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1437 DcSrc
, XSrc
, YSrc
, Rop3
, 0, 0);
1439 else if (SRCCOPY
== Rop3
)
1441 NtGdiStretchBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1442 DcSrc
, XSrc
, YSrc
, WidthSrc
, HeightSrc
,
1447 DcStretched
= NtGdiCreateCompatibleDC(DcSrc
);
1448 if (NULL
== DcStretched
)
1450 DPRINT1("Failed to create compatible DC\n");
1455 BitmapStretched
= NtGdiCreateCompatibleBitmap(DcDest
, WidthDest
,
1460 BitmapStretched
= IntGdiCreateBitmap(WidthDest
, HeightDest
, 1, 1, NULL
);
1462 if (NULL
== BitmapStretched
)
1464 NtGdiDeleteObjectApp(DcStretched
);
1465 DPRINT1("Failed to create temporary bitmap\n");
1468 OldBitmap
= NtGdiSelectBitmap(DcStretched
, BitmapStretched
);
1469 if (NULL
== OldBitmap
)
1471 NtGdiDeleteObject(BitmapStretched
);
1472 NtGdiDeleteObjectApp(DcStretched
);
1473 DPRINT1("Failed to create temporary bitmap\n");
1476 if (! NtGdiStretchBlt(DcStretched
, 0, 0, WidthDest
, HeightDest
,
1477 DcSrc
, XSrc
, YSrc
, WidthSrc
, HeightSrc
,
1479 ! NtGdiBitBlt(DcDest
, XDest
, YDest
, WidthDest
, HeightDest
,
1480 DcStretched
, 0, 0, Rop3
, 0, 0))
1482 DPRINT1("Failed to blt\n");
1484 NtGdiSelectBitmap(DcStretched
, OldBitmap
);
1485 NtGdiDeleteObject(BitmapStretched
);
1486 NtGdiDeleteObjectApp(DcStretched
);
1490 #define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \
1491 DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \
1492 NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \
1493 (DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \
1495 #endif /* STRETCH_CAN_SRCCOPY_ONLY */
1502 PCURICON_OBJECT pIcon
,
1506 HBRUSH hbrFlickerFreeDraw
,
1510 HBITMAP hbmMask
, hbmColor
;
1511 BITMAP bmpMask
, bmpColor
;
1512 COLORREF oldFg
, oldBg
;
1518 HGDIOBJ hOldOffBrush
= 0;
1519 HGDIOBJ hOldOffBmp
= 0;
1523 BOOL bAlpha
= FALSE
;
1525 hbmMask
= pIcon
->IconInfo
.hbmMask
;
1526 hbmColor
= pIcon
->IconInfo
.hbmColor
;
1529 DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
1531 if (!hbmMask
|| !IntGdiGetObject(hbmMask
, sizeof(BITMAP
), &bmpMask
))
1536 if (hbmColor
&& !IntGdiGetObject(hbmColor
, sizeof(BITMAP
), &bmpColor
))
1543 IconSize
.cx
= bmpColor
.bmWidth
;
1544 IconSize
.cy
= bmpColor
.bmHeight
;
1548 IconSize
.cx
= bmpMask
.bmWidth
;
1549 IconSize
.cy
= bmpMask
.bmHeight
/ 2;
1552 /* NtGdiCreateCompatibleBitmap will create a monochrome bitmap
1553 when cxWidth or cyHeight is 0 */
1554 if ((bmpColor
.bmBitsPixel
== 32) && (cxWidth
!= 0) && (cyHeight
!= 0))
1560 diFlags
= DI_NORMAL
;
1563 cxWidth
= ((diFlags
& DI_DEFAULTSIZE
) ?
1564 UserGetSystemMetrics(SM_CXICON
) : IconSize
.cx
);
1567 cyHeight
= ((diFlags
& DI_DEFAULTSIZE
) ?
1568 UserGetSystemMetrics(SM_CYICON
) : IconSize
.cy
);
1570 DoFlickerFree
= (hbrFlickerFreeDraw
&&
1571 (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw
) == GDI_OBJECT_TYPE_BRUSH
));
1573 if (DoFlickerFree
|| bAlpha
)
1577 BITMAPOBJ
*BitmapObj
= NULL
;
1580 r
.bottom
= cyHeight
;
1582 hdcOff
= NtGdiCreateCompatibleDC(hDc
);
1585 DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
1589 hbmOff
= NtGdiCreateCompatibleBitmap(hDc
, cxWidth
, cyHeight
);
1592 DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
1596 /* make sure we have a 32 bit offscreen bitmap
1597 otherwise we can't do alpha blending */
1598 BitmapObj
= BITMAPOBJ_LockBitmap(hbmOff
);
1599 if (BitmapObj
== NULL
)
1601 DPRINT1("GDIOBJ_LockObj() failed!\n");
1604 BITMAP_GetObject(BitmapObj
, sizeof(BITMAP
), &bm
);
1606 if (bm
.bmBitsPixel
!= 32)
1609 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1611 hOldOffBmp
= NtGdiSelectBitmap(hdcOff
, hbmOff
);
1614 DPRINT1("NtGdiSelectBitmap() failed!\n");
1620 hOldOffBrush
= NtGdiSelectBrush(hdcOff
, hbrFlickerFreeDraw
);
1623 DPRINT1("NtGdiSelectBitmap() failed!\n");
1627 NtGdiPatBlt(hdcOff
, 0, 0, r
.right
, r
.bottom
, PATCOPY
);
1633 hdcMem
= NtGdiCreateCompatibleDC(hDc
);
1636 DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
1640 nStretchMode
= IntGdiSetStretchBltMode(hdcOff
, STRETCH_DELETESCANS
);
1642 oldFg
= IntGdiSetTextColor(hdcOff
, RGB(0, 0, 0));
1643 oldBg
= IntGdiSetBkColor(hdcOff
, RGB(255, 255, 255));
1645 if (diFlags
& DI_MASK
)
1647 hOldMem
= NtGdiSelectBitmap(hdcMem
, hbmMask
);
1650 DPRINT("NtGdiSelectBitmap() failed!\n");
1654 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1655 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1656 0, 0, IconSize
.cx
, IconSize
.cy
,
1657 ((diFlags
& DI_IMAGE
) ? SRCAND
: SRCCOPY
), FALSE
);
1659 if (!hbmColor
&& (bmpMask
.bmHeight
== 2 * bmpMask
.bmWidth
)
1660 && (diFlags
& DI_IMAGE
))
1662 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1663 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1664 0, IconSize
.cy
, IconSize
.cx
, IconSize
.cy
, SRCINVERT
,
1667 diFlags
&= ~DI_IMAGE
;
1670 NtGdiSelectBitmap(hdcMem
, hOldMem
);
1673 if(diFlags
& DI_IMAGE
)
1675 hOldMem
= NtGdiSelectBitmap(hdcMem
, (hbmColor
? hbmColor
: hbmMask
));
1677 DoStretchBlt(hdcOff
, (DoFlickerFree
? 0 : xLeft
),
1678 (DoFlickerFree
? 0 : yTop
), cxWidth
, cyHeight
, hdcMem
,
1679 0, (hbmColor
? 0 : IconSize
.cy
), IconSize
.cx
, IconSize
.cy
,
1680 ((diFlags
& DI_MASK
) ? SRCINVERT
: SRCCOPY
),
1683 NtGdiSelectBitmap(hdcMem
, hOldMem
);
1689 BITMAPOBJ
*BitmapObj
= NULL
;
1691 BLENDFUNCTION BlendFunc
;
1693 BYTE Red
, Green
, Blue
, Alpha
;
1697 BitmapObj
= BITMAPOBJ_LockBitmap(hbmOff
);
1698 if (BitmapObj
== NULL
)
1700 DPRINT1("GDIOBJ_LockObj() failed!\n");
1703 BITMAP_GetObject(BitmapObj
, sizeof(BITMAP
), &bm
);
1705 pBits
= ExAllocatePoolWithTag(PagedPool
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), TAG_BITMAP
);
1708 DPRINT1("ExAllocatePoolWithTag() failed!\n");
1709 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1714 IntGetBitmapBits(BitmapObj
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), pBits
);
1716 /* premultiply with the alpha channel value */
1717 for (i
= 0; i
< cyHeight
; i
++)
1719 for (j
= 0; j
< cxWidth
; j
++)
1721 Pixel
= *(DWORD
*)(pBits
+ Count
);
1723 Alpha
= ((BYTE
)(Pixel
>> 24) & 0xff);
1725 Red
= (((BYTE
)(Pixel
>> 0)) * Alpha
) / 0xff;
1726 Green
= (((BYTE
)(Pixel
>> 8)) * Alpha
) / 0xff;
1727 Blue
= (((BYTE
)(Pixel
>> 16)) * Alpha
) / 0xff;
1729 *(DWORD
*)(pBits
+ Count
) = (DWORD
)(Red
| (Green
<< 8) | (Blue
<< 16) | (Alpha
<< 24));
1731 Count
+= sizeof (DWORD
);
1736 IntSetBitmapBits(BitmapObj
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), pBits
);
1739 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1741 BlendFunc
.BlendOp
= AC_SRC_OVER
;
1742 BlendFunc
.BlendFlags
= 0;
1743 BlendFunc
.SourceConstantAlpha
= 255;
1744 BlendFunc
.AlphaFormat
= AC_SRC_ALPHA
;
1746 NtGdiAlphaBlend(hDc
, xLeft
, yTop
, cxWidth
, cyHeight
,
1747 hdcOff
, 0, 0, cxWidth
, cyHeight
, BlendFunc
, 0);
1749 else if (DoFlickerFree
)
1751 NtGdiBitBlt(hDc
, xLeft
, yTop
, cxWidth
,
1752 cyHeight
, hdcOff
, 0, 0, SRCCOPY
, 0, 0);
1755 IntGdiSetTextColor(hdcOff
, oldFg
);
1756 IntGdiSetBkColor(hdcOff
, oldBg
);
1757 IntGdiSetStretchBltMode(hdcOff
, nStretchMode
);
1762 if(DoFlickerFree
|| bAlpha
)
1764 if(hOldOffBmp
) NtGdiSelectBitmap(hdcOff
, hOldOffBmp
);
1765 if(hOldOffBrush
) NtGdiSelectBrush(hdcOff
, hOldOffBrush
);
1766 if(hbmOff
) NtGdiDeleteObject(hbmOff
);
1767 if(hdcOff
) NtGdiDeleteObjectApp(hdcOff
);
1770 if(hdcMem
) NtGdiDeleteObjectApp(hdcMem
);
1787 HBRUSH hbrFlickerFreeDraw
,
1792 PCURICON_OBJECT pIcon
;
1795 DPRINT("Enter NtUserDrawIconEx\n");
1796 UserEnterExclusive();
1798 if(!(pIcon
= UserGetCurIconObject(hIcon
)))
1800 DPRINT1("UserGetCurIconObject() failed!\n");
1805 Ret
= UserDrawIconEx(hdc
,
1815 UserDereferenceObject(pIcon
);
1821 /* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
1822 * User32 macro NtUserShowCursor */
1825 UserShowCursor(BOOL bShow
)
1827 PWINSTATION_OBJECT WinSta
= PsGetCurrentThreadWin32Thread()->Desktop
->WindowStation
;
1828 PSYSTEM_CURSORINFO CurInfo
;
1834 BITMAPOBJ
*BitmapObj
;
1839 if(!(Screen
= IntGetScreenDC()))
1841 return showpointer
; /* No mouse */
1844 dc
= DC_LockDc(Screen
);
1848 return showpointer
; /* No mouse */
1851 dcbmp
= dc
->w
.hBitmap
;
1854 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
1857 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1858 return showpointer
; /* No Mouse */
1861 SurfObj
= &BitmapObj
->SurfObj
;
1862 if (SurfObj
== NULL
)
1864 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1865 return showpointer
; /* No mouse */
1868 ppdev
= GDIDEV(SurfObj
);
1872 BITMAPOBJ_UnlockBitmap(BitmapObj
);
1873 return showpointer
; /* No mouse */
1876 pgp
= &ppdev
->Pointer
;
1878 CurInfo
= IntGetSysCursorInfo(WinSta
);
1883 showpointer
= pgp
->ShowPointer
;
1885 if (showpointer
>= 0)
1887 //ppdev->SafetyRemoveCount = 1;
1888 //ppdev->SafetyRemoveLevel = 1;
1889 EngMovePointer(SurfObj
,-1,-1,NULL
);
1890 CurInfo
->ShowingCursor
= 0;
1897 showpointer
= pgp
->ShowPointer
;
1900 if (showpointer
< 0)
1902 //ppdev->SafetyRemoveCount = 0;
1903 //ppdev->SafetyRemoveLevel = 0;
1904 EngMovePointer(SurfObj
,-1,-1,NULL
);
1905 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
1909 BITMAPOBJ_UnlockBitmap(BitmapObj
);