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: mouse.c,v 1.78 2004/12/12 01:40:36 weiden Exp $
21 * PROJECT: ReactOS kernel
23 * FILE: subsys/win32k/eng/mouse.c
24 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * 06-06-2001 CSH Created
28 /* INCLUDES ******************************************************************/
31 /* FUNCTIONS *****************************************************************/
34 MouseSafetyOnDrawStart(SURFOBJ
*SurfObj
, LONG HazardX1
,
35 LONG HazardY1
, LONG HazardX2
, LONG HazardY2
)
37 * FUNCTION: Notify the mouse driver that drawing is about to begin in
38 * a rectangle on a particular surface.
46 ASSERT(SurfObj
!= NULL
);
48 ppdev
= GDIDEV(SurfObj
);
55 pgp
= &ppdev
->Pointer
;
57 if (SPS_ACCEPT_NOEXCLUDE
== pgp
->Status
)
62 if (HazardX1
> HazardX2
)
64 tmp
= HazardX2
; HazardX2
= HazardX1
; HazardX1
= tmp
;
66 if (HazardY1
> HazardY2
)
68 tmp
= HazardY2
; HazardY2
= HazardY1
; HazardY1
= tmp
;
71 pt
.x
= pgp
->Pos
.x
- pgp
->HotSpot
.x
;
72 pt
.y
= pgp
->Pos
.y
- pgp
->HotSpot
.y
;
74 if (pt
.x
+ pgp
->Size
.cx
>= HazardX1
76 && pt
.y
+ pgp
->Size
.cy
>= HazardY1
79 if (0 != pgp
->SafetyRemoveCount
++)
83 pgp
->SafetySwitch
= TRUE
;
85 pgp
->MovePointer(SurfObj
, -1, -1, NULL
);
87 EngMovePointer(SurfObj
, -1, -1, NULL
);
94 MouseSafetyOnDrawEnd(SURFOBJ
*SurfObj
)
96 * FUNCTION: Notify the mouse driver that drawing has finished on a surface.
102 ASSERT(SurfObj
!= NULL
);
104 ppdev
= GDIDEV(SurfObj
);
111 pgp
= &ppdev
->Pointer
;
113 if(SPS_ACCEPT_NOEXCLUDE
== pgp
->Status
)
118 if (pgp
->SafetySwitch
)
120 if (1 < pgp
->SafetyRemoveCount
--)
122 /* Someone else removed it too, let them restore it */
125 if (pgp
->MovePointer
)
126 pgp
->MovePointer(SurfObj
, pgp
->Pos
.x
, pgp
->Pos
.y
, NULL
);
128 EngMovePointer(SurfObj
, pgp
->Pos
.x
, pgp
->Pos
.y
, NULL
);
129 pgp
->SafetySwitch
= FALSE
;
135 /* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
138 IntHideMousePointer(GDIDEVICE
*ppdev
, SURFOBJ
*DestSurface
)
146 pgp
= &ppdev
->Pointer
;
153 pgp
->Enabled
= FALSE
;
160 pt
.x
= pgp
->Pos
.x
- pgp
->HotSpot
.x
;
161 pt
.y
= pgp
->Pos
.y
- pgp
->HotSpot
.y
;
163 if (pgp
->SaveSurface
!= NULL
)
167 SURFOBJ
*SaveSurface
;
168 SURFOBJ
*MaskSurface
;
170 DestRect
.left
= max(pt
.x
, 0);
171 DestRect
.top
= max(pt
.y
, 0);
172 DestRect
.right
= min(
174 DestSurface
->sizlBitmap
.cx
);
175 DestRect
.bottom
= min(
177 DestSurface
->sizlBitmap
.cy
);
179 SrcPoint
.x
= max(-pt
.x
, 0);
180 SrcPoint
.y
= max(-pt
.y
, 0);
182 if((SaveSurface
= EngLockSurface(pgp
->SaveSurface
)))
184 if((MaskSurface
= EngLockSurface(pgp
->MaskSurface
)))
186 EngBitBlt(DestSurface
, SaveSurface
, MaskSurface
, NULL
, NULL
,
187 &DestRect
, &SrcPoint
, &SrcPoint
, NULL
, NULL
, SRCCOPY
);
188 EngUnlockSurface(MaskSurface
);
190 EngUnlockSurface(SaveSurface
);
196 IntShowMousePointer(GDIDEVICE
*ppdev
, SURFOBJ
*DestSurface
)
199 SURFOBJ
*SaveSurface
;
205 pgp
= &ppdev
->Pointer
;
214 pt
.x
= pgp
->Pos
.x
- pgp
->HotSpot
.x
;
215 pt
.y
= pgp
->Pos
.y
- pgp
->HotSpot
.y
;
218 * Copy the pixels under the cursor to temporary surface.
221 if (pgp
->SaveSurface
!= NULL
&&
222 (SaveSurface
= EngLockSurface(pgp
->SaveSurface
)))
227 SrcPoint
.x
= max(pt
.x
, 0);
228 SrcPoint
.y
= max(pt
.y
, 0);
230 DestRect
.left
= SrcPoint
.x
- pt
.x
;
231 DestRect
.top
= SrcPoint
.y
- pt
.y
;
232 DestRect
.right
= min(
234 DestSurface
->sizlBitmap
.cx
- pt
.x
);
235 DestRect
.bottom
= min(
237 DestSurface
->sizlBitmap
.cy
- pt
.y
);
239 EngBitBlt(SaveSurface
, DestSurface
, NULL
, NULL
, NULL
,
240 &DestRect
, &SrcPoint
, NULL
, NULL
, NULL
, SRCCOPY
);
241 EngUnlockSurface(SaveSurface
);
245 * Blit the cursor on the screen.
254 DestRect
.left
= max(pt
.x
, 0);
255 DestRect
.top
= max(pt
.y
, 0);
256 DestRect
.right
= min(
258 DestSurface
->sizlBitmap
.cx
);
259 DestRect
.bottom
= min(
261 DestSurface
->sizlBitmap
.cy
);
263 SrcPoint
.x
= max(-pt
.x
, 0);
264 SrcPoint
.y
= max(-pt
.y
, 0);
266 MaskSurf
= EngLockSurface(pgp
->MaskSurface
);
267 if (MaskSurf
!= NULL
)
269 if (pgp
->ColorSurface
!= NULL
)
271 if((ColorSurf
= EngLockSurface(pgp
->ColorSurface
)))
273 EngBitBlt(DestSurface
, ColorSurf
, MaskSurf
, NULL
, pgp
->XlateObject
,
274 &DestRect
, &SrcPoint
, &SrcPoint
, NULL
, NULL
, 0xAACC);
275 EngUnlockSurface(ColorSurf
);
280 EngBitBlt(DestSurface
, MaskSurf
, NULL
, NULL
, pgp
->XlateObject
,
281 &DestRect
, &SrcPoint
, NULL
, NULL
, NULL
, SRCAND
);
282 SrcPoint
.y
+= pgp
->Size
.cy
;
283 EngBitBlt(DestSurface
, MaskSurf
, NULL
, NULL
, pgp
->XlateObject
,
284 &DestRect
, &SrcPoint
, NULL
, NULL
, NULL
, SRCINVERT
);
286 EngUnlockSurface(MaskSurf
);
299 IN SURFOBJ
*psoColor
,
309 SURFOBJ
*TempSurfObj
;
315 pgp
= &ppdev
->Pointer
;
317 IntHideMousePointer(ppdev
, pso
);
319 if (pgp
->ColorSurface
!= NULL
)
321 /* FIXME: Is this really needed? */
322 if((TempSurfObj
= EngLockSurface(pgp
->ColorSurface
)))
324 EngFreeMem(TempSurfObj
->pvBits
);
325 TempSurfObj
->pvBits
= 0;
326 EngUnlockSurface(TempSurfObj
);
329 EngDeleteSurface(pgp
->ColorSurface
);
330 pgp
->MaskSurface
= NULL
;
333 if (pgp
->MaskSurface
!= NULL
)
335 /* FIXME: Is this really needed? */
336 if((TempSurfObj
= EngLockSurface(pgp
->MaskSurface
)))
338 EngFreeMem(TempSurfObj
->pvBits
);
339 TempSurfObj
->pvBits
= 0;
340 EngUnlockSurface(TempSurfObj
);
343 EngDeleteSurface(pgp
->MaskSurface
);
344 pgp
->MaskSurface
= NULL
;
347 if (pgp
->SaveSurface
!= NULL
)
349 EngDeleteSurface(pgp
->SaveSurface
);
350 pgp
->SaveSurface
= NULL
;
353 if (pgp
->XlateObject
!= NULL
)
355 EngDeleteXlate(pgp
->XlateObject
);
356 pgp
->XlateObject
= NULL
;
360 * See if we are being asked to hide the pointer.
365 return SPS_ACCEPT_NOEXCLUDE
;
368 pgp
->HotSpot
.x
= xHot
;
369 pgp
->HotSpot
.y
= yHot
;
373 pgp
->Size
.cx
= abs(psoMask
->lDelta
) << 3;
374 pgp
->Size
.cy
= (psoMask
->cjBits
/ abs(psoMask
->lDelta
)) >> 1;
378 /* FIXME - right rectangle when x == -1? */
379 prcl
->left
= pgp
->Pos
.x
- pgp
->HotSpot
.x
;
380 prcl
->top
= pgp
->Pos
.y
- pgp
->HotSpot
.x
;
381 prcl
->right
= prcl
->left
+ pgp
->Size
.cx
;
382 prcl
->bottom
= prcl
->top
+ pgp
->Size
.cy
;
385 if (psoColor
!= NULL
)
389 Bits
= EngAllocMem(0, psoColor
->cjBits
, TAG_MOUSE
);
390 memcpy(Bits
, psoColor
->pvBits
, psoColor
->cjBits
);
392 pgp
->ColorSurface
= (HSURF
)EngCreateBitmap(pgp
->Size
,
393 psoColor
->lDelta
, psoColor
->iBitmapFormat
,
394 psoColor
->lDelta
< 0 ? 0 : BMF_TOPDOWN
, Bits
);
398 pgp
->ColorSurface
= NULL
;
405 Size
.cx
= pgp
->Size
.cx
;
406 Size
.cy
= pgp
->Size
.cy
<< 1;
407 Bits
= EngAllocMem(0, psoMask
->cjBits
, TAG_MOUSE
);
408 memcpy(Bits
, psoMask
->pvBits
, psoMask
->cjBits
);
410 pgp
->MaskSurface
= (HSURF
)EngCreateBitmap(Size
,
411 psoMask
->lDelta
, psoMask
->iBitmapFormat
,
412 psoMask
->lDelta
< 0 ? 0 : BMF_TOPDOWN
, Bits
);
416 * Create an XLATEOBJ that will be used for drawing masks.
417 * FIXME: We should get this in pxlo parameter!
422 HPALETTE BWPalette
, DestPalette
;
423 ULONG BWColors
[] = {0, 0xFFFFFF};
425 BWPalette
= EngCreatePalette(PAL_INDEXED
, sizeof(BWColors
) / sizeof(ULONG
),
428 DestPalette
= ppdev
->DevInfo
.hpalDefault
;
429 pgp
->XlateObject
= IntEngCreateXlate(0, PAL_INDEXED
,
430 DestPalette
, BWPalette
);
431 EngDeletePalette(BWPalette
);
435 pgp
->XlateObject
= pxlo
;
439 * Create surface for saving the pixels under the cursor.
445 switch (pso
->iBitmapFormat
)
448 lDelta
= pgp
->Size
.cx
>> 3;
451 lDelta
= pgp
->Size
.cx
>> 1;
454 lDelta
= pgp
->Size
.cx
;
457 lDelta
= pgp
->Size
.cx
<< 1;
460 lDelta
= pgp
->Size
.cx
* 3;
463 lDelta
= pgp
->Size
.cx
<< 2;
470 pgp
->SaveSurface
= (HSURF
)EngCreateBitmap(
471 pgp
->Size
, lDelta
, pso
->iBitmapFormat
, BMF_TOPDOWN
| BMF_NOZEROINIT
, NULL
);
476 IntShowMousePointer(ppdev
, pso
);
479 return SPS_ACCEPT_EXCLUDE
;
502 pgp
= &ppdev
->Pointer
;
505 IntHideMousePointer(ppdev
, pso
);
510 IntShowMousePointer(ppdev
, pso
);
515 /* FIXME - right rectangle when x == -1? */
516 prcl
->left
= pgp
->Pos
.x
- pgp
->HotSpot
.x
;
517 prcl
->top
= pgp
->Pos
.y
- pgp
->HotSpot
.x
;
518 prcl
->right
= prcl
->left
+ pgp
->Size
.cx
;
519 prcl
->bottom
= prcl
->top
+ pgp
->Size
.cy
;