⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swcursor.cpp

📁 AU1100嵌入式处理器lcd显示驱动程序
💻 CPP
字号:
/*++
Copyright:
  
    Copyright (c) 1998,2002-2003 BSQUARE Corporation. All rights reserved.
  
Module Name:  

    swcursor.h

Abstract:  

    This module is the implemenation of the software cursor.

Author:

    Edward Sumanaseni, 5-Nov-1998

Revisions:

--*/

#include "headers.h"
#include "gpe.h"
#include "swcursor.h"

SOFT_CURSOR::SOFT_CURSOR(
    IN GPE *pGpe
    )

/*++

Routine Description:

    SOFT_CURSOR class contructor.

Arguments:

    pGpe - Pointer to a GPE object.

Returns:

    None.

--*/

{
    //
    // Initialize data members.
    //
    m_pGpe = pGpe;
    m_pANDSurf = NULL;
    m_pXORSurf = NULL;
    m_pBackBuf = NULL;
    m_bCursorVisible = FALSE;
	m_bCursorHidden = FALSE;
    m_nCx = 0;
    m_nCy = 0;
    m_rclScreen.left = 0;
    m_rclScreen.top = 0;
    m_rclScreen.right = 0;
    m_rclScreen.bottom = 0;

    m_bFailedCreateSurfaces = TRUE;

    m_eFormat = pGpe->PrimarySurface()->Format();
    m_nBytesPerPixel = EGPEFormatToBpp[m_eFormat] / 8;
}


SOFT_CURSOR::~SOFT_CURSOR(
    VOID
    )

/*++

Routine Description:

    SOFT_CURSOR class destructor.

Arguments:

    None.

Returns:

    None.

--*/
{
    //
    // Delete surfaces.
    //

    DeleteSurfaces();
}


VOID
SOFT_CURSOR::DeleteSurfaces(
    VOID
    )

/*++

Routine Description:

    This routine deletes surfaces used by the software cursor.

Arguments:

    None.

Return Value:

    None.

--*/

{

    if (m_pBackBuf != NULL) {
        delete m_pBackBuf;
    }

    if (m_pANDSurf != NULL) {
        delete m_pANDSurf;
    }

    if (m_pXORSurf != NULL) {  
        delete m_pXORSurf;
    }
}


BOOL
SOFT_CURSOR::CreateSurfaces(
    VOID
    )

/*++

Routine Description:

    This routine creates surfaces that are used by the software cursor.

Arguments:

    None.

Return Value:

    TURE if surfaces created, FALSE otherwise.

--*/

{
    SCODE sc;
    int SurfaceFlags = 0;

    //
    // Allocate cursor back buffer.
    //

    sc = m_pGpe->AllocSurface(
                    &m_pBackBuf,
                    SOFT_CURSOR_WIDTH_PIXELS,
                    SOFT_CURSOR_HEIGHT_PIXELS,
                    m_eFormat,
                    SurfaceFlags
                    );
    
    if (FAILED(sc)) {
        goto ErrorExit;
    }

    //
    // Allocate AND mask surface.
    //

    sc = m_pGpe->AllocSurface(
                    &m_pANDSurf,
                    SOFT_CURSOR_WIDTH_PIXELS,
                    SOFT_CURSOR_HEIGHT_PIXELS,
                    m_eFormat,
                    SurfaceFlags
                    );

    if (FAILED(sc)) {
        goto ErrorExit;
    }

    //
    // Allocate XOR mask surface.
    //

    sc = m_pGpe->AllocSurface(
                    &m_pXORSurf,
                    SOFT_CURSOR_WIDTH_PIXELS,
                    SOFT_CURSOR_HEIGHT_PIXELS,
                    m_eFormat,
                    SurfaceFlags
                    );

    if (FAILED(sc)) {
        goto ErrorExit;
    }

    //
    // Surfaces successfully created.
    //

    m_bFailedCreateSurfaces = FALSE;

    return TRUE;

ErrorExit:

    m_bFailedCreateSurfaces = TRUE;
    DeleteSurfaces();
    return FALSE;
}


