2 * PROJECT: ReactOS win32 subsystem
3 * PURPOSE: Mouse pointer functions
4 * FILE: subsystems/win32k/eng/mouse.c
5 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * Timo Kreuzer (timo.kreuzer@reactos.org)
8 * 06-06-2001 CSH Created
10 /* INCLUDES ******************************************************************/
17 /* FUNCTIONS *****************************************************************/
20 * FUNCTION: Notify the mouse driver that drawing is about to begin in
21 * a rectangle on a particular surface.
24 MouseSafetyOnDrawStart(
43 pgp
= &ppdev
->Pointer
;
45 if (pgp
->Exclude
.right
== -1)
50 ppdev
->SafetyRemoveCount
++;
52 if (ppdev
->SafetyRemoveLevel
!= 0)
57 if (HazardX1
> HazardX2
)
63 if (HazardY1
> HazardY2
)
70 if (pgp
->Exclude
.right
>= HazardX1
71 && pgp
->Exclude
.left
<= HazardX2
72 && pgp
->Exclude
.bottom
>= HazardY1
73 && pgp
->Exclude
.top
<= HazardY2
)
75 ppdev
->SafetyRemoveLevel
= ppdev
->SafetyRemoveCount
;
76 ppdev
->pfnMovePointer(pso
, -1, -1, NULL
);
83 * FUNCTION: Notify the mouse driver that drawing has finished on a surface.
94 ppdev
= (PDEVOBJ
*)pso
->hdev
;
101 pgp
= &ppdev
->Pointer
;
103 if (pgp
->Exclude
.right
== -1)
108 if (--ppdev
->SafetyRemoveCount
>= ppdev
->SafetyRemoveLevel
)
113 ppdev
->pfnMovePointer(pso
, gpsi
->ptCursor
.x
, gpsi
->ptCursor
.y
, &pgp
->Exclude
);
115 ppdev
->SafetyRemoveLevel
= 0;
120 /* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
136 pgp
= &ppdev
->Pointer
;
143 pgp
->Enabled
= FALSE
;
145 /* The mouse is hide from ShowCours and it is frist ?? */
146 if (pgp
->ShowPointer
< 0)
153 DPRINT1("No SaveSurface!\n");
157 /* Calculate cursor coordinates */
158 pt
.x
= ppdev
->ptlPointer
.x
- pgp
->HotSpot
.x
;
159 pt
.y
= ppdev
->ptlPointer
.y
- pgp
->HotSpot
.y
;
161 rclDest
.left
= max(pt
.x
, 0);
162 rclDest
.top
= max(pt
.y
, 0);
163 rclDest
.right
= min(pt
.x
+ pgp
->Size
.cx
, psoDest
->sizlBitmap
.cx
);
164 rclDest
.bottom
= min(pt
.y
+ pgp
->Size
.cy
, psoDest
->sizlBitmap
.cy
);
166 ptlSave
.x
= rclDest
.left
- pt
.x
;
167 ptlSave
.y
= rclDest
.top
- pt
.y
;
169 IntEngBitBltEx(psoDest
,
170 &pgp
->psurfSave
->SurfObj
,
179 ROP3_TO_ROP4(SRCCOPY
),
185 IntShowMousePointer(PDEVOBJ
*ppdev
, SURFOBJ
*psoDest
)
189 RECTL rclSurf
, rclPointer
;
194 pgp
= &ppdev
->Pointer
;
203 /* Do not blt the pointer, if it is hidden */
204 if (pgp
->ShowPointer
< 0)
209 /* Calculate pointer coordinates */
210 pt
.x
= ppdev
->ptlPointer
.x
- pgp
->HotSpot
.x
;
211 pt
.y
= ppdev
->ptlPointer
.y
- pgp
->HotSpot
.y
;
213 /* Calculate the rect on the surface */
214 rclSurf
.left
= max(pt
.x
, 0);
215 rclSurf
.top
= max(pt
.y
, 0);
216 rclSurf
.right
= min(pt
.x
+ pgp
->Size
.cx
, psoDest
->sizlBitmap
.cx
);
217 rclSurf
.bottom
= min(pt
.y
+ pgp
->Size
.cy
, psoDest
->sizlBitmap
.cy
);
219 /* Calculate the rect in the pointer bitmap */
220 rclPointer
.left
= rclSurf
.left
- pt
.x
;
221 rclPointer
.top
= rclSurf
.top
- pt
.y
;
222 rclPointer
.right
= min(pgp
->Size
.cx
, psoDest
->sizlBitmap
.cx
- pt
.x
);
223 rclPointer
.bottom
= min(pgp
->Size
.cy
, psoDest
->sizlBitmap
.cy
- pt
.y
);
225 /* Copy the pixels under the cursor to temporary surface. */
226 IntEngBitBltEx(&pgp
->psurfSave
->SurfObj
,
236 ROP3_TO_ROP4(SRCCOPY
),
239 /* Blt the pointer on the screen. */
242 IntEngBitBltEx(psoDest
,
243 &pgp
->psurfColor
->SurfObj
,
244 &pgp
->psurfMask
->SurfObj
,
248 (POINTL
*)&rclPointer
,
249 (POINTL
*)&rclPointer
,
257 IntEngBitBltEx(psoDest
,
258 &pgp
->psurfMask
->SurfObj
,
263 (POINTL
*)&rclPointer
,
267 ROP3_TO_ROP4(SRCAND
),
270 rclPointer
.top
+= pgp
->Size
.cy
;
272 IntEngBitBltEx(psoDest
,
273 &pgp
->psurfMask
->SurfObj
,
278 (POINTL
*)&rclPointer
,
282 ROP3_TO_ROP4(SRCINVERT
),
294 IN SURFOBJ
*psoColor
,
313 pgp
= &ppdev
->Pointer
;
315 IntHideMousePointer(ppdev
, pso
);
319 /* FIXME: let GDI allocate/free memory */
320 EngFreeMem(pgp
->psurfColor
->SurfObj
.pvBits
);
321 pgp
->psurfColor
->SurfObj
.pvBits
= 0;
323 EngDeleteSurface(pgp
->psurfColor
->BaseObject
.hHmgr
);
324 SURFACE_ShareUnlockSurface(pgp
->psurfColor
);
325 pgp
->psurfColor
= NULL
;
330 /* FIXME: let GDI allocate/free memory */
331 EngFreeMem(pgp
->psurfMask
->SurfObj
.pvBits
);
332 pgp
->psurfMask
->SurfObj
.pvBits
= 0;
334 EngDeleteSurface(pgp
->psurfMask
->BaseObject
.hHmgr
);
335 SURFACE_ShareUnlockSurface(pgp
->psurfMask
);
336 pgp
->psurfMask
= NULL
;
339 if (pgp
->psurfSave
!= NULL
)
341 EngDeleteSurface(pgp
->psurfSave
->BaseObject
.hHmgr
);
342 SURFACE_ShareUnlockSurface(pgp
->psurfSave
);
343 pgp
->psurfSave
= NULL
;
346 if (pgp
->XlateObject
!= NULL
)
348 EngDeleteXlate(pgp
->XlateObject
);
349 pgp
->XlateObject
= NULL
;
352 /* See if we are being asked to hide the pointer. */
355 return SPS_ACCEPT_NOEXCLUDE
;
358 pgp
->HotSpot
.x
= xHot
;
359 pgp
->HotSpot
.y
= yHot
;
363 ppdev
->ptlPointer
.x
= x
;
364 ppdev
->ptlPointer
.y
= y
;
367 pgp
->Size
.cx
= abs(psoMask
->lDelta
) << 3;
368 pgp
->Size
.cy
= (psoMask
->cjBits
/ abs(psoMask
->lDelta
)) >> 1;
370 if (psoColor
!= NULL
)
372 /* FIXME: let GDI allocate/free memory */
373 Bits
= EngAllocMem(0, psoColor
->cjBits
, TAG_MOUSE
);
379 memcpy(Bits
, psoColor
->pvBits
, psoColor
->cjBits
);
381 hbmp
= EngCreateBitmap(pgp
->Size
,
383 psoColor
->iBitmapFormat
,
384 psoColor
->lDelta
< 0 ? 0 : BMF_TOPDOWN
,
387 pgp
->psurfColor
= SURFACE_ShareLockSurface(hbmp
);
391 pgp
->psurfColor
= NULL
;
394 Size
.cx
= pgp
->Size
.cx
;
395 Size
.cy
= pgp
->Size
.cy
<< 1;
396 Bits
= EngAllocMem(0, psoMask
->cjBits
, TAG_MOUSE
);
402 memcpy(Bits
, psoMask
->pvBits
, psoMask
->cjBits
);
404 hbmp
= EngCreateBitmap(Size
,
406 psoMask
->iBitmapFormat
,
407 psoMask
->lDelta
< 0 ? 0 : BMF_TOPDOWN
,
410 pgp
->psurfMask
= SURFACE_ShareLockSurface(hbmp
);
412 /* Create an XLATEOBJ that will be used for drawing masks.
413 * FIXME: We should get this in pxlo parameter! */
416 HPALETTE BWPalette
, DestPalette
;
417 ULONG BWColors
[] = {0, 0xFFFFFF};
419 BWPalette
= EngCreatePalette(PAL_INDEXED
, sizeof(BWColors
) / sizeof(ULONG
),
422 DestPalette
= ppdev
->DevInfo
.hpalDefault
;
423 pgp
->XlateObject
= IntEngCreateXlate(0, PAL_INDEXED
,
424 DestPalette
, BWPalette
);
425 EngDeletePalette(BWPalette
);
429 pgp
->XlateObject
= pxlo
;
432 /* Create surface for saving the pixels under the cursor. */
433 switch (pso
->iBitmapFormat
)
436 lDelta
= pgp
->Size
.cx
>> 3;
439 lDelta
= pgp
->Size
.cx
>> 1;
442 lDelta
= pgp
->Size
.cx
;
445 lDelta
= pgp
->Size
.cx
<< 1;
448 lDelta
= pgp
->Size
.cx
* 3;
451 lDelta
= pgp
->Size
.cx
<< 2;
458 hbmp
= EngCreateBitmap(pgp
->Size
,
461 BMF_TOPDOWN
| BMF_NOZEROINIT
,
464 pgp
->psurfSave
= SURFACE_ShareLockSurface(hbmp
);
468 IntShowMousePointer(ppdev
, pso
);
472 prcl
->left
= x
- pgp
->HotSpot
.x
;
473 prcl
->top
= y
- pgp
->HotSpot
.x
;
474 prcl
->right
= prcl
->left
+ pgp
->Size
.cx
;
475 prcl
->bottom
= prcl
->top
+ pgp
->Size
.cy
;
477 } else if (prcl
!= NULL
)
478 prcl
->left
= prcl
->top
= prcl
->right
= prcl
->bottom
= -1;
480 return SPS_ACCEPT_NOEXCLUDE
;
502 pgp
= &ppdev
->Pointer
;
504 IntHideMousePointer(ppdev
, pso
);
506 ppdev
->ptlPointer
.x
= x
;
507 ppdev
->ptlPointer
.y
= y
;
511 IntShowMousePointer(ppdev
, pso
);
514 prcl
->left
= x
- pgp
->HotSpot
.x
;
515 prcl
->top
= y
- pgp
->HotSpot
.x
;
516 prcl
->right
= prcl
->left
+ pgp
->Size
.cx
;
517 prcl
->bottom
= prcl
->top
+ pgp
->Size
.cy
;
519 } else if (prcl
!= NULL
)
520 prcl
->left
= prcl
->top
= prcl
->right
= prcl
->bottom
= -1;
530 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
531 PPDEVOBJ ppdev
= (PPDEVOBJ
)pso
->hdev
;
533 SURFACE_LockBitmapBits(psurf
);
534 ppdev
->pfnMovePointer(pso
, x
, y
, prcl
);
535 SURFACE_UnlockBitmapBits(psurf
);
539 IntEngSetPointerShape(
542 IN SURFOBJ
*psoColor
,
551 ULONG ulResult
= SPS_DECLINE
;
552 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
553 PFN_DrvSetPointerShape pfnSetPointerShape
;
554 PPDEVOBJ ppdev
= GDIDEV(pso
);
556 pfnSetPointerShape
= GDIDEVFUNCS(pso
).SetPointerShape
;
558 SURFACE_LockBitmapBits(psurf
);
559 if (pfnSetPointerShape
)
561 ulResult
= pfnSetPointerShape(pso
,
573 /* Check if the driver accepted it */
574 if (ulResult
== SPS_ACCEPT_NOEXCLUDE
)
576 /* Set MovePointer to the driver function */
577 ppdev
->pfnMovePointer
= GDIDEVFUNCS(pso
).MovePointer
;
581 /* Set software pointer */
582 ulResult
= EngSetPointerShape(pso
,
592 /* Set MovePointer to the eng function */
593 ppdev
->pfnMovePointer
= EngMovePointer
;
596 SURFACE_UnlockBitmapBits(psurf
);