Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpointer.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Framebuffer Display Driver 00003 * LICENSE: Microsoft NT4 DDK Sample Code License 00004 * FILE: boot/drivers/video/displays/framebuf/pointer.c 00005 * PURPOSE: Hardware Pointer Support 00006 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation 00007 */ 00008 00009 #include "driver.h" 00010 00011 BOOL bCopyColorPointer( 00012 PPDEV ppdev, 00013 SURFOBJ *psoMask, 00014 SURFOBJ *psoColor, 00015 XLATEOBJ *pxlo); 00016 00017 BOOL bCopyMonoPointer( 00018 PPDEV ppdev, 00019 SURFOBJ *psoMask); 00020 00021 BOOL bSetHardwarePointerShape( 00022 SURFOBJ *pso, 00023 SURFOBJ *psoMask, 00024 SURFOBJ *psoColor, 00025 XLATEOBJ *pxlo, 00026 LONG x, 00027 LONG y, 00028 FLONG fl); 00029 00030 /******************************Public*Routine******************************\ 00031 * DrvMovePointer 00032 * 00033 * Moves the hardware pointer to a new position. 00034 * 00035 \**************************************************************************/ 00036 00037 VOID DrvMovePointer 00038 ( 00039 SURFOBJ *pso, 00040 LONG x, 00041 LONG y, 00042 RECTL *prcl 00043 ) 00044 { 00045 PPDEV ppdev = (PPDEV) pso->dhpdev; 00046 DWORD returnedDataLength; 00047 VIDEO_POINTER_POSITION NewPointerPosition; 00048 00049 // We don't use the exclusion rectangle because we only support 00050 // hardware Pointers. If we were doing our own Pointer simulations 00051 // we would want to update prcl so that the engine would call us 00052 // to exclude out pointer before drawing to the pixels in prcl. 00053 00054 UNREFERENCED_PARAMETER(prcl); 00055 00056 if (x == -1) 00057 { 00058 // 00059 // A new position of (-1,-1) means hide the pointer. 00060 // 00061 00062 if (EngDeviceIoControl(ppdev->hDriver, 00063 IOCTL_VIDEO_DISABLE_POINTER, 00064 NULL, 00065 0, 00066 NULL, 00067 0, 00068 &returnedDataLength)) 00069 { 00070 // 00071 // Not the end of the world, print warning in checked build. 00072 // 00073 00074 DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_DISABLE_POINTER\n")); 00075 } 00076 } 00077 else 00078 { 00079 NewPointerPosition.Column = (SHORT) x - (SHORT) (ppdev->ptlHotSpot.x); 00080 NewPointerPosition.Row = (SHORT) y - (SHORT) (ppdev->ptlHotSpot.y); 00081 00082 // 00083 // Call miniport driver to move Pointer. 00084 // 00085 00086 if (EngDeviceIoControl(ppdev->hDriver, 00087 IOCTL_VIDEO_SET_POINTER_POSITION, 00088 &NewPointerPosition, 00089 sizeof(VIDEO_POINTER_POSITION), 00090 NULL, 00091 0, 00092 &returnedDataLength)) 00093 { 00094 // 00095 // Not the end of the world, print warning in checked build. 00096 // 00097 00098 DISPDBG((1, "DISP vMoveHardwarePointer failed IOCTL_VIDEO_SET_POINTER_POSITION\n")); 00099 } 00100 } 00101 } 00102 00103 /******************************Public*Routine******************************\ 00104 * DrvSetPointerShape 00105 * 00106 * Sets the new pointer shape. 00107 * 00108 \**************************************************************************/ 00109 00110 ULONG DrvSetPointerShape 00111 ( 00112 SURFOBJ *pso, 00113 SURFOBJ *psoMask, 00114 SURFOBJ *psoColor, 00115 XLATEOBJ *pxlo, 00116 LONG xHot, 00117 LONG yHot, 00118 LONG x, 00119 LONG y, 00120 RECTL *prcl, 00121 FLONG fl 00122 ) 00123 { 00124 PPDEV ppdev = (PPDEV) pso->dhpdev; 00125 DWORD returnedDataLength; 00126 00127 // We don't use the exclusion rectangle because we only support 00128 // hardware Pointers. If we were doing our own Pointer simulations 00129 // we would want to update prcl so that the engine would call us 00130 // to exclude out pointer before drawing to the pixels in prcl. 00131 UNREFERENCED_PARAMETER(prcl); 00132 00133 if (ppdev->pPointerAttributes == (PVIDEO_POINTER_ATTRIBUTES) NULL) 00134 { 00135 // Mini-port has no hardware Pointer support. 00136 return(SPS_ERROR); 00137 } 00138 00139 // See if we are being asked to hide the pointer 00140 00141 if (psoMask == (SURFOBJ *) NULL) 00142 { 00143 if (EngDeviceIoControl(ppdev->hDriver, 00144 IOCTL_VIDEO_DISABLE_POINTER, 00145 NULL, 00146 0, 00147 NULL, 00148 0, 00149 &returnedDataLength)) 00150 { 00151 // 00152 // It should never be possible to fail. 00153 // Message supplied for debugging. 00154 // 00155 00156 DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n")); 00157 } 00158 00159 return(TRUE); 00160 } 00161 00162 ppdev->ptlHotSpot.x = xHot; 00163 ppdev->ptlHotSpot.y = yHot; 00164 00165 if (!bSetHardwarePointerShape(pso,psoMask,psoColor,pxlo,x,y,fl)) 00166 { 00167 if (ppdev->fHwCursorActive) { 00168 ppdev->fHwCursorActive = FALSE; 00169 00170 if (EngDeviceIoControl(ppdev->hDriver, 00171 IOCTL_VIDEO_DISABLE_POINTER, 00172 NULL, 00173 0, 00174 NULL, 00175 0, 00176 &returnedDataLength)) { 00177 00178 DISPDBG((1, "DISP bSetHardwarePointerShape failed IOCTL_VIDEO_DISABLE_POINTER\n")); 00179 } 00180 } 00181 00182 // 00183 // Mini-port declines to realize this Pointer 00184 // 00185 00186 return(SPS_DECLINE); 00187 } 00188 else 00189 { 00190 ppdev->fHwCursorActive = TRUE; 00191 } 00192 00193 return(SPS_ACCEPT_NOEXCLUDE); 00194 } 00195 00196 /******************************Public*Routine******************************\ 00197 * bSetHardwarePointerShape 00198 * 00199 * Changes the shape of the Hardware Pointer. 00200 * 00201 * Returns: True if successful, False if Pointer shape can't be hardware. 00202 * 00203 \**************************************************************************/ 00204 00205 BOOL bSetHardwarePointerShape( 00206 SURFOBJ *pso, 00207 SURFOBJ *psoMask, 00208 SURFOBJ *psoColor, 00209 XLATEOBJ *pxlo, 00210 LONG x, 00211 LONG y, 00212 FLONG fl) 00213 { 00214 PPDEV ppdev = (PPDEV) pso->dhpdev; 00215 PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; 00216 DWORD returnedDataLength; 00217 00218 if (psoColor != (SURFOBJ *) NULL) 00219 { 00220 if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER) && 00221 bCopyColorPointer(ppdev, psoMask, psoColor, pxlo)) 00222 { 00223 pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER; 00224 } else { 00225 return(FALSE); 00226 } 00227 00228 } else { 00229 00230 if ((ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER) && 00231 bCopyMonoPointer(ppdev, psoMask)) 00232 { 00233 pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER; 00234 } else { 00235 return(FALSE); 00236 } 00237 } 00238 00239 // 00240 // Initialize Pointer attributes and position 00241 // 00242 00243 pPointerAttributes->Enable = 1; 00244 00245 // 00246 // if x,y = -1,-1 then pass them directly to the miniport so that 00247 // the cursor will be disabled 00248 00249 pPointerAttributes->Column = (SHORT)(x); 00250 pPointerAttributes->Row = (SHORT)(y); 00251 00252 if ((x != -1) || (y != -1)) { 00253 pPointerAttributes->Column -= (SHORT)(ppdev->ptlHotSpot.x); 00254 pPointerAttributes->Row -= (SHORT)(ppdev->ptlHotSpot.y); 00255 } 00256 00257 // 00258 // set animate flags 00259 // 00260 00261 if (fl & SPS_ANIMATESTART) { 00262 pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_START; 00263 } else if (fl & SPS_ANIMATEUPDATE) { 00264 pPointerAttributes->Flags |= VIDEO_MODE_ANIMATE_UPDATE; 00265 } 00266 00267 // 00268 // Set the new Pointer shape. 00269 // 00270 00271 if (EngDeviceIoControl(ppdev->hDriver, 00272 IOCTL_VIDEO_SET_POINTER_ATTR, 00273 pPointerAttributes, 00274 ppdev->cjPointerAttributes, 00275 NULL, 00276 0, 00277 &returnedDataLength)) { 00278 00279 DISPDBG((1, "DISP:Failed IOCTL_VIDEO_SET_POINTER_ATTR call\n")); 00280 return(FALSE); 00281 } 00282 00283 return(TRUE); 00284 } 00285 00286 /******************************Public*Routine******************************\ 00287 * bCopyMonoPointer 00288 * 00289 * Copies two monochrome masks into a buffer of the maximum size handled by the 00290 * miniport, with any extra bits set to 0. The masks are converted to topdown 00291 * form if they aren't already. Returns TRUE if we can handle this pointer in 00292 * hardware, FALSE if not. 00293 * 00294 \**************************************************************************/ 00295 00296 BOOL bCopyMonoPointer( 00297 PPDEV ppdev, 00298 SURFOBJ *pso) 00299 { 00300 ULONG cy; 00301 PBYTE pjSrcAnd, pjSrcXor; 00302 LONG lDeltaSrc, lDeltaDst; 00303 LONG lSrcWidthInBytes; 00304 ULONG cxSrc = pso->sizlBitmap.cx; 00305 ULONG cySrc = pso->sizlBitmap.cy; 00306 ULONG cxSrcBytes; 00307 PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; 00308 PBYTE pjDstAnd = pPointerAttributes->Pixels; 00309 PBYTE pjDstXor = pPointerAttributes->Pixels; 00310 00311 // Make sure the new pointer isn't too big to handle 00312 // (*2 because both masks are in there) 00313 if ((cxSrc > ppdev->PointerCapabilities.MaxWidth) || 00314 (cySrc > (ppdev->PointerCapabilities.MaxHeight * 2))) 00315 { 00316 return(FALSE); 00317 } 00318 00319 pjDstXor += ((ppdev->PointerCapabilities.MaxWidth + 7) / 8) * 00320 ppdev->pPointerAttributes->Height; 00321 00322 // set the desk and mask to 0xff 00323 RtlFillMemory(pjDstAnd, ppdev->pPointerAttributes->WidthInBytes * 00324 ppdev->pPointerAttributes->Height, 0xFF); 00325 00326 // Zero the dest XOR mask 00327 RtlZeroMemory(pjDstXor, ppdev->pPointerAttributes->WidthInBytes * 00328 ppdev->pPointerAttributes->Height); 00329 00330 cxSrcBytes = (cxSrc + 7) / 8; 00331 00332 if ((lDeltaSrc = pso->lDelta) < 0) 00333 { 00334 lSrcWidthInBytes = -lDeltaSrc; 00335 } else { 00336 lSrcWidthInBytes = lDeltaSrc; 00337 } 00338 00339 pjSrcAnd = (PBYTE) pso->pvBits; 00340 00341 // If the incoming pointer bitmap is bottomup, we'll flip it to topdown to 00342 // save the miniport some work 00343 if (!(pso->fjBitmap & BMF_TOPDOWN)) 00344 { 00345 // Copy from the bottom 00346 pjSrcAnd += lSrcWidthInBytes * (cySrc - 1); 00347 } 00348 00349 // Height of just AND mask 00350 cySrc = cySrc / 2; 00351 00352 // Point to XOR mask 00353 pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc); 00354 00355 // Offset from end of one dest scan to start of next 00356 lDeltaDst = ppdev->pPointerAttributes->WidthInBytes; 00357 00358 for (cy = 0; cy < cySrc; ++cy) 00359 { 00360 RtlCopyMemory(pjDstAnd, pjSrcAnd, cxSrcBytes); 00361 RtlCopyMemory(pjDstXor, pjSrcXor, cxSrcBytes); 00362 00363 // Point to next source and dest scans 00364 pjSrcAnd += lDeltaSrc; 00365 pjSrcXor += lDeltaSrc; 00366 pjDstAnd += lDeltaDst; 00367 pjDstXor += lDeltaDst; 00368 } 00369 00370 return(TRUE); 00371 } 00372 00373 /******************************Public*Routine******************************\ 00374 * bCopyColorPointer 00375 * 00376 * Copies the mono and color masks into the buffer of maximum size 00377 * handled by the miniport with any extra bits set to 0. Color translation 00378 * is handled at this time. The masks are converted to topdown form if they 00379 * aren't already. Returns TRUE if we can handle this pointer in hardware, 00380 * FALSE if not. 00381 * 00382 \**************************************************************************/ 00383 BOOL bCopyColorPointer( 00384 PPDEV ppdev, 00385 SURFOBJ *psoMask, 00386 SURFOBJ *psoColor, 00387 XLATEOBJ *pxlo) 00388 { 00389 return(FALSE); 00390 } 00391 00392 00393 /******************************Public*Routine******************************\ 00394 * bInitPointer 00395 * 00396 * Initialize the Pointer attributes. 00397 * 00398 \**************************************************************************/ 00399 00400 BOOL bInitPointer(PPDEV ppdev, DEVINFO *pdevinfo) 00401 { 00402 DWORD returnedDataLength; 00403 00404 ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL; 00405 ppdev->cjPointerAttributes = 0; // initialized in screen.c 00406 00407 // 00408 // Ask the miniport whether it provides pointer support. 00409 // 00410 00411 if (EngDeviceIoControl(ppdev->hDriver, 00412 IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES, 00413 NULL, 00414 0, 00415 &ppdev->PointerCapabilities, 00416 sizeof(ppdev->PointerCapabilities), 00417 &returnedDataLength)) 00418 { 00419 return(FALSE); 00420 } 00421 00422 // 00423 // If neither mono nor color hardware pointer is supported, there's no 00424 // hardware pointer support and we're done. 00425 // 00426 00427 if ((!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_MONO_POINTER)) && 00428 (!(ppdev->PointerCapabilities.Flags & VIDEO_MODE_COLOR_POINTER))) 00429 { 00430 return(TRUE); 00431 } 00432 00433 // 00434 // Note: The buffer itself is allocated after we set the 00435 // mode. At that time we know the pixel depth and we can 00436 // allocate the correct size for the color pointer if supported. 00437 // 00438 00439 // 00440 // Set the asynchronous support status (async means miniport is capable of 00441 // drawing the Pointer at any time, with no interference with any ongoing 00442 // drawing operation) 00443 // 00444 00445 if (ppdev->PointerCapabilities.Flags & VIDEO_MODE_ASYNC_POINTER) 00446 { 00447 pdevinfo->flGraphicsCaps |= GCAPS_ASYNCMOVE; 00448 } 00449 else 00450 { 00451 pdevinfo->flGraphicsCaps &= ~GCAPS_ASYNCMOVE; 00452 } 00453 00454 return(TRUE); 00455 } Generated on Fri May 25 2012 04:36:17 for ReactOS by
1.7.6.1
|