- Fix errors during optimized build.
[reactos.git] / reactos / subsys / win32k / eng / mouse.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id: mouse.c,v 1.75 2004/07/03 17:40:25 navaraf Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * PURPOSE: Mouse
23 * FILE: subsys/win32k/eng/mouse.c
24 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * REVISION HISTORY:
26 * 06-06-2001 CSH Created
27 */
28 /* INCLUDES ******************************************************************/
29 #include <w32k.h>
30
31 /* FUNCTIONS *****************************************************************/
32
33 BOOL FASTCALL
34 IntIsPrimarySurface(SURFOBJ *SurfObj);
35
36 VOID FASTCALL
37 EnableMouse(HDC hDisplayDC)
38 {
39 PDC dc;
40 BITMAPOBJ *BitmapObj;
41 GDIDEVICE *GdiDev;
42 PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo(InputWindowStation);
43
44 if( hDisplayDC && InputWindowStation)
45 {
46 if(!IntGetWindowStationObject(InputWindowStation))
47 {
48 CurInfo->Enabled = FALSE;
49 return;
50 }
51
52 dc = DC_LockDc(hDisplayDC);
53 ASSERT(dc);
54 BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
55 ASSERT(BitmapObj);
56
57 /* Move the cursor to the screen center */
58 DPRINT("Setting Cursor up at 0x%x, 0x%x\n", SurfObj->sizlBitmap.cx / 2, SurfObj->sizlBitmap.cy / 2);
59 ExAcquireFastMutex(&CurInfo->CursorMutex);
60 CurInfo->x = BitmapObj->SurfObj.sizlBitmap.cx / 2;
61 CurInfo->y = BitmapObj->SurfObj.sizlBitmap.cy / 2;
62 ExReleaseFastMutex(&CurInfo->CursorMutex);
63
64 GdiDev = GDIDEV(&BitmapObj->SurfObj);
65 BITMAPOBJ_UnlockBitmap(dc->w.hBitmap);
66 DC_UnlockDc( hDisplayDC );
67
68 IntSetCursor(InputWindowStation, NULL, TRUE);
69
70 CurInfo->Enabled = (SPS_ACCEPT_EXCLUDE == GdiDev->PointerStatus ||
71 SPS_ACCEPT_NOEXCLUDE == GdiDev->PointerStatus);
72
73 IntLoadDefaultCursors();
74
75 ObDereferenceObject(InputWindowStation);
76 }
77 else
78 {
79 if(IntGetWindowStationObject(InputWindowStation))
80 {
81 IntSetCursor(InputWindowStation, NULL, TRUE);
82 CurInfo->Enabled = FALSE;
83 CurInfo->CursorClipInfo.IsClipped = FALSE;
84 ObDereferenceObject(InputWindowStation);
85 return;
86 }
87 }
88 }
89
90 INT FASTCALL
91 MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
92 LONG HazardY1, LONG HazardX2, LONG HazardY2)
93 /*
94 * FUNCTION: Notify the mouse driver that drawing is about to begin in
95 * a rectangle on a particular surface.
96 */
97 {
98 LONG tmp;
99 PSYSTEM_CURSORINFO CurInfo;
100 BOOL MouseEnabled = FALSE;
101 PCURICON_OBJECT Cursor;
102
103
104 /* Mouse is not allowed to move if GDI is busy drawing */
105
106 if(IntGetWindowStationObject(InputWindowStation))
107 {
108 CurInfo = IntGetSysCursorInfo(InputWindowStation);
109
110 MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor;
111 }
112 else
113 return FALSE;
114
115 if (SurfObj == NULL)
116 {
117 ObDereferenceObject(InputWindowStation);
118 return(FALSE);
119 }
120 if (!IntIsPrimarySurface(SurfObj) || MouseEnabled == FALSE)
121 {
122 ObDereferenceObject(InputWindowStation);
123 return(FALSE);
124 }
125
126 if (SPS_ACCEPT_NOEXCLUDE == GDIDEV(SurfObj)->PointerStatus)
127 {
128 /* Hardware cursor, no need to remove it */
129 ObDereferenceObject(InputWindowStation);
130 return(FALSE);
131 }
132
133 if(!(Cursor = CurInfo->CurrentCursorObject))
134 {
135 ObDereferenceObject(InputWindowStation);
136 return(FALSE);
137 }
138
139 if (HazardX1 > HazardX2)
140 {
141 tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp;
142 }
143 if (HazardY1 > HazardY2)
144 {
145 tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
146 }
147
148 if (CurInfo->PointerRectRight >= HazardX1
149 && CurInfo->PointerRectLeft <= HazardX2
150 && CurInfo->PointerRectBottom >= HazardY1
151 && CurInfo->PointerRectTop <= HazardY2)
152 {
153 /* Mouse is not allowed to move if GDI is busy drawing */
154 ExAcquireFastMutex(&CurInfo->CursorMutex);
155 if (0 != CurInfo->SafetyRemoveCount++)
156 {
157 /* Was already removed */
158 ExReleaseFastMutex(&CurInfo->CursorMutex);
159 ObDereferenceObject(InputWindowStation);
160 return FALSE;
161 }
162 CurInfo->SafetySwitch = TRUE;
163 if (GDIDEVFUNCS(SurfObj).MovePointer)
164 GDIDEVFUNCS(SurfObj).MovePointer(SurfObj, -1, -1, NULL);
165 else
166 EngMovePointer(SurfObj, -1, -1, NULL);
167 ExReleaseFastMutex(&CurInfo->CursorMutex);
168 }
169
170 ObDereferenceObject(InputWindowStation);
171 return(TRUE);
172 }
173
174 VOID FASTCALL
175 SetPointerRect(PSYSTEM_CURSORINFO CurInfo, PRECTL PointerRect)
176 {
177 CurInfo->PointerRectLeft = PointerRect->left;
178 CurInfo->PointerRectRight = PointerRect->right;
179 CurInfo->PointerRectTop = PointerRect->top;
180 CurInfo->PointerRectBottom = PointerRect->bottom;
181 }
182
183 INT FASTCALL
184 MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
185 /*
186 * FUNCTION: Notify the mouse driver that drawing has finished on a surface.
187 */
188 {
189 PSYSTEM_CURSORINFO CurInfo;
190 BOOL MouseEnabled = FALSE;
191 RECTL PointerRect;
192
193 if(IntGetWindowStationObject(InputWindowStation))
194 {
195 CurInfo = IntGetSysCursorInfo(InputWindowStation);
196 }
197 else
198 return FALSE;
199
200 ExAcquireFastMutex(&CurInfo->CursorMutex);
201 if(SurfObj == NULL)
202 {
203 ExReleaseFastMutex(&CurInfo->CursorMutex);
204 ObDereferenceObject(InputWindowStation);
205 return FALSE;
206 }
207
208 MouseEnabled = CurInfo->Enabled && CurInfo->ShowingCursor;
209 if (!IntIsPrimarySurface(SurfObj) || MouseEnabled == FALSE)
210 {
211 ExReleaseFastMutex(&CurInfo->CursorMutex);
212 ObDereferenceObject(InputWindowStation);
213 return(FALSE);
214 }
215
216 if (SPS_ACCEPT_NOEXCLUDE == GDIDEV(SurfObj)->PointerStatus)
217 {
218 /* Hardware cursor, it wasn't removed so need to restore it */
219 ExReleaseFastMutex(&CurInfo->CursorMutex);
220 ObDereferenceObject(InputWindowStation);
221 return(FALSE);
222 }
223
224 if (CurInfo->SafetySwitch)
225 {
226 if (1 < CurInfo->SafetyRemoveCount--)
227 {
228 /* Someone else removed it too, let them restore it */
229 ExReleaseFastMutex(&CurInfo->CursorMutex);
230 ObDereferenceObject(InputWindowStation);
231 return FALSE;
232 }
233 if (GDIDEVFUNCS(SurfObj).MovePointer)
234 GDIDEVFUNCS(SurfObj).MovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
235 else
236 EngMovePointer(SurfObj, CurInfo->x, CurInfo->y, &PointerRect);
237 SetPointerRect(CurInfo, &PointerRect);
238 CurInfo->SafetySwitch = FALSE;
239 }
240
241 ExReleaseFastMutex(&CurInfo->CursorMutex);
242 ObDereferenceObject(InputWindowStation);
243 return(TRUE);
244 }
245
246 #define ClearMouseInput(mi) \
247 mi.dx = 0; \
248 mi.dy = 0; \
249 mi.mouseData = 0; \
250 mi.dwFlags = 0;
251
252 #define SendMouseEvent(mi) \
253 if(mi.dx != 0 || mi.dy != 0) \
254 mi.dwFlags |= MOUSEEVENTF_MOVE; \
255 if(mi.dwFlags) \
256 IntMouseInput(&mi); \
257 ClearMouseInput(mi);
258
259 VOID /* STDCALL */
260 MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
261 {
262 PMOUSE_INPUT_DATA mid;
263 MOUSEINPUT mi;
264 ULONG i;
265
266 ClearMouseInput(mi);
267 mi.time = 0;
268 mi.dwExtraInfo = 0;
269 for(i = 0; i < InputCount; i++)
270 {
271 mid = (Data + i);
272 mi.dx += mid->LastX;
273 mi.dy += mid->LastY;
274
275 if(mid->ButtonFlags)
276 {
277 if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
278 {
279 mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
280 SendMouseEvent(mi);
281 }
282 if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
283 {
284 mi.dwFlags |= MOUSEEVENTF_LEFTUP;
285 SendMouseEvent(mi);
286 }
287 if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
288 {
289 mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
290 SendMouseEvent(mi);
291 }
292 if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
293 {
294 mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
295 SendMouseEvent(mi);
296 }
297 if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
298 {
299 mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
300 SendMouseEvent(mi);
301 }
302 if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
303 {
304 mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
305 SendMouseEvent(mi);
306 }
307 if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
308 {
309 mi.mouseData |= XBUTTON1;
310 mi.dwFlags |= MOUSEEVENTF_XDOWN;
311 SendMouseEvent(mi);
312 }
313 if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
314 {
315 mi.mouseData |= XBUTTON1;
316 mi.dwFlags |= MOUSEEVENTF_XUP;
317 SendMouseEvent(mi);
318 }
319 if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
320 {
321 mi.mouseData |= XBUTTON2;
322 mi.dwFlags |= MOUSEEVENTF_XDOWN;
323 SendMouseEvent(mi);
324 }
325 if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
326 {
327 mi.mouseData |= XBUTTON2;
328 mi.dwFlags |= MOUSEEVENTF_XUP;
329 SendMouseEvent(mi);
330 }
331 if(mid->ButtonFlags & MOUSE_WHEEL)
332 {
333 mi.mouseData = mid->ButtonData;
334 mi.dwFlags |= MOUSEEVENTF_WHEEL;
335 SendMouseEvent(mi);
336 }
337 }
338 }
339
340 SendMouseEvent(mi);
341 }
342
343 /* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
344
345 VOID FASTCALL
346 IntHideMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
347 {
348 if (ppdev->PointerAttributes.Enable == FALSE)
349 {
350 return;
351 }
352
353 ppdev->PointerAttributes.Enable = FALSE;
354
355 if (ppdev->PointerAttributes.Column + ppdev->PointerHotSpot.x == -1)
356 {
357 return;
358 }
359
360 if (ppdev->PointerSaveSurface != NULL)
361 {
362 RECTL DestRect;
363 POINTL SrcPoint;
364 SURFOBJ *SaveSurface;
365 SURFOBJ *MaskSurface;
366
367 DestRect.left = max(ppdev->PointerAttributes.Column, 0);
368 DestRect.top = max(ppdev->PointerAttributes.Row, 0);
369 DestRect.right = min(
370 ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width,
371 DestSurface->sizlBitmap.cx);
372 DestRect.bottom = min(
373 ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height,
374 DestSurface->sizlBitmap.cy);
375
376 SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0);
377 SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0);
378
379 SaveSurface = EngLockSurface(ppdev->PointerSaveSurface);
380 MaskSurface = EngLockSurface(ppdev->PointerMaskSurface);
381 EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL,
382 &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY);
383 EngUnlockSurface(MaskSurface);
384 EngUnlockSurface(SaveSurface);
385 }
386 }
387
388 VOID FASTCALL
389 IntShowMousePointer(GDIDEVICE *ppdev, SURFOBJ *DestSurface)
390 {
391 if (ppdev->PointerAttributes.Enable == TRUE)
392 {
393 return;
394 }
395
396 ppdev->PointerAttributes.Enable = TRUE;
397
398 /*
399 * Copy the pixels under the cursor to temporary surface.
400 */
401
402 if (ppdev->PointerSaveSurface != NULL)
403 {
404 RECTL DestRect;
405 POINTL SrcPoint;
406 SURFOBJ *SaveSurface;
407
408 SrcPoint.x = max(ppdev->PointerAttributes.Column, 0);
409 SrcPoint.y = max(ppdev->PointerAttributes.Row, 0);
410
411 DestRect.left = SrcPoint.x - ppdev->PointerAttributes.Column;
412 DestRect.top = SrcPoint.y - ppdev->PointerAttributes.Row;
413 DestRect.right = min(
414 ppdev->PointerAttributes.Width,
415 DestSurface->sizlBitmap.cx - ppdev->PointerAttributes.Column);
416 DestRect.bottom = min(
417 ppdev->PointerAttributes.Height,
418 DestSurface->sizlBitmap.cy - ppdev->PointerAttributes.Row);
419
420 SaveSurface = EngLockSurface(ppdev->PointerSaveSurface);
421 EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL,
422 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY);
423 EngUnlockSurface(SaveSurface);
424 }
425
426 /*
427 * Blit the cursor on the screen.
428 */
429
430 {
431 RECTL DestRect;
432 POINTL SrcPoint;
433 SURFOBJ *ColorSurf;
434 SURFOBJ *MaskSurf;
435
436 DestRect.left = max(ppdev->PointerAttributes.Column, 0);
437 DestRect.top = max(ppdev->PointerAttributes.Row, 0);
438 DestRect.right = min(
439 ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width,
440 DestSurface->sizlBitmap.cx);
441 DestRect.bottom = min(
442 ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height,
443 DestSurface->sizlBitmap.cy);
444
445 SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0);
446 SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0);
447
448 MaskSurf = EngLockSurface(ppdev->PointerMaskSurface);
449 if (ppdev->PointerColorSurface != NULL)
450 {
451 ColorSurf = EngLockSurface(ppdev->PointerColorSurface);
452 EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, ppdev->PointerXlateObject,
453 &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC);
454 EngUnlockSurface(ColorSurf);
455 }
456 else
457 {
458 EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject,
459 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND);
460 SrcPoint.y += ppdev->PointerAttributes.Height;
461 EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject,
462 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT);
463 }
464 EngUnlockSurface(MaskSurf);
465 }
466 }
467
468 /*
469 * @implemented
470 */
471
472 ULONG STDCALL
473 EngSetPointerShape(
474 IN SURFOBJ *pso,
475 IN SURFOBJ *psoMask,
476 IN SURFOBJ *psoColor,
477 IN XLATEOBJ *pxlo,
478 IN LONG xHot,
479 IN LONG yHot,
480 IN LONG x,
481 IN LONG y,
482 IN RECTL *prcl,
483 IN FLONG fl)
484 {
485 GDIDEVICE *ppdev = (GDIDEVICE *)pso->hdev;
486 SURFOBJ *TempSurfObj;
487
488 IntHideMousePointer(ppdev, pso);
489
490 if (ppdev->PointerColorSurface != NULL)
491 {
492 /* FIXME: Is this really needed? */
493 TempSurfObj = EngLockSurface(ppdev->PointerColorSurface);
494 EngFreeMem(TempSurfObj->pvBits);
495 TempSurfObj->pvBits = 0;
496 EngUnlockSurface(TempSurfObj);
497
498 EngDeleteSurface(ppdev->PointerColorSurface);
499 ppdev->PointerMaskSurface = NULL;
500 }
501
502 if (ppdev->PointerMaskSurface != NULL)
503 {
504 /* FIXME: Is this really needed? */
505 TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface);
506 EngFreeMem(TempSurfObj->pvBits);
507 TempSurfObj->pvBits = 0;
508 EngUnlockSurface(TempSurfObj);
509
510 EngDeleteSurface(ppdev->PointerMaskSurface);
511 ppdev->PointerMaskSurface = NULL;
512 }
513
514 if (ppdev->PointerSaveSurface != NULL)
515 {
516 EngDeleteSurface(ppdev->PointerSaveSurface);
517 ppdev->PointerSaveSurface = NULL;
518 }
519
520 if (ppdev->PointerXlateObject != NULL)
521 {
522 EngDeleteXlate(ppdev->PointerXlateObject);
523 ppdev->PointerXlateObject = NULL;
524 }
525
526 /*
527 * See if we are being asked to hide the pointer.
528 */
529
530 if (psoMask == NULL)
531 {
532 return SPS_ACCEPT_NOEXCLUDE;
533 }
534
535 ppdev->PointerHotSpot.x = xHot;
536 ppdev->PointerHotSpot.y = yHot;
537
538 ppdev->PointerAttributes.Column = x - xHot;
539 ppdev->PointerAttributes.Row = y - yHot;
540 ppdev->PointerAttributes.Width = abs(psoMask->lDelta) << 3;
541 ppdev->PointerAttributes.Height = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
542
543 if (prcl != NULL)
544 {
545 prcl->left = ppdev->PointerAttributes.Column;
546 prcl->top = ppdev->PointerAttributes.Row;
547 prcl->right = prcl->left + ppdev->PointerAttributes.Width;
548 prcl->bottom = prcl->top + ppdev->PointerAttributes.Height;
549 }
550
551 if (psoColor != NULL)
552 {
553 SIZEL Size;
554 PBYTE Bits;
555
556 Size.cx = ppdev->PointerAttributes.Width;
557 Size.cy = ppdev->PointerAttributes.Height;
558 Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE);
559 memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
560
561 ppdev->PointerColorSurface = (HSURF)EngCreateBitmap(Size,
562 psoColor->lDelta, psoColor->iBitmapFormat,
563 psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
564 }
565 else
566 {
567 ppdev->PointerColorSurface = NULL;
568 }
569
570 {
571 SIZEL Size;
572 PBYTE Bits;
573
574 Size.cx = ppdev->PointerAttributes.Width;
575 Size.cy = ppdev->PointerAttributes.Height << 1;
576 Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE);
577 memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
578
579 ppdev->PointerMaskSurface = (HSURF)EngCreateBitmap(Size,
580 psoMask->lDelta, psoMask->iBitmapFormat,
581 psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
582 }
583
584 /*
585 * Create an XLATEOBJ that will be used for drawing masks.
586 * FIXME: We should get this in pxlo parameter!
587 */
588
589 if (pxlo == NULL)
590 {
591 HPALETTE BWPalette, DestPalette;
592 ULONG BWColors[] = {0, 0xFFFFFF};
593 PDC Dc;
594 PPALGDI PalObj;
595 LONG DestMode;
596
597 BWPalette = EngCreatePalette(PAL_INDEXED, sizeof(BWColors) / sizeof(ULONG),
598 BWColors, 0, 0, 0);
599 Dc = DC_LockDc(IntGetScreenDC());
600 DestPalette = Dc->w.hPalette;
601 PalObj = PALETTE_LockPalette(DestPalette);
602 DestMode = PalObj->Mode;
603 PALETTE_UnlockPalette(DestPalette);
604 DC_UnlockDc(IntGetScreenDC());
605 ppdev->PointerXlateObject = IntEngCreateXlate(DestMode, PAL_INDEXED,
606 DestPalette, BWPalette);
607 EngDeletePalette(BWPalette);
608 }
609 else
610 {
611 ppdev->PointerXlateObject = pxlo;
612 }
613
614 /*
615 * Create surface for saving the pixels under the cursor.
616 */
617
618 {
619 SIZEL Size;
620 LONG lDelta;
621
622 Size.cx = ppdev->PointerAttributes.Width;
623 Size.cy = ppdev->PointerAttributes.Height;
624
625 switch (pso->iBitmapFormat)
626 {
627 case BMF_1BPP: lDelta = Size.cx >> 3; break;
628 case BMF_4BPP: lDelta = Size.cx >> 1; break;
629 case BMF_8BPP: lDelta = Size.cx; break;
630 case BMF_16BPP: lDelta = Size.cx << 1; break;
631 case BMF_24BPP: lDelta = Size.cx * 3; break;
632 case BMF_32BPP: lDelta = Size.cx << 2; break;
633 default: lDelta = 0; break;
634 }
635
636 ppdev->PointerSaveSurface = (HSURF)EngCreateBitmap(
637 Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
638 }
639
640 IntShowMousePointer(ppdev, pso);
641
642 return SPS_ACCEPT_EXCLUDE;
643 }
644
645 /*
646 * @implemented
647 */
648
649 VOID STDCALL
650 EngMovePointer(
651 IN SURFOBJ *pso,
652 IN LONG x,
653 IN LONG y,
654 IN RECTL *prcl)
655 {
656 GDIDEVICE *ppdev = (GDIDEVICE *)pso->hdev;
657
658 IntHideMousePointer(ppdev, pso);
659 ppdev->PointerAttributes.Column = x - ppdev->PointerHotSpot.x;
660 ppdev->PointerAttributes.Row = y - ppdev->PointerHotSpot.y;
661 if (x != -1)
662 {
663 IntShowMousePointer(ppdev, pso);
664 }
665
666 if (prcl != NULL)
667 {
668 prcl->left = ppdev->PointerAttributes.Column;
669 prcl->top = ppdev->PointerAttributes.Row;
670 prcl->right = prcl->left + ppdev->PointerAttributes.Width;
671 prcl->bottom = prcl->top + ppdev->PointerAttributes.Height;
672 }
673 }
674
675 /* EOF */