ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pointer.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.