Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// template\Template_Variant\Specific\lcd.cpp
// Implementation of an LCD driver.
// This file is part of the Template Base port
// N.B. This sample code assumes that the display supports setting the backlight on or off,
// as well as adjusting the contrast and the brightness.
//
//
#include <videodriver.h>
#include "platform.h"
#include <nkern.h>
#include <kernel/kernel.h>
#include <kernel/kern_priv.h>
#include <kernel/kpower.h>
#include <template_assp_priv.h>
// TO DO: (mandatory)
// If the display supports Contrast and/or Brightness control then supply the following defines:
// This is only example code... you may need to modify it for your hardware
const TInt KConfigInitialDisplayContrast = 128;
const TInt KConfigLcdMinDisplayContrast = 1;
const TInt KConfigLcdMaxDisplayContrast = 255;
const TInt KConfigInitialDisplayBrightness = 128;
const TInt KConfigLcdMinDisplayBrightness = 1;
const TInt KConfigLcdMaxDisplayBrightness = 255;
// TO DO: (mandatory)
// define a macro to calculate the screen buffer size
// This is only example code... you may need to modify it for your hardware
// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and
// aLpp number of lines per panel
#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp) (aBpp*aPpl*aLpp)/8
// TO DO: (mandatory)
// define the physical screen dimensions
// This is only example code... you need to modify it for your hardware
const TUint KConfigLcdWidth = 640; // 640 pixels per line
const TUint KConfigLcdHeight = 480; // 480 lines per panel
// TO DO: (mandatory)
// define the characteristics of the LCD display
// This is only example code... you need to modify it for your hardware
const TBool KConfigLcdIsMono = EFalse;
const TBool KConfigLcdPixelOrderLandscape = ETrue;
const TBool KConfigLcdPixelOrderRGB = ETrue;
const TInt KConfigLcdMaxDisplayColors = 65536;
// TO DO: (mandatory)
// define the display dimensions in TWIPs
// A TWIP is a 20th of a point. A point is a 72nd of an inch
// Therefore a TWIP is a 1440th of an inch
// This is only example code... you need to modify it for your hardware
const TInt KConfigLcdWidthInTwips = 9638; // = 6.69 inches
const TInt KConfigLcdHeightInTwips = 7370; // = 5.11 inches
// TO DO: (mandatory)
// define the available display modes
// This is only example code... you need to modify it for your hardware
const TInt KConfigLcdNumberOfDisplayModes = 1;
const TInt KConfigLcdInitialDisplayMode = 0;
struct SLcdConfig
{
TInt iMode;
TInt iOffsetToFirstVideoBuffer;
TInt iLenghtOfVideoBufferInBytes;
TInt iOffsetBetweenLines;
TBool iIsPalettized;
TInt iBitsPerPixel;
};
static const SLcdConfig Lcd_Mode_Config[KConfigLcdNumberOfDisplayModes]=
{
{
0, // iMode
0, // iOffsetToFirstVideoBuffer
FRAME_BUFFER_SIZE(8, KConfigLcdWidth, KConfigLcdHeight), // iLenghtOfVideoBufferInBytes
KConfigLcdWidth, // iOffsetBetweenLines
ETrue, // iIsPalettized
8 // iBitsPerPixel
}
};
_LIT(KLitLcd,"LCD");
//
// TO DO: (optional)
//
// Add any private functions and data you require
//
NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler
{
public:
DLcdPowerHandler();
~DLcdPowerHandler();
// from DPowerHandler
void PowerDown(TPowerState);
void PowerUp();
void PowerUpDfc();
void PowerDownDfc();
TInt Create();
void DisplayOn();
void DisplayOff();
TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
void PowerUpLcd(TBool aSecure);
void PowerDownLcd();
void ScreenInfo(TScreenInfoV01& aInfo);
void WsSwitchOnScreen();
void WsSwitchOffScreen();
void HandleMsg();
void SwitchDisplay(TBool aSecure);
void SetBacklightState(TBool aState);
void BacklightOn();
void BacklightOff();
TInt SetContrast(TInt aContrast);
TInt SetBrightness(TInt aBrightness);
private:
TInt SetPaletteEntry(TInt aEntry, TInt aColor);
TInt GetPaletteEntry(TInt aEntry, TInt* aColor);
TInt NumberOfPaletteEntries();
TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
TInt SetDisplayMode(TInt aMode);
void SplashScreen();
TInt GetDisplayColors(TInt* aColors);
private:
TBool iIsPalettized;
TBool iDisplayOn; // to prevent a race condition with WServer trying to power up/down at the same time
DPlatChunkHw* iChunk;
DPlatChunkHw* iSecureChunk;
TBool iWsSwitchOnScreen;
TBool iSecureDisplay;
TDynamicDfcQue* iDfcQ;
TMessageQue iMsgQ;
TDfc iPowerUpDfc;
TDfc iPowerDownDfc;
TVideoInfoV01 iVideoInfo;
TVideoInfoV01 iSecureVideoInfo;
NFastMutex iLock; // protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo
TPhysAddr ivRamPhys;
TPhysAddr iSecurevRamPhys;
TBool iBacklightOn;
TInt iContrast;
TInt iBrightness;
};
/**
HAL handler function
@param aPtr a pointer to an instance of DLcdPowerHandler
@param aFunction the function number
@param a1 an arbitrary parameter
@param a2 an arbitrary parameter
*/
LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
{
DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
return pH->HalFunction(aFunction,a1,a2);
}
/**
DFC for receiving messages from the power handler
@param aPtr a pointer to an instance of DLcdPowerHandler
*/
void rxMsg(TAny* aPtr)
{
DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
h.HandleMsg();
}
/**
DFC for powering up the device
@param aPtr aPtr a pointer to an instance of DLcdPowerHandler
*/
void power_up_dfc(TAny* aPtr)
{
((DLcdPowerHandler*)aPtr)->PowerUpDfc();
}
/**
DFC for powering down the device
@param aPtr aPtr a pointer to an instance of DLcdPowerHandler
*/
void power_down_dfc(TAny* aPtr)
{
((DLcdPowerHandler*)aPtr)->PowerDownDfc();
}
/**
Default constructor
*/
DLcdPowerHandler::DLcdPowerHandler() :
DPowerHandler(KLitLcd),
iMsgQ(rxMsg,this,NULL,1),
iPowerUpDfc(&power_up_dfc,this,6),
iPowerDownDfc(&power_down_dfc,this,7),
iBacklightOn(EFalse),
iContrast(KConfigInitialDisplayContrast),
iBrightness(KConfigInitialDisplayBrightness)
{
}
DLcdPowerHandler::~DLcdPowerHandler()
{
if (iDfcQ)
iDfcQ->Destroy();
}
/**
Second-phase constructor
Called by factory function at ordinal 0
*/
TInt DLcdPowerHandler::Create()
{
const TInt KLCDDfcQPriority=27; // Equal to Kern::DfcQue0() priority
TInt r = Kern::DynamicDfcQCreate(iDfcQ, KLCDDfcQPriority, _L("LCDPowerHandler"));
if (r != KErrNone)
{
return r;
}
// map the video RAM
TInt vSize = ((TemplateAssp*)Arch::TheAsic())->VideoRamSize();
ivRamPhys = TTemplate::VideoRamPhys(); // EXAMPLE ONLY: assume TTemplate interface class
r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
if (r != KErrNone)
return r;
//create "secure" screen immediately after normal one
iSecurevRamPhys = ivRamPhys + vSize;
TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
if (r2 != KErrNone)
return r2;
TUint* pV=(TUint*)iChunk->LinearAddress();
__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV));
// TO DO: (mandatory)
// initialise the palette for the initial display mode
// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
// or could be offered as part of the hardware block that implemenst the lcd control
//
TUint* pV2=(TUint*)iSecureChunk->LinearAddress();
__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2));
// TO DO: (mandatory)
// initialise the secure screen's palette for the initial display mode
//
// setup the video info structure, this'll be used to remember the video settings
iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode;
iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer;
iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized;
iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines;
iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel;
iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
iVideoInfo.iIsMono = KConfigLcdIsMono;
iVideoInfo.iVideoAddress=(TInt)pV;
iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape;
iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB;
iSecureVideoInfo = iVideoInfo;
iSecureVideoInfo.iVideoAddress = (TInt)pV2;
iDisplayOn = EFalse;
iSecureDisplay = EFalse;
// install the HAL function
r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
if (r!=KErrNone)
return r;
iPowerUpDfc.SetDfcQ(iDfcQ);
iPowerDownDfc.SetDfcQ(iDfcQ);
iMsgQ.SetDfcQ(iDfcQ);
iMsgQ.Receive();
// install the power handler
// power up the screen
Add();
DisplayOn();
SplashScreen();
return KErrNone;
}
/**
Turn the display on
May be called as a result of a power transition or from the HAL
If called from HAL, then the display may be already be on (iDisplayOn == ETrue)
*/
void DLcdPowerHandler::DisplayOn()
{
__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOn %d", iDisplayOn));
if (!iDisplayOn) // may have been powered up already
{
iDisplayOn = ETrue;
PowerUpLcd(iSecureDisplay);
SetContrast(iContrast);
SetBrightness(iBrightness);
}
}
/**
Turn the display off
May be called as a result of a power transition or from the HAL
If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse)
if the platform is in silent running mode
*/
void DLcdPowerHandler::DisplayOff()
{
__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOff %d", iDisplayOn));
if (iDisplayOn)
{
iDisplayOn = EFalse;
PowerDownLcd();
}
}
/**
Switch between secure and non-secure displays
@param aSecure ETrue if switching to secure display
*/
void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
{
if (aSecure)
{
if (!iSecureDisplay)
{
//switch to secure display
DisplayOff();
iSecureDisplay = ETrue;
DisplayOn();
}
}
else
{
if (iSecureDisplay)
{
//switch from secure display
DisplayOff();
iSecureDisplay = EFalse;
DisplayOn();
}
}
}
/**
DFC to power up the display
*/
void DLcdPowerHandler::PowerUpDfc()
{
__KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc"));
DisplayOn();
PowerUpDone(); // must be called from a different thread than PowerUp()
}
/**
DFC to power down the display
*/
void DLcdPowerHandler::PowerDownDfc()
{
__KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc"));
DisplayOff();
PowerDownDone(); // must be called from a different thread than PowerUp()
}
/**
Schedule the power-down DFC
*/
void DLcdPowerHandler::PowerDown(TPowerState)
{
iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread
}
/**
Schedule the power-up DFC
*/
void DLcdPowerHandler::PowerUp()
{
iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread
}
/**
Power up the display
@param aSecure ETrue if powering up the secure display
*/
void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
{
// TO DO: (mandatory)
// Power up the display and configure it ready for use
// Examples of things that may need initializing are:
// panel dimensions
// line & frame timings
// bits-per-pixel
// Configuring the DMA engine to map the video buffer in ivRamPhys or iSecurevRamPhys
// contrast, brightness, backlight
// power
// etc. etc.
//
}
/**
Power down the display and the backlight
*/
void DLcdPowerHandler::PowerDownLcd()
{
SetBacklightState(EFalse);
// TO DO: (mandatory)
// Power down the display & disable LCD DMA.
// May need to wait until the current frame has been output
//
}
/**
Set the Lcd contrast
@param aValue the contrast setting
*/
TInt DLcdPowerHandler::SetContrast(TInt aValue)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue));
if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast)
{
iContrast=aValue;
// TO DO: (mandatory)
// set the contrast
//
return KErrNone;
}
return KErrArgument;
}
/**
Set the Lcd brightness
@param aValue the brightness setting
*/
TInt DLcdPowerHandler::SetBrightness(TInt aValue)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness)
{
iBrightness=aValue;
// TO DO: (mandatory)
// set the brightness
//
return KErrNone;
}
return KErrArgument;
}
/**
Turn the backlight on
*/
void DLcdPowerHandler::BacklightOn()
{
// TO DO: (mandatory)
// turn the backlight on
//
}
/**
Turn the backlight off
*/
void DLcdPowerHandler::BacklightOff()
{
// TO DO: (mandatory)
// turn the backlight off
//
}
/**
Set the state of the backlight
@param aState ETrue if setting the backlight on
*/
void DLcdPowerHandler::SetBacklightState(TBool aState)
{
iBacklightOn=aState;
if (iBacklightOn)
BacklightOn();
else
BacklightOff();
}
void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo"));
anInfo.iWindowHandleValid=EFalse;
anInfo.iWindowHandle=NULL;
anInfo.iScreenAddressValid=ETrue;
anInfo.iScreenAddress=(TAny *)(iChunk->LinearAddress());
anInfo.iScreenSize.iWidth=KConfigLcdWidth;
anInfo.iScreenSize.iHeight=KConfigLcdHeight;
}
/**
Handle a message from the power handler
*/
void DLcdPowerHandler::HandleMsg(void)
{
TMessageBase* msg = iMsgQ.iMessage;
if (msg == NULL)
return;
if (msg->iValue)
DisplayOn();
else
DisplayOff();
msg->Complete(KErrNone,ETrue);
}
/**
Send a message to the power-handler message queue to turn the display on
*/
void DLcdPowerHandler::WsSwitchOnScreen()
{
TThreadMessage& m=Kern::Message();
m.iValue = ETrue;
m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up
}
/**
Send a message to the power-handler message queue to turn the display off
*/
void DLcdPowerHandler::WsSwitchOffScreen()
{
TThreadMessage& m=Kern::Message();
m.iValue = EFalse;
m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down
}
/**
Return information about the current display mode
@param aInfo a structure supplied by the caller to be filled by this function.
@param aSecure ETrue if requesting information about the secure display
@return KErrNone if successful
*/
TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
NKern::FMWait(&iLock);
if (aSecure)
aInfo = iSecureVideoInfo;
else
aInfo = iVideoInfo;
NKern::FMSignal(&iLock);
return KErrNone;
}
/**
Return information about the specified display mode
@param aMode the display mode to query
@param aInfo a structure supplied by the caller to be filled by this function.
@return KErrNone if successful
*/
TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("GetSpecifiedDisplayModeInfo mode is %d",aMode));
if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
return KErrArgument;
NKern::FMWait(&iLock);
aInfo = iVideoInfo;
NKern::FMSignal(&iLock);
if (aMode != aInfo.iDisplayMode)
{
aInfo.iOffsetToFirstPixel=Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
aInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
aInfo.iOffsetBetweenLines=Lcd_Mode_Config[aMode].iOffsetBetweenLines;
aInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
}
return KErrNone;
}
/**
Set the display mode
@param aMode the display mode to set
*/
TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
{
__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode = %d", aMode));
if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
return KErrArgument;
NKern::FMWait(&iLock);
// store the current mode
iVideoInfo.iDisplayMode = aMode;
iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
iVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
// store the current mode for secure screen
iSecureVideoInfo.iDisplayMode = aMode;
iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
// TO DO: (mandatory)
// set bits per pixel on hardware
// May need to reconfigure DMA if video buffer size and location have changed
//
NKern::FMSignal(&iLock);
__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode mode = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d",
aMode, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines));
return KErrNone;
}
/**
Fill the video memory with an initial pattern or image
This will be displayed on boot-up
*/
void DLcdPowerHandler::SplashScreen()
{
// TO DO: (optional)
// replace the example code below to display a different spash screen
// initialise the video ram to be a splash screen
__KTRACE_OPT(KEXTENSION,Kern::Printf("SplashScreen"));
TUint x,y;
TUint8 * p = (TUint8*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel);
//draw >< on screen
TUint rsh = KConfigLcdHeight;
TUint rsw = KConfigLcdWidth;
for (y = 0; y < rsh>>1; y++)
{
TUint8* q = p;
for (x = 0; x < rsw; x++)
*p++ = (x < y || (rsw-x<y)) ? 1 : 2;
p = q + iVideoInfo.iOffsetBetweenLines;
}
for (y = rsh>>1; y < rsh; y++)
{
TUint8* q = p;
for (x = 0; x < rsw; x++)
*p++ = ((x < rsh-y) || (rsw-x<rsh-y)) ? 1 : 2;
p = q + iVideoInfo.iOffsetBetweenLines;
}
p = (TUint8*)(iSecureVideoInfo.iVideoAddress + iSecureVideoInfo.iOffsetToFirstPixel);
//draw >< on secure screen
for (y = 0; y < rsh>>1; y++)
{
TUint8* q = p;
for (x = 0; x < rsw; x++)
*p++ = (x < y || (rsw-x<y)) ? 1 : 2;
p = q + iSecureVideoInfo.iOffsetBetweenLines;
}
for (y = rsh>>1; y < rsh; y++)
{
TUint8* q = p;
for (x = 0; x < rsw; x++)
*p++ = ((x < rsh-y) || (rsw-x<rsh-y)) ? 1 : 2;
p = q + iSecureVideoInfo.iOffsetBetweenLines;
}
}
/**
Get the size of the pallete
@return the number of pallete entries
*/
TInt DLcdPowerHandler::NumberOfPaletteEntries() //only call when holding mutex
{
// TO DO: (mandatory)
// Calculate the number of Palette entries - this is normally
// calculated from the bits per-pixel.
// This is only example code... you may need to modify it for your hardware
//
TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
__KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
return num;
}
/**
Retrieve the palette entry at a particular offset
@param aEntry the palette index
@param aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
@return KErrNone if successful
KErrNotSupported if the current vide mode does not support a palette
KErrArgument if aEntry is out of range
*/
TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
{
NKern::FMWait(&iLock);
if (!iVideoInfo.iIsPalettized)
{
NKern::FMSignal(&iLock);
return KErrNotSupported;
}
if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))
{
NKern::FMSignal(&iLock);
return KErrArgument;
}
// TO DO: (mandatory)
// read the RGB value of the palette entry into aColor
// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
// or could be offered as part of the hardware block that implemenst the lcd control
//
NKern::FMSignal(&iLock);
__KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor));
return KErrNone;
}
/**
Set the palette entry at a particular offset
@param aEntry the palette index
@param aColor the RGB color to store
@return KErrNone if successful
KErrNotSupported if the current vide mode does not support a palette
KErrArgument if aEntry is out of range
*/
TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor)
{
NKern::FMWait(&iLock);
if (!iVideoInfo.iIsPalettized)
{
NKern::FMSignal(&iLock);
return KErrNotSupported;
}
if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries())) //check entry in range
{
NKern::FMSignal(&iLock);
return KErrArgument;
}
// TO DO: (mandatory)
// update the palette entry for the secure and non-secure screen
// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
// or could be offered as part of the hardware block that implemenst the lcd control
//
__KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor ));
return KErrNone;
}
/**
a HAL entry handling function for HAL group attribute EHalGroupDisplay
@param a1 an arbitrary argument
@param a2 an arbitrary argument
@return KErrNone if successful
*/
TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
{
__e32_memory_barrier(); // Ensure changes from other clients are picked up
TInt r=KErrNone;
switch(aFunction)
{
case EDisplayHalScreenInfo:
{
TPckgBuf<TScreenInfoV01> vPckg;
ScreenInfo(vPckg());
Kern::InfoCopy(*(TDes8*)a1,vPckg);
break;
}
case EDisplayHalWsRegisterSwitchOnScreenHandling:
iWsSwitchOnScreen=(TBool)a1;
break;
case EDisplayHalWsSwitchOnScreen:
WsSwitchOnScreen();
break;
case EDisplayHalMaxDisplayContrast:
{
TInt mc=KConfigLcdMaxDisplayContrast;
kumemput32(a1,&mc,sizeof(mc));
break;
}
case EDisplayHalSetDisplayContrast:
if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
return KErrPermissionDenied;
r=SetContrast(TInt(a1));
break;
case EDisplayHalDisplayContrast:
kumemput32(a1,&iContrast,sizeof(iContrast));
break;
case EDisplayHalMaxDisplayBrightness:
{
TInt mc=KConfigLcdMaxDisplayBrightness;
kumemput32(a1,&mc,sizeof(mc));
break;
}
case EDisplayHalSetDisplayBrightness:
if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
return KErrPermissionDenied;
r=SetBrightness(TInt(a1));
break;
case EDisplayHalDisplayBrightness:
kumemput32(a1,&iBrightness,sizeof(iBrightness));
break;
case EDisplayHalSetBacklightOn:
if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
return KErrPermissionDenied;
if (Kern::MachinePowerStatus()<ELow)
r=KErrBadPower;
else
SetBacklightState(TBool(a1));
break;
case EDisplayHalBacklightOn:
kumemput32(a1,&iBacklightOn,sizeof(TInt));
break;
case EDisplayHalModeCount:
{
TInt ndm = KConfigLcdNumberOfDisplayModes;
kumemput32(a1, &ndm, sizeof(ndm));
break;
}
case EDisplayHalSetMode:
if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
return KErrPermissionDenied;
r = SetDisplayMode((TInt)a1);
break;
case EDisplayHalMode:
kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
break;
case EDisplayHalSetPaletteEntry:
if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
return KErrPermissionDenied;
r = SetPaletteEntry((TInt)a1, (TInt)a2);
break;
case EDisplayHalPaletteEntry:
{
TInt entry;
kumemget32(&entry, a1, sizeof(TInt));
TInt x;
r = GetPaletteEntry(entry, &x);
if (r == KErrNone)
kumemput32(a2, &x, sizeof(x));
break;
}
case EDisplayHalSetState:
{
if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
return KErrPermissionDenied;
if ((TBool)a1)
{
WsSwitchOnScreen();
}
else
{
WsSwitchOffScreen();
}
break;
}
case EDisplayHalState:
kumemput32(a1, &iDisplayOn, sizeof(TBool));
break;
case EDisplayHalColors:
{
TInt mdc = KConfigLcdMaxDisplayColors;
kumemput32(a1, &mdc, sizeof(mdc));
break;
}
case EDisplayHalCurrentModeInfo:
{
TPckgBuf<TVideoInfoV01> vPckg;
r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
if (KErrNone == r)
Kern::InfoCopy(*(TDes8*)a1,vPckg);
}
break;
case EDisplayHalSpecifiedModeInfo:
{
TPckgBuf<TVideoInfoV01> vPckg;
TInt mode;
kumemget32(&mode, a1, sizeof(mode));
r = GetSpecifiedDisplayModeInfo(mode, vPckg());
if (KErrNone == r)
Kern::InfoCopy(*(TDes8*)a2,vPckg);
}
break;
case EDisplayHalSecure:
kumemput32(a1, &iSecureDisplay, sizeof(TBool));
break;
case EDisplayHalSetSecure:
{
if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
return KErrPermissionDenied;
SwitchDisplay((TBool)a1);
}
break;
default:
r=KErrNotSupported;
break;
}
__e32_memory_barrier(); // Ensure any changes are propagated to other clients
return r;
}
DECLARE_STANDARD_EXTENSION()
{
__KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
// create LCD power handler
TInt r=KErrNoMemory;
DLcdPowerHandler* pH=new DLcdPowerHandler;
if (pH)
r=pH->Create();
__KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
return r;
}