Fixes to syborg-graphicswrapper.vcproj
These changes allow syborg-graphicswrapper to link against the hostthreadadapter and khronosapiwrapper libraries built by the graphics.simulator component.
The .vcproj file uses relative paths, which requires that the following three packages are laid out as follows:
os/
graphics
adapt/
graphics.simulator
qemu
/*
* Copyright (c) 2010 ISB.
* 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:
* ISB - initial contribution.
*
* Contributors:
*
* Description: USB driver for test
*
*/
#include <kern_priv.h>
#include "webcamera_ldd.h"
#include <webcamera_driver.h>
#define DP(format...) Kern::Printf(format)
_LIT(KDriver1PanicCategory,"WebcameraDevice");
/**
*Create Logic device.
*
*/
DECLARE_STANDARD_LDD()
{
DP("DECLARE_STANDARD_LDD()");
return new DWebcameraLogicalDevice;
}
/**
Constructor
*/
DWebcameraLogicalDevice::DWebcameraLogicalDevice()
{
DP("DWebcameraLogicalDevice()");
// Set version number for this device
iVersion=RWebcameraDevice::VersionRequired();
// Indicate that we work with a PDD
iParseMask=KDeviceAllowPhysicalDevice;
}
/**
Destructor
*/
DWebcameraLogicalDevice::~DWebcameraLogicalDevice()
{
}
/**
Second stage constructor for DDriver1Factory.
This must at least set a name for the driver object.
@return KErrNone if successful, otherwise one of the other system wide error codes.
*/
TInt DWebcameraLogicalDevice::Install()
{
DP("DWebcameraLogicalDevice::Install()");
return SetName(&RWebcameraDevice::Name());
}
/**
Return the drivers capabilities.
Called in the response to an RDevice::GetCaps() request.
@param aDes User-side descriptor to write capabilities information into
*/
void DWebcameraLogicalDevice::GetCaps(TDes8& aDes) const
{
// Create a capabilities object
RWebcameraDevice::TCaps caps;
caps.iVersion = iVersion;
// Write it back to user memory
Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
}
/**
Called by the kernel's device driver framework to create a Logical Channel.
This is called in the context of the user thread (client) which requested the creation of a Logical Channel
(E.g. through a call to RBusLogicalChannel::DoCreate)
The thread is in a critical section.
@param aChannel Set to point to the created Logical Channel
@return KErrNone if successful, otherwise one of the other system wide error codes.
*/
TInt DWebcameraLogicalDevice::Create(DLogicalChannelBase*& aChannel)
{
DP("DWebcameraLogicalDevice::Create() start");
aChannel = new DWebcameraLogicalChannel;
if(!aChannel)
return KErrNoMemory;
return KErrNone;
DP("DWebcameraLogicalDevice::Create() end");
}
/**
Constructor
*/
DWebcameraLogicalChannel::DWebcameraLogicalChannel()
: iReceiveDataDfc(GetOneFlameDfc, this, 1)
,iCaptureDfc(CaptureDfc,this,1)
{
DP("DWebcameraLogicalChannel::DWebcameraLogicalChannel() start");
// Get pointer to client threads DThread object
iClient=&Kern::CurrentThread();
// Open a reference on client thread so it's control block can't dissapear until
// this driver has finished with it.
((DObject*)iClient)->Open();
DP("DWebcameraLogicalChannel::DWebcameraLogicalChannel() end");
}
/**
Destructor
*/
DWebcameraLogicalChannel::~DWebcameraLogicalChannel()
{
DP("DWebcameraLogicalChannel::~DWebcameraLogicalChannel() start");
// Cancel all processing that we may be doing
DoCancel(RWebcameraDevice::EAllRequests);
if (iComm)
{
delete iComm;
}
if (iChunk)
{
Epoc::FreePhysicalRam(iPhysAddr, iSize);
}
// Close our reference on the client thread
Kern::SafeClose((DObject*&)iClient,NULL);
DP("DWebcameraLogicalChannel::~DWebcameraLogicalChannel() end");
}
/**
Called when a user thread requests a handle to this channel.
*/
TInt DWebcameraLogicalChannel::RequestUserHandle(DThread* aThread, TOwnerType aType)
{
// Make sure that only our client can get a handle
if (aType!=EOwnerThread || aThread!=iClient)
return KErrAccessDenied;
return KErrNone;
}
/**
Second stage constructor called by the kernel's device driver framework.
This is called in the context of the user thread (client) which requested the creation of a Logical Channel
(E.g. through a call to RBusLogicalChannel::DoCreate)
The thread is in a critical section.
@param aUnit The unit argument supplied by the client
@param aInfo The info argument supplied by the client
@param aVer The version argument supplied by the client
@return KErrNone if successful, otherwise one of the other system wide error codes.
*/
TInt DWebcameraLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
{
DP("DWebcameraLogicalChannel::DoCreate() start");
if(!Kern::CurrentThreadHasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by Webcamera")))
{
return KErrPermissionDenied;
}
// Check version
if (!Kern::QueryVersionSupported(RWebcameraDevice::VersionRequired(),aVer))
{
return KErrNotSupported;
}
// Setup LDD for receiving client messages
SetDfcQ(Kern::DfcQue0());
iMsgQ.Receive();
// Associate DFCs with the same queue we set above to receive client messages on
iReceiveDataDfc.SetDfcQ(iDfcQ);
iCaptureDfc.SetDfcQ(iDfcQ);
// Give PDD a pointer to this channel
Pdd()->iLdd=this;
//allocate Memory
iSize=Kern::RoundToPageSize(BUFSIZE);
TInt rtn=Epoc::AllocPhysicalRam(iSize, iPhysAddr);
if (rtn != KErrNone)
{
return rtn;
}
rtn=DPlatChunkHw::New(iChunk, iPhysAddr, iSize,EMapAttrUserRw|EMapAttrBufferedC);
if (rtn != KErrNone)
{
if (iPhysAddr)
{
Epoc::FreePhysicalRam(iPhysAddr, iSize);
}
return rtn;
}
iLAdr = reinterpret_cast<TUint8*>(iChunk->LinearAddress());
iComm=HBuf8::New(BUFSIZE);
if (!iComm)
{
return KErrNotSupported;
}
iReceiveDataBuffer=iComm;
iCaptureBuffer=iComm;
DP("DWebcameraLogicalChannel::DoCreate() end");
return KErrNone;
}
/**
Process a message for this logical channel.
This function is called in the context of a DFC thread.
@param aMessage The message to process.
The iValue member of this distinguishes the message type:
iValue==ECloseMsg, channel close message
iValue==KMaxTInt, a 'DoCancel' message
iValue>=0, a 'DoControl' message with function number equal to iValue
iValue<0, a 'DoRequest' message with function number equal to ~iValue
*/
void DWebcameraLogicalChannel::HandleMsg(TMessageBase* aMsg)
{
DP("DWebcameraLogicalChannel::HandleMsg() start");
TThreadMessage& m=*(TThreadMessage*)aMsg;
// Get message type
TInt id=m.iValue;
DP("id=%d",id);
// Decode the message type and dispatch it to the relevent handler function...
if (id==(TInt)ECloseMsg)
{
DoCancel(RWebcameraDevice::EAllRequests);
m.Complete(KErrNone, EFalse);
return;
}
if(m.Client()!=iClient)
{
Kern::ThreadKill(m.Client(),
EExitPanic,
ERequestFromWrongThread,
KDriver1PanicCategory);
m.Complete(KErrNone,ETrue);
return;
}
if (id==KMaxTInt)
{
DoCancel(m.Int0());
m.Complete(KErrNone,ETrue);
return;
}
if (id<0)
{
// DoRequest
TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
TInt rtn =DoRequest(~id,pS,m.Ptr1(),aMsg);
if (rtn != KErrNone)
Kern::RequestComplete(iClient,pS,rtn);
m.Complete(KErrNone,ETrue);
}
else
{
// DoControl
TInt rtn = DoControl(id,m.Ptr0(),aMsg);
m.Complete(rtn,ETrue);
}
DP("DWebcameraLogicalChannel::HandleMsg() end");
}
/**
Process synchronous 'control' requests
*/
TInt DWebcameraLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
{
DP("DWebcameraLogicalChannel::DoControl() start");
TInt rtn;
TThreadMessage& m=*(TThreadMessage*)a2;
TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
switch (aFunction)
{
case RWebcameraDevice::EGetConfig:
// rtn = GetConfig((TDes8*)a1);
rtn = KErrNone;
if ( rtn != KErrNone )
{
Kern::RequestComplete(iClient,pS,rtn);
}
break;
case RWebcameraDevice::ESetConfig:
// rtn = SetConfig((const TDesC8*)a1);
break;
default:
rtn = KErrNotSupported;
Kern::RequestComplete(iClient,pS,rtn);
break;
}
DP("DWebcameraLogicalChannel::DoControl() end");
return rtn;
}
/**
Process asynchronous requests.
*/
TInt DWebcameraLogicalChannel::DoRequest(TInt aReqNo,
TRequestStatus* aStatus,
TAny* a1,
TAny* a2)
{
DP("DWebcameraLogicalChannel::DoRequest() start");
TInt rtn;
TThreadMessage& m=*(TThreadMessage*)a2;
iRequesting =ETrue;
rtn = KErrNone;
DP("aReqNo=%d",aReqNo);
switch(aReqNo)
{
case RWebcameraDevice::EStart:
DP("EStart=%d",RWebcameraDevice::EStart);
iReceiveDataStatus = aStatus;
iReceiving = ETrue ;
iReceiveDataBuffer->FillZ(iCaptureBuffer->MaxLength());
iReceiveDataBuffer->Zero();
DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->MaxLength());
DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->Length());
rtn = Pdd()->StartViewerFinder(iPhysAddr,iSize);
if ( rtn != KErrNone )
{
DP("rtn=%d",rtn);
iReceiving = EFalse ;
Kern::RequestComplete(iClient,aStatus,rtn);
}
else
{
DP("rtn=%d",rtn);
// Example Platform Security capability check which tests the
// client for ECapability_None (which always passes)...
if ( iRequesting == EFalse )
{
DP("iRequesting=EFalse");
iReceiving = EFalse ;
Kern::RequestComplete(iClient,
iReceiveDataStatus,
iReceiveDataResult);
}
else
{
DP("iRequesting=ETrue");
iReceiveDataDescriptor=(TDes8*)a1;
}
}
break;
case RWebcameraDevice::ECapture:
iCaptureing = ETrue ;
iCaptureStatus = aStatus;
iCaptureBuffer->FillZ(iCaptureBuffer->MaxLength());
iCaptureBuffer->Zero();
DP("iCaptureBuffer Len=%d",iCaptureBuffer->MaxLength());
DP("iCaptureBuffer Len=%d",iCaptureBuffer->Length());
rtn = Pdd()->StartCapture(iPhysAddr,iSize);
DP("rtn=%d",rtn);
if ( rtn != KErrNone )
{
iCaptureing = EFalse ;
Kern::RequestComplete(iClient,aStatus,rtn);
}
else
{
if ( iRequesting == EFalse )
{
DP("iRequesting=EFalse");
iReceiving = EFalse ;
Kern::RequestComplete(iClient,iCaptureStatus,iCaptureResult);
}
else
{
DP("Capture iRequesting=ETrue");
iCaptureDescriptor=(TDes8*)a1;
}
}
break;
default:
rtn=KErrNotSupported;
Kern::RequestComplete(iClient,aStatus,rtn);
break;
}
iRequesting = EFalse;
DP("DWebcameraLogicalChannel::DoRequest() end");
return rtn;
}
/**
Process cancelling of asynchronous requests.
*/
void DWebcameraLogicalChannel::DoCancel(TUint aMask)
{
DP("DWebcameraLogicalChannel::DoCancel() start");
TInt rtn;
DP("aMask=%d",aMask);
if (aMask&(1<<RWebcameraDevice::EStart))
{
DP("RWebcameraDevice::EStart=%d",RWebcameraDevice::EStart);
if (iReceiveDataStatus)
{
DP("iReceiveDataStatus=%d",iReceiveDataStatus);
Pdd()->Stop(DWebcameraDriverBase::USB_cancel);
iReceiving = EFalse ;
iReceiveDataDfc.Cancel();
Kern::RequestComplete(iClient,iReceiveDataStatus,KErrCancel);
}
}
if (aMask&(1<<RWebcameraDevice::ECapture))
{
DP("RWebcameraDevice::ECapture=%d",RWebcameraDevice::ECapture);
if (iCaptureStatus)
{
Pdd()->Stop(DWebcameraDriverBase::USB_cancel);
iReceiving = EFalse ;
iCaptureDfc.Cancel();
Kern::RequestComplete(iClient,iCaptureStatus,KErrCancel);
}
}
DP("DWebcameraLogicalChannel::DoCancel() end");
}
/**
Called by PDD from ISR to indicate that a ReceiveData operation has completed.
*/
void DWebcameraLogicalChannel::GetOneFlameComplete(TInt aDataSize)
{
DP("DWebcameraLogicalChannel::GetOneFlameComplete() start");
DP("datasize=%d",aDataSize);
iSaveSize=iSize - aDataSize;
// Queue DFC
iReceiveDataDfc.Add();
//set size of received data
if (iSaveSize > 0)
{
iReceiveDataResult = KErrNone;
}
else
{
iReceiveDataResult = KErrUnknown;//TODO:define of error
}
DP("DWebcameraLogicalChannel::GetOneFlameComplete() end");
}
/**
Called by PDD from ISR to indicate that a get capture image operation has completed.
*/
void DWebcameraLogicalChannel::CaptureComplete(TInt aDataSize)
{
DP("DWebcameraLogicalChannel::CaptureComplete() start");
DP("datasize=%d",aDataSize);
iSaveSize=iSize - aDataSize;
// Queue DFC
iCaptureDfc.Add();
//set size of received data
if (iSaveSize > 0)
{
iCaptureResult = KErrNone;
}
else
{
iCaptureResult = KErrUnknown;//TODO:define of error
}
DP("DWebcameraLogicalChannel::CaptureComplete() end");
}
/**
DFC Callback which gets triggered after the PDD has signalled that getting oneflame completed.
This just casts aPtr and calls DoGetOneFlameComplete().
*/
void DWebcameraLogicalChannel::GetOneFlameDfc(TAny* aPtr)
{
DP("DWebcameraLogicalChannel::GetOneFlameDfc() start");
((DWebcameraLogicalChannel*)aPtr)->DoGetOneFlameComplete();
DP("DWebcameraLogicalChannel::GetOneFlameDfc() end");
}
/**
DFC Callback which gets triggered after the PDD has signalled that getting Capture image completed.
This just casts aPtr and calls DoCaptureComplete().
*/
void DWebcameraLogicalChannel::CaptureDfc(TAny* aPtr)
{
DP("DWebcameraLogicalChannel::CaptureDfc() start");
((DWebcameraLogicalChannel*)aPtr)->DoCaptureComplete();
DP("DWebcameraLogicalChannel::CaptureDfc() end");
}
/**
Called from a DFC after the PDD has signalled that getting oneflame completed.
*/
void DWebcameraLogicalChannel::DoGetOneFlameComplete()
{
DP("DWebcameraLogicalChannel::DoGetOneFlameComplete() start");
iReceiveDataBuffer->Copy(iLAdr,iSaveSize);
DP("iReceiveDataBuffer Len=%d",iReceiveDataBuffer->Length());
// Write data to client from our buffer
TInt result=Kern::ThreadDesWrite(iClient,iReceiveDataDescriptor,*iReceiveDataBuffer,0);
// Finished with client descriptor, so NULL it to help detect coding errors
iReceiveDataDescriptor = NULL;
// Use result code from PDD if it was an error
if(iReceiveDataResult!=KErrNone)
result = iReceiveDataResult;
// Complete clients request
Kern::RequestComplete(iClient,iReceiveDataStatus,result);
DP("DWebcameraLogicalChannel::DoGetOneFlameComplete() end");
}
/**
Called from a DFC after the PDD has signalled that getting Capture image completed.
*/
void DWebcameraLogicalChannel::DoCaptureComplete()
{
DP("DWebcameraLogicalChannel::DoCaptureComplete() start");
iCaptureBuffer->Copy(iLAdr,iSaveSize);
DP("iCaptureBuffer Len=%d",iCaptureBuffer->Length());
// Write data to client from our buffer
TInt result=Kern::ThreadDesWrite(iClient,iCaptureDescriptor,*iCaptureBuffer,0);
// Finished with client descriptor, so NULL it to help detect coding errors
iCaptureDescriptor = NULL;
// Use result code from PDD if it was an error
if(iCaptureResult!=KErrNone)
result = iCaptureResult;
// Complete clients request
Kern::RequestComplete(iClient,iCaptureStatus,result);
DP("DWebcameraLogicalChannel::DoCaptureComplete() end");
}
/**
Process a GetConfig control message. This writes the current driver configuration to a
RWebcameraDevice::TConfigBuf supplied by the client.
*/
TInt DWebcameraLogicalChannel::GetConfig(TDes8* aConfigBuf)
{
//unsupported
}
/**
Process a SetConfig control message. This sets the driver configuration using a
RWebcameraDevice::TConfigBuf supplied by the client.
*/
TInt DWebcameraLogicalChannel::SetConfig(const TDesC8* aConfigBuf)
{
//unsupported
}
/**
Fill a TConfig with the drivers current configuration.
*/
/*void DWebcameraLogicalChannel::CurrentConfig(RWebcameraDevice::TConfig& aConfig)
{
//unsupported
}
*/
/**
*Get the point to Physical channel.
*/
DWebcameraDriverBase* DWebcameraLogicalChannel::Pdd()
{
DP("DWebcameraLogicalChannel::Pdd() start");
return (DWebcameraDriverBase*)iPdd;
}