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

📄 rotate.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
字号:
/***************************************************************************
 * Name        : rotate.cpp
 * Title       : MBX WinCE driver GPE class
 * Author(s)   : Imagination Technologies
 * Created	   : 20th January 2003
 *
 * Copyright   : 2003 by Imagination Technologies. All rights reserved.
 *             : No part of this software, either material or conceptual 
 *             : may be copied or distributed, transmitted, transcribed,
 *             : stored in a retrieval system or translated into any 
 *             : human or computer language in any form by any means,
 *             : electronic, mechanical, manual or other-wise, or 
 *             : disclosed to third parties without the express written
 *             : permission of Imagination Technologies Limited, Unit 8,
 *             : HomePark Industrial Estate, King's Langley, Hertfordshire,
 *             : WD4 8LZ, U.K.
 *
 * Description : MBX WinCE driver GPE class.
 *
 * Platform    : WinCE
 *
 * Modifications:-
 * $Log: rotate.cpp $
 *
 *  --- Revision Logs Removed --- 
 *
 *  --- Revision Logs Removed --- 
 *
 *  --- Revision Logs Removed --- 
 *
 ****************************************************************************/

#include	"precomp.h"

extern "C"
{
#include	"dispperf.h"
}

#ifdef ROTATE_ENABLE

static LONG ValidateAngle(LONG lDegrees);
static LONG RotEnumToDegrees(int iRotEnum);

#define BATCH_SIZE_2D		0x30


/***********************************************************************************
 Function Name	: GetRotateModeFromReg
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: 
************************************************************************************/
int MBX::GetRotateModeFromReg()
{
	int nRtn;
	LONG lLogicalAngle = 0;
	LONG lPhysAngle = 0;

	HKEY hKey;

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("system\\gdi\\rotation"),0,0, &hKey) == ERROR_SUCCESS)
	{
		ULONG ulSize = sizeof(ULONG);
		ULONG ulType = REG_DWORD;

		RegQueryValueEx(hKey, TEXT("Angle"), NULL, &ulType, (PBYTE)&lLogicalAngle, &ulSize);
		RegCloseKey(hKey);
	}

	// Side effect : sets up the the m_lRotationRemap member of MBX class.
	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Drivers\\Display\\PowerVR"),0,0, &hKey) == ERROR_SUCCESS)
	{
		ULONG ulSize = sizeof(ULONG);
		ULONG ulType = REG_DWORD;

		RegQueryValueEx(hKey, TEXT("RotationRemap"), NULL, &ulType, (PBYTE)&m_lRotationRemap, &ulSize);
		RegCloseKey(hKey);
	}

	lPhysAngle = LogicalToPhysRotDegrees(lLogicalAngle);
	nRtn = DegreesToRotEnum(lPhysAngle);

	return nRtn;

}//GetRotateModeFromReg


/***********************************************************************************
 Function Name	: SetRotateParams
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: 
************************************************************************************/
void MBX::SetRotateParams()
{
	int nSwap;

	switch(m_iRotate)
	{
		default:
		case DMDO_0:
			m_nScreenHeightSave = m_nScreenHeight;
			m_nScreenWidthSave  = m_nScreenWidth;
			break;

		case DMDO_180:
			m_nScreenHeightSave = m_nScreenHeight;
			m_nScreenWidthSave  = m_nScreenWidth;
			break;

		case DMDO_90:
		case DMDO_270:
			nSwap = m_nScreenHeight;
			m_nScreenHeight     = m_nScreenWidth;
			m_nScreenWidth      = nSwap;
			m_nScreenHeightSave = m_nScreenWidth;
			m_nScreenWidthSave  = m_nScreenHeight;
			break;
	}

}//SetRotateParams


