ReactOS  0.4.14-dev-323-g6fe6a88
pointer.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS VGA display driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: win32ss/drivers/displays/vga/objects/pointer.c
5  * PURPOSE: Draws the mouse pointer
6  * PROGRAMMERS: Copyright (C) 1998-2001 ReactOS Team
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <vgaddi.h>
12 
13 /* GLOBALS *******************************************************************/
14 
15 static VOID VGADDI_HideCursor(PPDEV ppdev);
16 static VOID VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl);
17 
18 /* FUNCTIONS *****************************************************************/
19 
20 VOID
22  IN LONG StartX,
23  IN LONG StartY,
24  IN ULONG SizeX,
25  IN ULONG SizeY,
26  IN PUCHAR MaskBits,
27  IN ULONG MaskPitch,
28  IN ULONG MaskOp)
29 {
30  ULONG DestX, EndX, DestY, EndY;
31  UCHAR Mask;
32  PUCHAR Video;
33  PUCHAR Src;
34  UCHAR SrcValue;
35  ULONG i, j;
36  ULONG Left;
37  ULONG Length;
38  LONG Bits;
39 
40  DestX = StartX < 0 ? 0 : StartX;
41  DestY = StartY < 0 ? 0 : StartY;
42  EndX = StartX + SizeX;
43  EndY = StartY + SizeY;
44 
45  /* Set write mode zero. */
48 
49  /* Select raster op. */
51  WRITE_PORT_UCHAR((PUCHAR)GRA_D, MaskOp);
52 
53  if ((DestX % 8) != 0)
54  {
55  /* Disable writes to pixels outside of the destination rectangle. */
56  Mask = (1 << (8 - (DestX % 8))) - 1;
57  if ((EndX - DestX) < (8 - (DestX % 8)))
58  {
59  Mask &= ~((1 << (8 - (EndX % 8))) - 1);
60  }
63 
64  /* Write the mask. */
65  Video = (PUCHAR)vidmem + DestY * 80 + (DestX >> 3);
66  Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch;
67  for (i = DestY; i < EndY; i++, Video += 80)
68  {
69  Src -= MaskPitch;
70  SrcValue = (*Src) >> (DestX % 8);
71  (VOID)READ_REGISTER_UCHAR(Video);
72  WRITE_REGISTER_UCHAR(Video, SrcValue);
73  }
74  }
75 
76  /* Enable writes to all pixels. */
79 
80  /* Have we finished. */
81  if ((EndX - DestX) < (8 - (DestX % 8)))
82  return;
83 
84  /* Fill any whole rows of eight pixels. */
85  Left = (DestX + 7) & ~0x7;
86  Length = (EndX >> 3) - (Left >> 3);
87  Bits = StartX;
88  while (Bits < 0)
89  Bits += 8;
90  Bits = Bits % 8;
91  for (i = DestY; i < EndY; i++)
92  {
93  Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
94  Src = MaskBits + (EndY - i - 1) * MaskPitch + ((DestX - StartX) >> 3);
95  for (j = 0; j < Length; j++, Video++, Src++)
96  {
97  if (Bits != 0)
98  {
99  SrcValue = (Src[0] << (8 - Bits));
100  SrcValue |= (Src[1] >> Bits);
101  }
102  else
103  {
104  SrcValue = Src[0];
105  }
106  (VOID)READ_REGISTER_UCHAR(Video);
107  WRITE_REGISTER_UCHAR(Video, SrcValue);
108  }
109  }
110 
111  /* Fill any pixels on the right which don't fall into a complete row. */
112  if ((EndX % 8) != 0)
113  {
114  /* Disable writes to pixels outside the destination rectangle. */
115  Mask = ~((1 << (8 - (EndX % 8))) - 1);
117  WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask);
118 
119  Video = (PUCHAR)vidmem + DestY * 80 + (EndX >> 3);
120  Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch + (SizeX >> 3) - 1;
121  for (i = DestY; i < EndY; i++, Video += 80)
122  {
123  Src -= MaskPitch;
124  SrcValue = (Src[0] << (8 - Bits));
125  (VOID)READ_REGISTER_UCHAR(Video);
126  WRITE_REGISTER_UCHAR(Video, SrcValue);
127  }
128 
129  /* Restore the default write masks. */
131  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
132  }
133 
134  /* Set write mode two. */
137 
138  /* Select raster op replace. */
141 }
142 
144 {
145  ULONG CursorWidth = 32, CursorHeight = 32;
146  ULONG PointerAttributesSize;
147  ULONG SavedMemSize;
148 
149  ppdev->xyHotSpot.x = 0;
150  ppdev->xyHotSpot.y = 0;
151 
152  /* Determine the size of the pointer attributes */
153  PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) +
154  ((CursorWidth * CursorHeight * 2) >> 3);
155 
156  /* Allocate memory for pointer attributes */
157  ppdev->pPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG);
158 
159  ppdev->pPointerAttributes->Flags = 0; /* FIXME: Do this right */
160  ppdev->pPointerAttributes->Width = CursorWidth;
161  ppdev->pPointerAttributes->Height = CursorHeight;
162  ppdev->pPointerAttributes->WidthInBytes = CursorWidth >> 3;
163  ppdev->pPointerAttributes->Enable = 0;
164  ppdev->pPointerAttributes->Column = 0;
165  ppdev->pPointerAttributes->Row = 0;
166 
167  /* Allocate memory for the pixels behind the cursor */
168  SavedMemSize = ((((CursorWidth + 7) & ~0x7) + 16) * CursorHeight) >> 3;
169  ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize);
170 
171  return TRUE;
172 }
173 
176  IN SURFOBJ* pso,
177  IN LONG x,
178  IN LONG y,
179  IN PRECTL prcl)
180 {
181  PPDEV ppdev = (PPDEV)pso->dhpdev;
182 
183  VGADDI_HideCursor(ppdev);
184 
185  if(x != -1)
186  {
187  ppdev->pPointerAttributes->Column = x;
188  ppdev->pPointerAttributes->Row = y;
189 
190  VGADDI_ShowCursor(ppdev, prcl);
191  }
192 }
193 
194 
197  IN SURFOBJ* pso,
198  IN SURFOBJ* psoMask,
200  IN XLATEOBJ* pxlo,
201  IN LONG xHot,
202  IN LONG yHot,
203  IN LONG x,
204  IN LONG y,
205  IN PRECTL prcl,
206  IN ULONG fl)
207 {
208  PPDEV ppdev = (PPDEV)pso->dhpdev;
209  ULONG NewWidth, NewHeight;
210  PUCHAR Src, Dest;
211  ULONG i;
212 
213  if (!psoMask)
214  return SPS_DECLINE;
215 
216  /* Hide the cursor */
217  VGADDI_HideCursor(ppdev);
218 
219  NewWidth = abs(psoMask->lDelta) << 3;
220  NewHeight = (psoMask->cjBits / abs(psoMask->lDelta)) / 2;
221 
222  /* Reallocate the space for the cursor if necessary. */
223  if (ppdev->pPointerAttributes->Width != NewWidth ||
224  ppdev->pPointerAttributes->Height != NewHeight)
225  {
226  ULONG PointerAttributesSize;
227  PVIDEO_POINTER_ATTRIBUTES NewPointerAttributes;
228  ULONG SavedMemSize;
229 
230  /* Determine the size of the pointer attributes */
231  PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) +
232  ((NewWidth * NewHeight * 2) >> 3);
233 
234  /* Allocate memory for pointer attributes */
235  NewPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG);
236  *NewPointerAttributes = *ppdev->pPointerAttributes;
237  NewPointerAttributes->Width = NewWidth;
238  NewPointerAttributes->Height = NewHeight;
239  NewPointerAttributes->WidthInBytes = NewWidth >> 3;
241  ppdev->pPointerAttributes = NewPointerAttributes;
242 
243  /* Reallocate the space for the saved bits. */
245  SavedMemSize = ((((NewWidth + 7) & ~0x7) + 16) * NewHeight) >> 3;
246  ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize);
247  }
248 
249  Src = (PUCHAR)psoMask->pvScan0;
250  /* Copy the new cursor in. */
251  for (i = 0; i < (NewHeight * 2); i++)
252  {
253  Dest = (PUCHAR)ppdev->pPointerAttributes->Pixels;
254  if (i >= NewHeight)
255  Dest += (((NewHeight * 3) - i - 1) * (NewWidth >> 3));
256  else
257  Dest += ((NewHeight - i - 1) * (NewWidth >> 3));
258  memcpy(Dest, Src, NewWidth >> 3);
259  Src += psoMask->lDelta;
260  }
261 
262  /* Set the new cursor position */
263  ppdev->xyHotSpot.x = xHot;
264  ppdev->xyHotSpot.y = yHot;
265 
266  if(x != -1)
267  {
268  ppdev->pPointerAttributes->Column = x;
269  ppdev->pPointerAttributes->Row = y;
270 
271  /* show the cursor */
272  VGADDI_ShowCursor(ppdev, prcl);
273  }
274 
275  return SPS_ACCEPT_NOEXCLUDE;
276 }
277 
278 static VOID FASTCALL
280  IN PPDEV ppdev,
281  IN LONG X,
282  IN LONG Y,
283  IN PRECTL Rect)
284 {
285  ULONG SizeX, SizeY;
286 
287  SizeX = min(((X + (LONG)ppdev->pPointerAttributes->Width) + 7) & ~0x7, ppdev->sizeSurf.cx);
288  SizeX -= (X & ~0x7);
289  SizeY = min((LONG)ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - Y);
290 
291  Rect->left = max(X, 0) & ~0x7;
292  Rect->top = max(Y, 0);
293  Rect->right = Rect->left + SizeX;
294  Rect->bottom = Rect->top + SizeY;
295 }
296 
297 static VOID
299 {
300  if(ppdev->pPointerAttributes->Enable)
301  {
302  LONG cx, cy;
303  RECTL Rect;
304 
305  ppdev->pPointerAttributes->Enable = 0;
306 
307  cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x;
308  cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y;
309 
310  VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect);
311 
312  /* Display what was behind cursor */
314  Rect.top,
315  ppdev->ImageBehindCursor,
316  Rect.right - Rect.left,
317  Rect.bottom - Rect.top);
318  }
319 }
320 
321 static VOID
323 {
324  LONG cx, cy;
325  PUCHAR AndMask, XorMask;
326  ULONG SizeX, SizeY;
327  RECTL Rect;
328 
329  if(ppdev->pPointerAttributes->Enable)
330  return;
331 
332  /* Mark the cursor as currently displayed. */
333  ppdev->pPointerAttributes->Enable = 1;
334 
335  cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x;
336  cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y;
337 
338  /* Capture pixels behind the cursor */
339  VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect);
340 
342  Rect.left,
343  Rect.top,
344  Rect.right - Rect.left,
345  Rect.bottom - Rect.top);
346 
347  /* Display the cursor. */
348  SizeX = min((LONG)ppdev->pPointerAttributes->Width, ppdev->sizeSurf.cx - cx);
349  SizeY = min((LONG)ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - cy);
350  AndMask = ppdev->pPointerAttributes->Pixels +
353  cy,
354  SizeX,
355  SizeY,
356  AndMask,
358  VGA_AND);
359  XorMask = AndMask +
361  ppdev->pPointerAttributes->Height;
363  cy,
364  SizeX,
365  SizeY,
366  XorMask,
368  VGA_XOR);
369 
370  if (NULL != prcl)
371  *prcl = Rect;
372 }
#define abs(i)
Definition: fconv.c:206
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
PBYTE vidmem
Definition: vgavideo.c:18
struct _VIDEO_POINTER_ATTRIBUTES VIDEO_POINTER_ATTRIBUTES
#define TRUE
Definition: types.h:120
VOID VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits)
Definition: offscreen.c:87
#define Y(I)
#define EngFreeMem
Definition: polytest.cpp:56
unsigned char * PUCHAR
Definition: retypes.h:3
#define GRA_I
Definition: vgavideo.h:59
PSAVED_SCREEN_BITS ImageBehindCursor
Definition: vgaddi.h:118
static VOID VGADDI_HideCursor(PPDEV ppdev)
Definition: pointer.c:298
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static ULONG SizeX
Definition: display.c:138
#define SPS_ACCEPT_NOEXCLUDE
Definition: winddi.h:4030
#define FASTCALL
Definition: nt_native.h:50
VOID VGADDI_BltPointerToVGA(IN LONG StartX, IN LONG StartY, IN ULONG SizeX, IN ULONG SizeY, IN PUCHAR MaskBits, IN ULONG MaskPitch, IN ULONG MaskOp)
Definition: pointer.c:21
#define ALLOC_TAG
Definition: btrfs_drv.h:91
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ FLONG fl
Definition: winddi.h:1279
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
VOID APIENTRY DrvMovePointer(IN SURFOBJ *pso, IN LONG x, IN LONG y, IN RECTL *prcl)
Definition: pointer.c:62
_In_opt_ SURFOBJ _In_opt_ SURFOBJ _In_ XLATEOBJ _In_ LONG _In_ LONG yHot
Definition: winddi.h:4049
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
SIZEL sizeSurf
Definition: vgaddi.h:136
smooth NULL
Definition: ftsmooth.c:416
USHORT y
Definition: vgaddi.h:86
LONG cx
Definition: windef.h:319
VOID VGADDI_BltToSavedScreenBits(IN PSAVED_SCREEN_BITS Dest, IN ULONG SourceX, IN ULONG SourceY, IN ULONG SizeX, IN ULONG SizeY)
Definition: offscreen.c:53
BOOL InitPointer(PPDEV ppdev)
Definition: pointer.c:143
USHORT x
Definition: vgaddi.h:85
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_In_ HANDLE _In_ SURFOBJ * pso
Definition: winddi.h:3664
if(!(yy_init))
Definition: macro.lex.yy.c:714
_In_opt_ SURFOBJ _In_opt_ SURFOBJ _In_ XLATEOBJ _In_ LONG xHot
Definition: winddi.h:4049
#define for
Definition: utility.h:88
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define VGA_XOR
Definition: vgavideo.h:10
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
struct _PDEV * PPDEV
VOID VGADDI_BltFromSavedScreenBits(IN ULONG DestX, IN ULONG DestY, IN PSAVED_SCREEN_BITS Src, IN ULONG SizeX, IN ULONG SizeY)
Definition: offscreen.c:20
Definition: framebuf.h:33
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SPS_DECLINE
Definition: winddi.h:4029
#define VOID
Definition: acefi.h:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
_In_opt_ SURFOBJ _In_opt_ SURFOBJ * psoColor
Definition: winddi.h:4049
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes
Definition: driver.h:45
static VOID FASTCALL VGADDI_ComputePointerRect(IN PPDEV ppdev, IN LONG X, IN LONG Y, IN PRECTL Rect)
Definition: pointer.c:279
#define GRA_D
Definition: vgavideo.h:60
#define min(a, b)
Definition: monoChain.cc:55
_In_opt_ SURFOBJ _In_opt_ SURFOBJ * psoMask
Definition: winddi.h:3433
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
_In_ ULONG _In_ CLIPOBJ _In_ RECTL * prcl
Definition: winddi.h:3529
ULONG APIENTRY DrvSetPointerShape(IN SURFOBJ *pso, IN SURFOBJ *psoMask, IN SURFOBJ *psoColor, IN XLATEOBJ *pxlo, IN LONG xHot, IN LONG yHot, IN LONG x, IN LONG y, IN RECTL *prcl, IN FLONG fl)
Definition: pointer.c:35
_Out_opt_ int * cx
Definition: commctrl.h:581
#define VGA_AND
Definition: vgavideo.h:8
unsigned int ULONG
Definition: retypes.h:1
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
static VOID VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl)
Definition: pointer.c:322
XYPAIR xyHotSpot
Definition: vgaddi.h:114
LONG cy
Definition: windef.h:320
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
static ULONG SizeY
Definition: display.c:139
#define APIENTRY
Definition: api.h:79
struct Rect Rect
PSAVED_SCREEN_BITS VGADDI_AllocSavedScreenBits(ULONG Size)
Definition: offscreen.c:121
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ * pxlo
Definition: winddi.h:3414