Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpointer.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS VGA display driver 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: drivers/video/displays/vga/objects/pointer.c 00005 * PURPOSE: Draws the mouse pointer 00006 * PROGRAMMERS: Copyright (C) 1998-2001 ReactOS Team 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <vgaddi.h> 00012 00013 /* GLOBALS *******************************************************************/ 00014 00015 static VOID VGADDI_HideCursor(PPDEV ppdev); 00016 static VOID VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl); 00017 00018 /* FUNCTIONS *****************************************************************/ 00019 00020 VOID 00021 VGADDI_BltPointerToVGA( 00022 IN LONG StartX, 00023 IN LONG StartY, 00024 IN ULONG SizeX, 00025 IN ULONG SizeY, 00026 IN PUCHAR MaskBits, 00027 IN ULONG MaskPitch, 00028 IN ULONG MaskOp) 00029 { 00030 ULONG DestX, EndX, DestY, EndY; 00031 UCHAR Mask; 00032 PUCHAR Video; 00033 PUCHAR Src; 00034 UCHAR SrcValue; 00035 ULONG i, j; 00036 ULONG Left; 00037 ULONG Length; 00038 LONG Bits; 00039 00040 DestX = StartX < 0 ? 0 : StartX; 00041 DestY = StartY < 0 ? 0 : StartY; 00042 EndX = StartX + SizeX; 00043 EndY = StartY + SizeY; 00044 00045 /* Set write mode zero. */ 00046 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 00047 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0); 00048 00049 /* Select raster op. */ 00050 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3); 00051 WRITE_PORT_UCHAR((PUCHAR)GRA_D, MaskOp); 00052 00053 if ((DestX % 8) != 0) 00054 { 00055 /* Disable writes to pixels outside of the destination rectangle. */ 00056 Mask = (1 << (8 - (DestX % 8))) - 1; 00057 if ((EndX - DestX) < (8 - (DestX % 8))) 00058 { 00059 Mask &= ~((1 << (8 - (EndX % 8))) - 1); 00060 } 00061 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); 00062 WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); 00063 00064 /* Write the mask. */ 00065 Video = (PUCHAR)vidmem + DestY * 80 + (DestX >> 3); 00066 Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch; 00067 for (i = DestY; i < EndY; i++, Video += 80) 00068 { 00069 Src -= MaskPitch; 00070 SrcValue = (*Src) >> (DestX % 8); 00071 (VOID)READ_REGISTER_UCHAR(Video); 00072 WRITE_REGISTER_UCHAR(Video, SrcValue); 00073 } 00074 } 00075 00076 /* Enable writes to all pixels. */ 00077 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); 00078 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); 00079 00080 /* Have we finished. */ 00081 if ((EndX - DestX) < (8 - (DestX % 8))) 00082 return; 00083 00084 /* Fill any whole rows of eight pixels. */ 00085 Left = (DestX + 7) & ~0x7; 00086 Length = (EndX >> 3) - (Left >> 3); 00087 Bits = StartX; 00088 while (Bits < 0) 00089 Bits += 8; 00090 Bits = Bits % 8; 00091 for (i = DestY; i < EndY; i++) 00092 { 00093 Video = (PUCHAR)vidmem + i * 80 + (Left >> 3); 00094 Src = MaskBits + (EndY - i - 1) * MaskPitch + ((DestX - StartX) >> 3); 00095 for (j = 0; j < Length; j++, Video++, Src++) 00096 { 00097 if (Bits != 0) 00098 { 00099 SrcValue = (Src[0] << (8 - Bits)); 00100 SrcValue |= (Src[1] >> Bits); 00101 } 00102 else 00103 { 00104 SrcValue = Src[0]; 00105 } 00106 (VOID)READ_REGISTER_UCHAR(Video); 00107 WRITE_REGISTER_UCHAR(Video, SrcValue); 00108 } 00109 } 00110 00111 /* Fill any pixels on the right which don't fall into a complete row. */ 00112 if ((EndX % 8) != 0) 00113 { 00114 /* Disable writes to pixels outside the destination rectangle. */ 00115 Mask = ~((1 << (8 - (EndX % 8))) - 1); 00116 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); 00117 WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); 00118 00119 Video = (PUCHAR)vidmem + DestY * 80 + (EndX >> 3); 00120 Src = MaskBits + (SizeY - (DestY - StartY)) * MaskPitch + (SizeX >> 3) - 1; 00121 for (i = DestY; i < EndY; i++, Video += 80) 00122 { 00123 Src -= MaskPitch; 00124 SrcValue = (Src[0] << (8 - Bits)); 00125 (VOID)READ_REGISTER_UCHAR(Video); 00126 WRITE_REGISTER_UCHAR(Video, SrcValue); 00127 } 00128 00129 /* Restore the default write masks. */ 00130 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); 00131 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); 00132 } 00133 00134 /* Set write mode two. */ 00135 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); 00136 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); 00137 00138 /* Select raster op replace. */ 00139 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3); 00140 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0); 00141 } 00142 00143 BOOL InitPointer(PPDEV ppdev) 00144 { 00145 ULONG CursorWidth = 32, CursorHeight = 32; 00146 ULONG PointerAttributesSize; 00147 ULONG SavedMemSize; 00148 00149 ppdev->xyHotSpot.x = 0; 00150 ppdev->xyHotSpot.y = 0; 00151 00152 /* Determine the size of the pointer attributes */ 00153 PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) + 00154 ((CursorWidth * CursorHeight * 2) >> 3); 00155 00156 /* Allocate memory for pointer attributes */ 00157 ppdev->pPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG); 00158 00159 ppdev->pPointerAttributes->Flags = 0; /* FIXME: Do this right */ 00160 ppdev->pPointerAttributes->Width = CursorWidth; 00161 ppdev->pPointerAttributes->Height = CursorHeight; 00162 ppdev->pPointerAttributes->WidthInBytes = CursorWidth >> 3; 00163 ppdev->pPointerAttributes->Enable = 0; 00164 ppdev->pPointerAttributes->Column = 0; 00165 ppdev->pPointerAttributes->Row = 0; 00166 00167 /* Allocate memory for the pixels behind the cursor */ 00168 SavedMemSize = ((((CursorWidth + 7) & ~0x7) + 16) * CursorHeight) >> 3; 00169 ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); 00170 00171 return TRUE; 00172 } 00173 00174 VOID APIENTRY 00175 DrvMovePointer( 00176 IN SURFOBJ* pso, 00177 IN LONG x, 00178 IN LONG y, 00179 IN PRECTL prcl) 00180 { 00181 PPDEV ppdev = (PPDEV)pso->dhpdev; 00182 00183 VGADDI_HideCursor(ppdev); 00184 00185 if(x != -1) 00186 { 00187 ppdev->pPointerAttributes->Column = x; 00188 ppdev->pPointerAttributes->Row = y; 00189 00190 VGADDI_ShowCursor(ppdev, prcl); 00191 } 00192 } 00193 00194 00195 ULONG APIENTRY 00196 DrvSetPointerShape( 00197 IN SURFOBJ* pso, 00198 IN SURFOBJ* psoMask, 00199 IN SURFOBJ* psoColor, 00200 IN XLATEOBJ* pxlo, 00201 IN LONG xHot, 00202 IN LONG yHot, 00203 IN LONG x, 00204 IN LONG y, 00205 IN PRECTL prcl, 00206 IN ULONG fl) 00207 { 00208 PPDEV ppdev = (PPDEV)pso->dhpdev; 00209 ULONG NewWidth, NewHeight; 00210 PUCHAR Src, Dest; 00211 ULONG i; 00212 00213 if (!psoMask) 00214 return SPS_DECLINE; 00215 00216 /* Hide the cursor */ 00217 VGADDI_HideCursor(ppdev); 00218 00219 NewWidth = abs(psoMask->lDelta) << 3; 00220 NewHeight = (psoMask->cjBits / abs(psoMask->lDelta)) / 2; 00221 00222 /* Reallocate the space for the cursor if necessary. */ 00223 if (ppdev->pPointerAttributes->Width != NewWidth || 00224 ppdev->pPointerAttributes->Height != NewHeight) 00225 { 00226 ULONG PointerAttributesSize; 00227 PVIDEO_POINTER_ATTRIBUTES NewPointerAttributes; 00228 ULONG SavedMemSize; 00229 00230 /* Determine the size of the pointer attributes */ 00231 PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) + 00232 ((NewWidth * NewHeight * 2) >> 3); 00233 00234 /* Allocate memory for pointer attributes */ 00235 NewPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG); 00236 *NewPointerAttributes = *ppdev->pPointerAttributes; 00237 NewPointerAttributes->Width = NewWidth; 00238 NewPointerAttributes->Height = NewHeight; 00239 NewPointerAttributes->WidthInBytes = NewWidth >> 3; 00240 EngFreeMem(ppdev->pPointerAttributes); 00241 ppdev->pPointerAttributes = NewPointerAttributes; 00242 00243 /* Reallocate the space for the saved bits. */ 00244 VGADDI_FreeSavedScreenBits(ppdev->ImageBehindCursor); 00245 SavedMemSize = ((((NewWidth + 7) & ~0x7) + 16) * NewHeight) >> 3; 00246 ppdev->ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); 00247 } 00248 00249 Src = (PUCHAR)psoMask->pvScan0; 00250 /* Copy the new cursor in. */ 00251 for (i = 0; i < (NewHeight * 2); i++) 00252 { 00253 Dest = (PUCHAR)ppdev->pPointerAttributes->Pixels; 00254 if (i >= NewHeight) 00255 Dest += (((NewHeight * 3) - i - 1) * (NewWidth >> 3)); 00256 else 00257 Dest += ((NewHeight - i - 1) * (NewWidth >> 3)); 00258 memcpy(Dest, Src, NewWidth >> 3); 00259 Src += psoMask->lDelta; 00260 } 00261 00262 /* Set the new cursor position */ 00263 ppdev->xyHotSpot.x = xHot; 00264 ppdev->xyHotSpot.y = yHot; 00265 00266 if(x != -1) 00267 { 00268 ppdev->pPointerAttributes->Column = x; 00269 ppdev->pPointerAttributes->Row = y; 00270 00271 /* show the cursor */ 00272 VGADDI_ShowCursor(ppdev, prcl); 00273 } 00274 00275 return SPS_ACCEPT_NOEXCLUDE; 00276 } 00277 00278 static VOID FASTCALL 00279 VGADDI_ComputePointerRect( 00280 IN PPDEV ppdev, 00281 IN LONG X, 00282 IN LONG Y, 00283 IN PRECTL Rect) 00284 { 00285 ULONG SizeX, SizeY; 00286 00287 SizeX = min(((X + (LONG)ppdev->pPointerAttributes->Width) + 7) & ~0x7, ppdev->sizeSurf.cx); 00288 SizeX -= (X & ~0x7); 00289 SizeY = min((LONG)ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - Y); 00290 00291 Rect->left = max(X, 0) & ~0x7; 00292 Rect->top = max(Y, 0); 00293 Rect->right = Rect->left + SizeX; 00294 Rect->bottom = Rect->top + SizeY; 00295 } 00296 00297 static VOID 00298 VGADDI_HideCursor(PPDEV ppdev) 00299 { 00300 if(ppdev->pPointerAttributes->Enable) 00301 { 00302 LONG cx, cy; 00303 RECTL Rect; 00304 00305 ppdev->pPointerAttributes->Enable = 0; 00306 00307 cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x; 00308 cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y; 00309 00310 VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect); 00311 00312 /* Display what was behind cursor */ 00313 VGADDI_BltFromSavedScreenBits(Rect.left, 00314 Rect.top, 00315 ppdev->ImageBehindCursor, 00316 Rect.right - Rect.left, 00317 Rect.bottom - Rect.top); 00318 } 00319 } 00320 00321 static VOID 00322 VGADDI_ShowCursor(PPDEV ppdev, PRECTL prcl) 00323 { 00324 LONG cx, cy; 00325 PUCHAR AndMask, XorMask; 00326 ULONG SizeX, SizeY; 00327 RECTL Rect; 00328 00329 if(ppdev->pPointerAttributes->Enable) 00330 return; 00331 00332 /* Mark the cursor as currently displayed. */ 00333 ppdev->pPointerAttributes->Enable = 1; 00334 00335 cx = ppdev->pPointerAttributes->Column - ppdev->xyHotSpot.x; 00336 cy = ppdev->pPointerAttributes->Row - ppdev->xyHotSpot.y; 00337 00338 /* Capture pixels behind the cursor */ 00339 VGADDI_ComputePointerRect(ppdev, cx, cy, &Rect); 00340 00341 VGADDI_BltToSavedScreenBits(ppdev->ImageBehindCursor, 00342 Rect.left, 00343 Rect.top, 00344 Rect.right - Rect.left, 00345 Rect.bottom - Rect.top); 00346 00347 /* Display the cursor. */ 00348 SizeX = min((LONG)ppdev->pPointerAttributes->Width, ppdev->sizeSurf.cx - cx); 00349 SizeY = min((LONG)ppdev->pPointerAttributes->Height, ppdev->sizeSurf.cy - cy); 00350 AndMask = ppdev->pPointerAttributes->Pixels + 00351 (ppdev->pPointerAttributes->Height - SizeY) * ppdev->pPointerAttributes->WidthInBytes; 00352 VGADDI_BltPointerToVGA(cx, 00353 cy, 00354 SizeX, 00355 SizeY, 00356 AndMask, 00357 ppdev->pPointerAttributes->WidthInBytes, 00358 VGA_AND); 00359 XorMask = AndMask + 00360 ppdev->pPointerAttributes->WidthInBytes * 00361 ppdev->pPointerAttributes->Height; 00362 VGADDI_BltPointerToVGA(cx, 00363 cy, 00364 SizeX, 00365 SizeY, 00366 XorMask, 00367 ppdev->pPointerAttributes->WidthInBytes, 00368 VGA_XOR); 00369 00370 if (NULL != prcl) 00371 *prcl = Rect; 00372 } Generated on Sun May 27 2012 04:38:07 for ReactOS by
1.7.6.1
|