/***********************************************************************************
 Function Name	: UnRotate
 Inputs			: Either the source or dest rect. THEY ARE BOTH ON THE DEST SURFACE.
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Unrotated a rectangle. Used when doing a rotated blt unrotated.
************************************************************************************/
void MBX::UnRotate(RECTL* prcRect, MBXSurf *pSurf)
{
	RECTL rcSwap = *prcRect;
	LONG lPhysWidth,lPhysHeight;
	
	if (!pSurf->m_lRotationAngle)
	{
		return;
	}

	if (pSurf->m_lRotationAngle == 90 || pSurf->m_lRotationAngle == 270)
	{
		lPhysWidth = pSurf->Height();
		lPhysHeight = pSurf->Width();
	}
	else
	{
		lPhysWidth = pSurf->Width();
		lPhysHeight = pSurf->Height();
	}

	switch (pSurf->m_lRotationAngle)
	{
		case 90:
		{
			prcRect->top    = lPhysHeight - rcSwap.right;
			prcRect->bottom = lPhysHeight - rcSwap.left;
			prcRect->left   = rcSwap.top;
			prcRect->right  = rcSwap.bottom;
			break;
		}
		
		case 180:
		{
			prcRect->top    = lPhysHeight - rcSwap.bottom;
			prcRect->bottom = lPhysHeight - rcSwap.top;
			prcRect->left   = lPhysWidth-rcSwap.right;
			prcRect->right  = lPhysWidth-rcSwap.left;
			break;
		}
		
		case 270:
		{
			prcRect->top    = rcSwap.left;
			prcRect->bottom = rcSwap.right;
			prcRect->left   = lPhysWidth - rcSwap.bottom;
			prcRect->right  = lPhysWidth - rcSwap.top;
			break;
		}
	}

}//UnRotate


/***********************************************************************************
 Function Name	: DynRotate
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: 
************************************************************************************/
LONG MBX::DynRotate(int nAngle)
{
	MBXSurf* pMBXSurf = (MBXSurf*)m_pPrimarySurface;

	if (nAngle == m_iRotate)
	{
		// No change, do nothing.
		return (DISP_CHANGE_SUCCESSFUL);
	}
	else
	{
		m_iRotate = nAngle;
	}

	switch(m_iRotate)
	{
		case DMDO_0:
			pMBXSurf->m_lRotationAngle = 0;
			pMBXSurf->m_bIsRotated = FALSE;
			m_nScreenHeight = m_nScreenHeightSave;
			m_nScreenWidth  = m_nScreenWidthSave;
			break;

		case DMDO_180:
			pMBXSurf->m_lRotationAngle = 180;
			pMBXSurf->m_bIsRotated = TRUE;
			m_nScreenHeight = m_nScreenHeightSave;
			m_nScreenWidth  = m_nScreenWidthSave;
			break;

		case DMDO_90:
			pMBXSurf->m_lRotationAngle = 90;
			pMBXSurf->m_bIsRotated = TRUE;
			m_nScreenHeight = m_nScreenWidthSave;
			m_nScreenWidth  = m_nScreenHeightSave;
			break;

		case DMDO_270:
			pMBXSurf->m_lRotationAngle = 270;
			pMBXSurf->m_bIsRotated = TRUE;
			m_nScreenHeight = m_nScreenWidthSave;
			m_nScreenWidth  = m_nScreenHeightSave;
			break;
	}

	m_pMode->width  = m_nScreenWidth;
	m_pMode->height = m_nScreenHeight;

	// Call GPE base class to update GPE rotation members
	((GPESurfRotate *)m_pPrimarySurface)->SetRotation(m_nScreenWidth, m_nScreenHeight, nAngle);

	// notify PDP of rotation
	m_clDisplay.PDP_SetCursorRotation(nAngle);

	// Verify rotation for debug builds please
	#if defined(ROTATE_ENABLE) && defined(HW_VERIFY) && defined(DEBUG) && 0
	switch(m_iRotate)
	{
		case DMDO_180:
		case DMDO_90:
		case DMDO_270:
		{
			m_clHwVer.Enable(	TRUE,		// bPDumpFailures
								TRUE,		// bUnattendedMode
								VERDST_RECT /*_PLUS */
								);
			break;
		}

		default:
		case DMDO_0:
		{
			m_clHwVer.Disable();
			break;
		}
	}
	#endif

	return (DISP_CHANGE_SUCCESSFUL);

}//DynRotate


/*

	Device Mode Display Orientation

	PocketPC expects DMDO_0 to be any rotation necessary to put the display in
	Portrait Mode regardless of the physical orientation of the screen.

	This makes it necessary for the display driver to do logical<->physical remapping.
	There is no Microsoft sample code for this, so we are left to make educated guesses as to how to implement this.

	The MS software blt libraries do not support logical->physical mapping of rotation
	and so we assume that the driver has to store physical rotation in the MS GPERotate
	and GPESurfRotate classes. If we did not do that the pixels of any punted blts would
	be written to the wrong addresses. Note that the same member name m_iRotate is used
	in both classes and they are not the same thing.

	I propose to convert rotation from logical to physical at the following points:

	1) "Angle" Registry entry.

	[HKEY_LOCAL_MACHINE\system\gdi\rotation]
	"Angle"=dword:0

	I assume that this is logical rotation and so we convert to physical before storing
	it in the m_iRotate member of the GPERotate class.

	I assume that an angle of 0 is portrait mode in PPC and landscape in WinCE.

	2) Driver escape :

	DRVESC_GETSCREENROTATION converts m_iRotate from physical to logical and the returns logical rotation.
	DRVESC_SETSCREENROTATION converts the angle from logical to physical and assigns it to m_iRotate.

	Assumptions:
	We have to assume that PPC knows about rotation remapping and so does not rely on the m_iRotate member.
	For example the public GPERotate member function
	 BOOL    IsRotate() {return (m_iRotate != DMDO_0);}
	will not work unless the caller wants to know if there is any physical rotation.


	New Registry settings:

	The physical rotation required to achieve a logical rotation of zero for any particular
	panel will be defined by a new setting in the registry called "RotationRemap" in degrees (see below).

	This will be used by the display driver to convert between logical and physical rotation.

	[HKEY_LOCAL_MACHINE\Drivers\Display\PowerVR]
		"RotationRemap"=dword:10E

*/


/***********************************************************************************
 Function Name	: LogicalToPhysRotDegrees
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts rotation angles from logical to physical in degrees
************************************************************************************/
LONG MBX::LogicalToPhysRotDegrees(LONG lDegreesLogical)
{
	return ValidateAngle(lDegreesLogical + m_lRotationRemap);
}

/***********************************************************************************
 Function Name	: PhysToLogicalRotDegrees
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts rotation angles from physical to logical in degrees
************************************************************************************/
LONG MBX::PhysToLogicalRotDegrees(LONG lDegreesPhys)
{
	return ValidateAngle(lDegreesPhys - m_lRotationRemap);
}

/***********************************************************************************
 Function Name	: LogicalToPhysRotEnum
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts rotation from logical to physical using DMDO enum
************************************************************************************/
int MBX::LogicalToPhysRotEnum(int iRotEnumLogical)
{
	LONG lDegreesLogical = RotEnumToDegrees(iRotEnumLogical);
	LONG lDegreesPhys = LogicalToPhysRotDegrees(lDegreesLogical);

	return DegreesToRotEnum(lDegreesPhys);
}

/***********************************************************************************
 Function Name	: PhysToLogicalRotEnum
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts rotation from physical to logical using DMDO enum
************************************************************************************/
int MBX::PhysToLogicalRotEnum(int iRotEnumPhys)
{
	LONG lDegreesPhys = RotEnumToDegrees(iRotEnumPhys);
	LONG lDegreesLogical = PhysToLogicalRotDegrees(lDegreesPhys);

	return DegreesToRotEnum(lDegreesLogical);
}

/***********************************************************************************
 Function Name	: ValidateAngle
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Truncates angles greater than 360 degrees
************************************************************************************/
static LONG ValidateAngle(LONG lDegrees)
{
	if (lDegrees <= -360)
	{
		lDegrees += 360;
	}

	if (lDegrees >= 360)
	{
		lDegrees -= 360;
	}
	return lDegrees;
}

/***********************************************************************************
 Function Name	: RotEnumToDegrees
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts DMDO_x format into degrees
************************************************************************************/
static LONG RotEnumToDegrees(int iRotEnum)
{
	switch (iRotEnum)
	{
		case DMDO_0:
		default:
			return 0;

		case DMDO_90:
			return 90;

		case DMDO_180:
			return 180;

		case DMDO_270:
			return 270;
	}
}

/***********************************************************************************
 Function Name	: DegreesToRotEnum
 Inputs			: 
 Outputs		: 
 Returns		: 
 Globals Used	: 
 Description	: Converts rotation angle into DMDO_x format.
************************************************************************************/
int MBX::DegreesToRotEnum(LONG lDegrees)
{
	switch (ValidateAngle(lDegrees))
	{
		case 0:
		default:
			return DMDO_0;

		case 90:
			return DMDO_90;

		case 180:
			return DMDO_180;

		case 270:
			return DMDO_270;
	}
}


#endif //ROTATE_ENABLE

/********************************** end of file ******************************/

⌨️ 快捷键说明

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