1 /* 2 * ReactOS Generic Framebuffer display driver 3 * 4 * Copyright (C) 2004 Filip Navara 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 "framebuf.h" 22 23 #ifndef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT 24 25 /* 26 * DrvSetPointerShape 27 * 28 * Sets the new pointer shape. 29 * 30 * Status 31 * @unimplemented 32 */ 33 34 ULONG APIENTRY 35 DrvSetPointerShape( 36 IN SURFOBJ *pso, 37 IN SURFOBJ *psoMask, 38 IN SURFOBJ *psoColor, 39 IN XLATEOBJ *pxlo, 40 IN LONG xHot, 41 IN LONG yHot, 42 IN LONG x, 43 IN LONG y, 44 IN RECTL *prcl, 45 IN FLONG fl) 46 { 47 /* return SPS_DECLINE;*/ 48 return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl); 49 } 50 51 /* 52 * DrvMovePointer 53 * 54 * Moves the pointer to a new position and ensures that GDI does not interfere 55 * with the display of the pointer. 56 * 57 * Status 58 * @unimplemented 59 */ 60 61 VOID APIENTRY 62 DrvMovePointer( 63 IN SURFOBJ *pso, 64 IN LONG x, 65 IN LONG y, 66 IN RECTL *prcl) 67 { 68 EngMovePointer(pso, x, y, prcl); 69 } 70 71 #else 72 73 VOID FASTCALL 74 IntHideMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) 75 { 76 if (ppdev->PointerAttributes.Enable == FALSE) 77 { 78 return; 79 } 80 81 ppdev->PointerAttributes.Enable = FALSE; 82 if (ppdev->PointerSaveSurface != NULL) 83 { 84 RECTL DestRect; 85 POINTL SrcPoint; 86 SURFOBJ *SaveSurface; 87 SURFOBJ *MaskSurface; 88 89 DestRect.left = max(ppdev->PointerAttributes.Column, 0); 90 DestRect.top = max(ppdev->PointerAttributes.Row, 0); 91 DestRect.right = min( 92 ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, 93 ppdev->ScreenWidth - 1); 94 DestRect.bottom = min( 95 ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, 96 ppdev->ScreenHeight - 1); 97 98 SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); 99 SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); 100 101 SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); 102 MaskSurface = EngLockSurface(ppdev->PointerMaskSurface); 103 EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL, 104 &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY); 105 EngUnlockSurface(MaskSurface); 106 EngUnlockSurface(SaveSurface); 107 } 108 } 109 110 VOID FASTCALL 111 IntShowMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) 112 { 113 if (ppdev->PointerAttributes.Enable) 114 { 115 return; 116 } 117 118 ppdev->PointerAttributes.Enable = TRUE; 119 120 /* 121 * Copy the pixels under the cursor to temporary surface. 122 */ 123 124 if (ppdev->PointerSaveSurface != NULL) 125 { 126 RECTL DestRect; 127 POINTL SrcPoint; 128 SURFOBJ *SaveSurface; 129 130 SrcPoint.x = max(ppdev->PointerAttributes.Column, 0); 131 SrcPoint.y = max(ppdev->PointerAttributes.Row, 0); 132 133 DestRect.left = SrcPoint.x - ppdev->PointerAttributes.Column; 134 DestRect.top = SrcPoint.y - ppdev->PointerAttributes.Row; 135 DestRect.right = min( 136 ppdev->PointerAttributes.Width, 137 ppdev->ScreenWidth - ppdev->PointerAttributes.Column - 1); 138 DestRect.bottom = min( 139 ppdev->PointerAttributes.Height, 140 ppdev->ScreenHeight - ppdev->PointerAttributes.Row - 1); 141 142 SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); 143 EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL, 144 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY); 145 EngUnlockSurface(SaveSurface); 146 } 147 148 /* 149 * Blit the cursor on the screen. 150 */ 151 152 { 153 RECTL DestRect; 154 POINTL SrcPoint; 155 SURFOBJ *ColorSurf; 156 SURFOBJ *MaskSurf; 157 158 DestRect.left = max(ppdev->PointerAttributes.Column, 0); 159 DestRect.top = max(ppdev->PointerAttributes.Row, 0); 160 DestRect.right = min( 161 ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, 162 ppdev->ScreenWidth - 1); 163 DestRect.bottom = min( 164 ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, 165 ppdev->ScreenHeight - 1); 166 167 SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); 168 SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); 169 170 MaskSurf = EngLockSurface(ppdev->PointerMaskSurface); 171 if (ppdev->PointerColorSurface != NULL) 172 { 173 ColorSurf = EngLockSurface(ppdev->PointerColorSurface); 174 EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, ppdev->PointerXlateObject, 175 &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC); 176 EngUnlockSurface(ColorSurf); 177 } 178 else 179 { 180 /* FIXME */ 181 EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, 182 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND); 183 SrcPoint.y += ppdev->PointerAttributes.Height; 184 EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, 185 &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT); 186 } 187 EngUnlockSurface(MaskSurf); 188 } 189 } 190 191 /* 192 * DrvSetPointerShape 193 * 194 * Sets the new pointer shape. 195 * 196 * Status 197 * @implemented 198 */ 199 200 ULONG APIENTRY 201 DrvSetPointerShape( 202 IN SURFOBJ *pso, 203 IN SURFOBJ *psoMask, 204 IN SURFOBJ *psoColor, 205 IN XLATEOBJ *pxlo, 206 IN LONG xHot, 207 IN LONG yHot, 208 IN LONG x, 209 IN LONG y, 210 IN RECTL *prcl, 211 IN FLONG fl) 212 { 213 PPDEV ppdev = (PPDEV)pso->dhpdev; 214 SURFOBJ *TempSurfObj; 215 216 IntHideMousePointer(ppdev, pso); 217 218 if (ppdev->PointerColorSurface != NULL) 219 { 220 /* FIXME: Is this really needed? */ 221 TempSurfObj = EngLockSurface(ppdev->PointerColorSurface); 222 EngFreeMem(TempSurfObj->pvBits); 223 TempSurfObj->pvBits = NULL; 224 EngUnlockSurface(TempSurfObj); 225 226 EngDeleteSurface(ppdev->PointerColorSurface); 227 ppdev->PointerColorSurface = NULL; 228 } 229 230 if (ppdev->PointerMaskSurface != NULL) 231 { 232 /* FIXME: Is this really needed? */ 233 TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface); 234 EngFreeMem(TempSurfObj->pvBits); 235 TempSurfObj->pvBits = NULL; 236 EngUnlockSurface(TempSurfObj); 237 238 EngDeleteSurface(ppdev->PointerMaskSurface); 239 ppdev->PointerMaskSurface = NULL; 240 } 241 242 if (ppdev->PointerSaveSurface != NULL) 243 { 244 EngDeleteSurface(ppdev->PointerSaveSurface); 245 ppdev->PointerSaveSurface = NULL; 246 } 247 248 /* 249 * See if we are being asked to hide the pointer. 250 */ 251 252 if (psoMask == NULL) 253 { 254 return SPS_ACCEPT_EXCLUDE; 255 } 256 257 ppdev->PointerHotSpot.x = xHot; 258 ppdev->PointerHotSpot.y = yHot; 259 260 ppdev->PointerXlateObject = pxlo; 261 ppdev->PointerAttributes.Column = x - xHot; 262 ppdev->PointerAttributes.Row = y - yHot; 263 ppdev->PointerAttributes.Width = psoMask->lDelta << 3; 264 ppdev->PointerAttributes.Height = (psoMask->cjBits / psoMask->lDelta) >> 1; 265 266 if (psoColor != NULL) 267 { 268 SIZEL Size; 269 PBYTE Bits; 270 271 Size.cx = ppdev->PointerAttributes.Width; 272 Size.cy = ppdev->PointerAttributes.Height; 273 Bits = EngAllocMem(0, psoColor->cjBits, ALLOC_TAG); 274 memcpy(Bits, psoColor->pvBits, psoColor->cjBits); 275 276 ppdev->PointerColorSurface = (HSURF)EngCreateBitmap(Size, 277 psoColor->lDelta, psoColor->iBitmapFormat, 0, Bits); 278 } 279 280 { 281 SIZEL Size; 282 PBYTE Bits; 283 284 Size.cx = ppdev->PointerAttributes.Width; 285 Size.cy = ppdev->PointerAttributes.Height << 1; 286 Bits = EngAllocMem(0, psoMask->cjBits, ALLOC_TAG); 287 memcpy(Bits, psoMask->pvBits, psoMask->cjBits); 288 289 ppdev->PointerMaskSurface = (HSURF)EngCreateBitmap(Size, 290 psoMask->lDelta, psoMask->iBitmapFormat, 0, Bits); 291 } 292 293 /* 294 * Create surface for saving the pixels under the cursor. 295 */ 296 297 { 298 SIZEL Size; 299 LONG lDelta; 300 301 Size.cx = ppdev->PointerAttributes.Width; 302 Size.cy = ppdev->PointerAttributes.Height; 303 304 switch (pso->iBitmapFormat) 305 { 306 case BMF_8BPP: lDelta = Size.cx; break; 307 case BMF_16BPP: lDelta = Size.cx << 1; break; 308 case BMF_24BPP: lDelta = Size.cx * 3; break; 309 case BMF_32BPP: lDelta = Size.cx << 2; break; 310 } 311 312 ppdev->PointerSaveSurface = (HSURF)EngCreateBitmap( 313 Size, lDelta, pso->iBitmapFormat, BMF_NOZEROINIT, NULL); 314 } 315 316 IntShowMousePointer(ppdev, pso); 317 318 return SPS_ACCEPT_EXCLUDE; 319 } 320 321 /* 322 * DrvMovePointer 323 * 324 * Moves the pointer to a new position and ensures that GDI does not interfere 325 * with the display of the pointer. 326 * 327 * Status 328 * @implemented 329 */ 330 331 VOID APIENTRY 332 DrvMovePointer( 333 IN SURFOBJ *pso, 334 IN LONG x, 335 IN LONG y, 336 IN RECTL *prcl) 337 { 338 PPDEV ppdev = (PPDEV)pso->dhpdev; 339 BOOL WasVisible; 340 341 WasVisible = ppdev->PointerAttributes.Enable; 342 if (WasVisible) 343 { 344 IntHideMousePointer(ppdev, pso); 345 } 346 347 if (x == -1) 348 { 349 return; 350 } 351 352 ppdev->PointerAttributes.Column = x - ppdev->PointerHotSpot.x; 353 ppdev->PointerAttributes.Row = y - ppdev->PointerHotSpot.y; 354 355 if (WasVisible) 356 { 357 IntShowMousePointer(ppdev, pso); 358 } 359 } 360 361 #endif 362