[USER32_WSPRINTF]
[reactos.git] / reactos / drivers / video / displays / framebufacc / pointer.c
1 /*
2 * ReactOS Generic Framebuffer display driver
3 *
4 * Copyright (C) 2007 Magnus Olsen
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "framebufacc.h"
22
23
24
25 /*
26 * DrvMovePointer
27 *
28 * Moves the pointer to a new position and ensures that GDI does not interfere
29 * with the display of the pointer.
30 *
31 * Status
32 * @implemented
33 */
34
35 VOID APIENTRY
36 DrvMovePointer(IN SURFOBJ *pso,
37 IN LONG x,
38 IN LONG y,
39 IN RECTL *prcl)
40 {
41 PPDEV ppdev = (PPDEV) pso->dhpdev;
42 DWORD returnedDataLength;
43 VIDEO_POINTER_POSITION NewPointerPosition;
44
45 x -= ppdev->ScreenOffsetXY.x;
46 y -= ppdev->ScreenOffsetXY.y;
47
48 /* position of (-1,-1) hide the pointer */
49 if ((x == -1) || (y == -1))
50 {
51 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &returnedDataLength))
52 {
53 /* hw did not disable the mouse, we try then with software */
54 EngMovePointer(pso, x, y, prcl);
55 }
56 }
57 else
58 {
59 /* Calc the mouse positions and set it to the new positions */
60 NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->PointerHotSpot.x);
61 NewPointerPosition.Row = (SHORT) y - (SHORT) (ppdev->PointerHotSpot.y);
62
63 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_POINTER_POSITION, &NewPointerPosition,
64 sizeof(VIDEO_POINTER_POSITION), NULL, 0, &returnedDataLength))
65 {
66 /* hw did not disable the mouse, we try then with software */
67 EngMovePointer(pso, x, y, prcl);
68 }
69 }
70 }
71
72
73 /*
74 * DrvSetPointerShape
75 *
76 * Sets the new pointer shape.
77 *
78 * Status
79 * @implemented
80 */
81
82 ULONG APIENTRY
83 DrvSetPointerShape(
84 IN SURFOBJ *pso,
85 IN SURFOBJ *psoMask,
86 IN SURFOBJ *psoColor,
87 IN XLATEOBJ *pxlo,
88 IN LONG xHot,
89 IN LONG yHot,
90 IN LONG x,
91 IN LONG y,
92 IN RECTL *prcl,
93 IN FLONG fl)
94 {
95 PPDEV ppdev = (PPDEV) pso->dhpdev;
96 ULONG returnedDataLength = 0;
97
98 if (ppdev->pPointerAttributes == NULL)
99 {
100 /* hw did not support hw mouse pointer, we try then with software */
101 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
102 }
103
104 /* check see if the apps ask to hide the mouse or not */
105 if (psoMask == (SURFOBJ *) NULL)
106 {
107 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &returnedDataLength))
108 {
109 /* no hw support found for the mouse we try then the software version */
110 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
111 }
112
113 return TRUE;
114 }
115
116 /* set our hotspot */
117 ppdev->PointerHotSpot.x = xHot;
118 ppdev->PointerHotSpot.y = yHot;
119
120 /* Set the hw mouse shape */
121
122 if (psoColor != (SURFOBJ *) NULL)
123 {
124 /* We got a color mouse pointer */
125 if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) &&
126 (CopyColorPointer(ppdev, psoMask, psoColor, pxlo)) )
127 {
128 ppdev->pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER;
129 }
130 else
131 {
132 /* No color mouse pointer being set, so we need try the software version then */
133 if (ppdev->HwMouseActive)
134 {
135 ppdev->HwMouseActive = FALSE;
136 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &returnedDataLength))
137 {
138 /* hw did not support hw mouse pointer, we try then with software */
139 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
140 }
141 }
142 return SPS_DECLINE ;
143 }
144 }
145 else
146 {
147 /* We got a mono mouse pointer */
148 if ( (ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) &&
149 (CopyMonoPointer(ppdev, psoMask)))
150 {
151 ppdev->pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER;
152 }
153 else
154 {
155 /* No mono mouse pointer being set, so we need try the software version then */
156 if (ppdev->HwMouseActive)
157 {
158 ppdev->HwMouseActive = FALSE;
159 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_DISABLE_POINTER, NULL, 0, NULL, 0, &returnedDataLength))
160 {
161 /* hw did not support hw mouse pointer, we try then with software */
162 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
163 }
164 }
165 return SPS_DECLINE ;
166 }
167 }
168
169 /* we goto hw mouse pointer then we contnue filling in more info */
170
171 /* calc the mouse point positions */
172 if ((x != -1) || (y != -1))
173 {
174 ppdev->pPointerAttributes->Column -= (SHORT)(ppdev->PointerHotSpot.x);
175 ppdev->pPointerAttributes->Row -= (SHORT)(ppdev->PointerHotSpot.y);
176 }
177
178 /* set correct flags if it animated or need be updated anime or no flags at all */
179 if (fl & SPS_ANIMATESTART)
180 {
181 ppdev->pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START;
182 }
183 else if (fl & SPS_ANIMATEUPDATE)
184 {
185 ppdev->pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE;
186 }
187
188 ppdev->pPointerAttributes->Enable = 1;
189 ppdev->pPointerAttributes->Column = (SHORT)(x);
190 ppdev->pPointerAttributes->Row = (SHORT)(y);
191
192 /* Set the new mouse pointer shape */
193 if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_POINTER_ATTR, ppdev->pPointerAttributes,
194 ppdev->PointerAttributesSize, NULL, 0, &returnedDataLength))
195 {
196 /* no hw support found for the mouse we try then the software version */
197 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
198 }
199
200 /* we got real hw support */
201 ppdev->HwMouseActive = TRUE;
202 return SPS_ACCEPT_NOEXCLUDE;
203 }
204
205
206 /* Internal api that are only use in DrvSetPointerShape */
207
208 BOOL
209 CopyColorPointer(PPDEV ppdev,
210 SURFOBJ *psoMask,
211 SURFOBJ *psoColor,
212 XLATEOBJ *pxlo)
213 {
214 /* FIXME unimplement */
215 return FALSE;
216 }
217
218 BOOL
219 CopyMonoPointer(PPDEV ppdev,
220 SURFOBJ *pso)
221 {
222 /* FIXME unimplement */
223 return FALSE;
224 }
225
226