SCODE
SOFT_CURSOR::SetSWCursorShape(
    IN GPESurf *pMask,
    IN int      cx,
    IN int      cy
    )

/*++

Routine Description:

    Sets the software cursor masks.

Arguments:

    pMask - The surface of the AND and XOR masks.
    cx - Cursor width in pixels.
    cy - Cursor height in pixels.

Returns:

    SCODE.

--*/

{
    //
    // Check parameters.
    //

    //
    // Check sufaces.
    //

    if (m_bFailedCreateSurfaces) {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    // hide the old cursor before we starting
    // messing with the new one
    HideSWCursor();

	// Check the condition for just doing a CursorShow(FALSE)
    if (pMask == NULL && cx == 0 && cy == 0) {
		// leave the cursor hidden and get out
		m_bCursorHidden = TRUE;
        return S_OK;
    } 

	// check for bad parameters
    if (pMask == NULL || cx <= 0 || cy <= 0) {
        return ERROR_INVALID_PARAMETER;
    }

	m_bCursorHidden = FALSE;
    
	//
    // Set cursor size.
    //

    m_nCx = cx;
    m_nCy = cy;

    m_rclCursor.left   = 0;
    m_rclCursor.right  = m_nCx;
    m_rclCursor.top    = 0;
    m_rclCursor.bottom = m_nCy;

    int row, col;
    int i;
    int bitMask;
    int maskStride = pMask->Stride();
    int andStride  = m_pANDSurf->Stride();
    int xorStride  = m_pXORSurf->Stride();


    PUCHAR  pucANDMask;
    PUCHAR  pucXORMask;
    PUCHAR  pANDDst8;
    PUCHAR  pXORDst8;
    PUSHORT pANDDst16;
    PUSHORT pXORDst16;


    //m_pGpe->WaitForVBlank();

    //
    // Init AND and XOR surfaces.
    //

    for (row = 0; row < cy; row++) {

        pucANDMask = (PUCHAR) pMask->Buffer() + (row * maskStride);
        pucXORMask = (PUCHAR) pMask->Buffer() + ((row + cy) * maskStride);

        pANDDst8 = (PUCHAR) m_pANDSurf->Buffer() + (row * andStride);
        pXORDst8 = (PUCHAR) m_pXORSurf->Buffer() + (row * xorStride);

        pANDDst16 = (PUSHORT) pANDDst8;
        pXORDst16 = (PUSHORT) pXORDst8;

        for (col = 0; col < cx / 8; col++) {

            for (i = 0, bitMask = 0x80; i < 8; i++, bitMask >>= 1) {

                if (m_eFormat == gpe8Bpp) {
                    *pANDDst8++ = (*pucANDMask & bitMask) ? 0xFF : 0x00;
                    *pXORDst8++ = (*pucXORMask & bitMask) ? 0xFF : 0x00;
                }
                else {
                    *pANDDst16++ = (*pucANDMask & bitMask) ? 0xFFFF : 0x0000;
                    *pXORDst16++ = (*pucXORMask & bitMask) ? 0xFFFF : 0x0000;
                }
            }

            pucANDMask++;
            pucXORMask++;
        }
    }

    return S_OK;
}


VOID
SOFT_CURSOR::SurfaceCopy(
    IN GPESurf *pSurfDst,
    IN RECTL   *prclDst,
    IN GPESurf *pSurfSrc,
    IN RECTL   *prclSrc
    )

/*++

Routine Description:

    Source copy for surfaces having the same color depth.  
    Hardware acceleration is used if both surfaces are in video 
    memory.
    
Arguments:

    pSurfDst - Destination surface.
    prclDst - Destination surface bounding box.
    pSurfSrc - Source surface.
    prclSrc - Source surface bounding box.

Returns:

    None.

--*/

{

    //
    // If one of the surfaces isn't in video memory,
    // then we have to do the BLT without acceleration.
    //

    int dstStride = pSurfDst->Stride();
    int srcStride = pSurfSrc->Stride();
    int width  = prclDst->right - prclDst->left;
    int height = prclDst->bottom - prclDst->top;

    PUCHAR pDstRow = (PUCHAR) (pSurfDst->Buffer()) + 
                    (prclDst->top * dstStride) + 
                    (m_nBytesPerPixel * prclDst->left);

    PUCHAR pSrcRow = (PUCHAR) (pSurfSrc->Buffer()) +
                    (prclSrc->top * srcStride) +
                    (m_nBytesPerPixel * prclSrc->left);


    //m_pGpe->WaitForNotBusy();

    for (int i = height; i > 0; i--) {
        
        memcpy(pDstRow, pSrcRow, width * m_nBytesPerPixel);

        pDstRow += dstStride;
        pSrcRow += srcStride;
    }
}


SCODE
SOFT_CURSOR::HideSWCursor(
    VOID
    )

/*++

Routine Description:

    Hides the software cursor.

Arguments:

    None.

Returns:

    SCODE.

--*/

{

    if (m_bCursorVisible) {

        SurfaceCopy(
            m_pGpe->PrimarySurface(),
            &m_rclScreen,
            m_pBackBuf,
            &m_rclCursor
            );
     
        m_bCursorVisible = FALSE;
    }

    return S_OK;
}


SCODE
SOFT_CURSOR::ShowSWCursor(
    VOID
    )

/*++

Routine Description:

    Shows the software cursor.

Arguments:

    None.

Returns:

    SCODE.

--*/

{
    if (!m_bCursorHidden && !m_bCursorVisible) {

        //
        // Get the destination surface.
        //

        GPESurf *pSurfDst = m_pGpe->PrimarySurface();


        //
        // Save back buffer.
        //

		SurfaceCopy(
            m_pBackBuf,
            &m_rclCursor,
            pSurfDst,
            &m_rclScreen
            );

        //
        // Draw masks.
        //

        int row, col;

        int dstStride = pSurfDst->Stride();
        int srcANDStride = m_pANDSurf->Stride();
        int srcXORStride = m_pXORSurf->Stride();
        int width  = m_rclScreen.right - m_rclScreen.left;
        int height = m_rclScreen.bottom - m_rclScreen.top;

        PUCHAR pDstRow = (PUCHAR) (pSurfDst->Buffer()) + 
                            (m_rclScreen.top * dstStride) + 
                            (m_nBytesPerPixel * m_rclScreen.left);

        PUCHAR pSrcANDRow = (PUCHAR) (m_pANDSurf->Buffer()) +
                            (m_rclCursor.top * srcANDStride) +
                            (m_nBytesPerPixel * m_rclCursor.left);

        PUCHAR pSrcXORRow = (PUCHAR) (m_pXORSurf->Buffer()) +
                            (m_rclCursor.top * srcXORStride) +
                            (m_nBytesPerPixel * m_rclCursor.left);

        PUCHAR  pDst8, pSrcAND8, pSrcXOR8;
        PUSHORT pDst16, pSrcAND16, pSrcXOR16;

        //m_pGpe->WaitForNotBusy();


        if (m_eFormat == gpe8Bpp) {

            //
            // 8 Bpp format.
            //

            for (row = height; row > 0; row--) {
    
                pDst8    = pDstRow;
                pSrcAND8 = pSrcANDRow;
                pSrcXOR8 = pSrcXORRow;

                for (col = width; col > 0; col--) {
                    *pDst8   &= *pSrcAND8++;
                    *pDst8++ ^= *pSrcXOR8++;
                }

                pDstRow    += dstStride;
                pSrcANDRow += srcANDStride;
                pSrcXORRow += srcXORStride;
            }
        }
        else {

            //
            // 16 Bpp format.
            //

            for (row = height; row > 0; row--) {
    
                pDst16    = (PUSHORT) pDstRow;
                pSrcAND16 = (PUSHORT) pSrcANDRow;
                pSrcXOR16 = (PUSHORT) pSrcXORRow;

                for (col = width; col > 0; col--) {
                    *pDst16   &= *pSrcAND16++;
                    *pDst16++ ^= *pSrcXOR16++;
                }

                pDstRow    += dstStride;
                pSrcANDRow += srcANDStride;
                pSrcXORRow += srcXORStride;
            }
        }

        m_bCursorVisible = TRUE;
    }

    return S_OK;
}


SCODE
SOFT_CURSOR::MoveSWCursor(
    IN int x,
    IN int y,
    IN int xOffset,
    IN int yOffset
    )

/*++

Routine Description:

    This routine moves the software cursor to a new position.

Arugments:

    x - New cursor screen X coordinate.
    y - New cursor screen Y coordinate.
    xOffset - X offset in cursor bitmap.
    yOffset - Y offset in cursor bitmap.

Returns:

    SCODE.

--*/

{

    //m_pGpe->WaitForVBlank();

    //
    // Hide the old cursor.
    //

    HideSWCursor();


    //
    // Set new cursor and screen bounding rectangles.
    //

    m_rclCursor.left   = 0;
    m_rclCursor.right  = m_nCx;
    m_rclCursor.top    = 0;
    m_rclCursor.bottom = m_nCy;

    m_rclScreen.left   = x - xOffset;
    m_rclScreen.right  = m_rclScreen.left + m_nCx;
    m_rclScreen.top    = y - yOffset;
    m_rclScreen.bottom = m_rclScreen.top  + m_nCy;

    int screenWidth  = m_pGpe->ScreenWidth();
    int screenHeight = m_pGpe->ScreenHeight();

	// make sure at least part of the cursor is onscreen, if not then
	// just default to drawing a zero sized cursor - ie nothing.

	if (m_rclScreen.left > screenWidth || m_rclScreen.top > screenHeight
	    || m_rclScreen.right < 0 || m_rclScreen.bottom < 0) {
		m_rclScreen.left = m_rclScreen.right = screenWidth;
		m_rclScreen.top = m_rclScreen.bottom = screenHeight;
		m_rclCursor.left = m_rclCursor.right = 0;
		m_rclCursor.top = m_rclCursor.bottom = 0;
	}

    //
    // Clip to left edge of screen.
    //

    if (m_rclScreen.left < 0) {
        m_rclScreen.left = 0;
        m_rclCursor.left = m_rclCursor.right - 
                                (m_rclScreen.right - m_rclScreen.left);
    }

    //
    // Clip to right edge of screen.
    //

    if (m_rclScreen.right > screenWidth) {
        m_rclScreen.right = screenWidth;
        m_rclCursor.right = m_rclCursor.left + 
                                (m_rclScreen.right - m_rclScreen.left);
    }

    //
    // Clip to top of screen.
    //

    if (m_rclScreen.top < 0) {
        m_rclScreen.top = 0;
        m_rclCursor.top = m_rclCursor.bottom -
                                (m_rclScreen.bottom - m_rclScreen.top);
    }

    //
    // Clip to bottom of screen.
    //

    if (m_rclScreen.bottom > screenHeight) {
        m_rclScreen.bottom = screenHeight;
        m_rclCursor.bottom = m_rclCursor.top +
                                (m_rclScreen.bottom - m_rclScreen.top);
    }


    //
    // Draw the new cursor.
    //

    ShowSWCursor();

    return S_OK;
}


BOOL
SOFT_CURSOR::CursorIntersect(
    IN RECTL *prclBounds
    )

/*++

Routine Description:

    Tests for cursor intersection.

Arugments:

    prclDst - Bounding box to test against cursor.

Returns:

    TRUE if bounding box intersects with cursor screen location,
    FALSE otherwise.

--*/

{

    if (!m_bCursorVisible) {
        return FALSE;
    }


    //
    // Check for X intersect and Y intersection.
    //

    if (NULL==prclBounds) {
        return FALSE;
    }

    if ((prclBounds->right > m_rclScreen.left) &&
        (prclBounds->left < m_rclScreen.right) &&
        (prclBounds->bottom > m_rclScreen.top) &&
        (prclBounds->top < m_rclScreen.bottom)) {

        return TRUE;
    }

    return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -