📄 en_main.cpp
字号:
// EN_MAIN.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.
#include <bldvariant.hrh>
#if defined(__SERIES60__)
#include <e32uid.h>
#include <opcodes.h>
#include <oplr.h>
#include "graphics.h"
#include "oplutil.h"
#include "opldialg.h"
#include <aknenv.h>
#include <eikhkeyt.h>
#include <opldbg.h>
#include <bafindf.h>
#include "clckupdt.h"
#include "opldb.h"
#include "module.h"
#include "frame.h"
#include "debug.h"
#include <avkon.rsg>
#elif defined(__UIQ__)
#include <OplAPI.h>
#include <e32hal.h>
#include <e32uid.h>
#include <opcodes.h>
#include <module.h>
#include <oplcmd.h>
#include <opldb.h>
#include <eikon.hrh>
#include <apgwgnam.h>
#include "frame.h"
#include "graphics.h"
#include "oplutil.h"
#include <opldbg.h>
#include "opldialg.h"
#include "iodev.h"
#include "oplr.h"
#include "clckupdt.h"
#include <bafindf.h>
#else
#include <OplAPI.h>
#include <e32hal.h>
#include <e32uid.h>
#include <opcodes.h>
#include <module.h>
#include <oplcmd.h>
#include <opldb.h>
#include <eikon.hrh>
#include <apgwgnam.h>
#include "frame.h"
#include "graphics.h"
#include "oplutil.h"
#include <opldbg.h>
#include "opldialg.h"
#include "iodev.h"
#include "oplr.h"
#include "clckupdt.h"
#include <bafindf.h>
#include <cknctl.rsg>
#include <ckon.mbg>
#endif
#define KMin64HeapSize 0x1000
#define KMenuBarId 0x2000
#if defined(__SERIES60__)
#define KMenuPaneIdOffset R_AVKON_MENUPANE_FEP_DEFAULT
#elif defined(__UIQ__)
#define KMenuPaneIdOffset 0
#else
#define KMenuPaneIdOffset R_CKN_TASKS_MENUPANE_STUB
#endif
#if defined(__SERIES60__)
#define KCommandIdOffset 0x8000
#else
#define KCommandIdOffset 0x4000
#endif
#define KSizeMagicStatics 0x36
enum {ENumberOfOpcodesToRunBetweenEventChecks=150};
enum {EMaximumNumberOfCompletedEventsToHandlePerEventCheck=5};
GLREF_C void DebugPrintThreadHandles(const TDesC& aText);
_LIT(KOplRuntime, "OPL-runtime");
TInt COplRuntime::Execute()
{
// FLOGWRITE(_L("COplRuntime::Execute() starts."));
__ASSERT_DEBUG(iIOCollection->WsEventHandler().IsStarted(), User::Panic(KOplRuntime, 1));
TInt returnValue=0;
FOREVER
{
TRAPD(err,SequencerL());
if (!err) // sequencer exited with 0
break; // so exit runtime with no error
iErrorValue=err; // set value returned by ERR function
if (ErrorHandler())
{
returnValue=iErrorValue;
break;
}
}
__ASSERT_DEBUG(iIOCollection->WsEventHandler().IsStarted(), User::Panic(KOplRuntime, 2));
// Fix the E32User-CBase 46 Panic.
// Soak up any lingering event, it's too late for the sequencer to process it.
// FLOGWRITE(_L("COplRuntime::Execute() about to DoConsumeEvent()."));
IOCollection().WsEventHandler().DoConsumeEvent(*iCoeEnv);
// FLOGWRITE(_L("COplRuntime::Execute() exits."));
return returnValue;
}
typedef CDebuggerBase* (*TDebuggerEntryPointL)(CDebuggerAPI* aDebuggerAPI);
void COplRuntime::InitializeL(const TInt aFlags, const TModuleName aModuleName)
// sets the environment for execution
{
#if defined(__SERIES60__)
#pragma message("Need to fix the iOplAlertWin!!!")
// It's still using three-button alert, prolly not suitable for OSv6.1!
#else
iOplAlertWin=new(ELeave) COplAlertWin;
iOplAlertWin->ConstructL(iCoeEnv);
#endif
iDebuggerAPI=new(ELeave) CDebuggerAPI(this);
if (iCommandLine->TailEndCommand()==KOplrCommandRunFromDebugger)
{
CFindFileByType* findFile=new(ELeave)CFindFileByType(ConEnv()->FsSession());
CleanupStack::PushL(findFile);
if (findFile->FindFirst(DebuggerDllFilename(),KNullDesC,TUidType(KDynamicLibraryUid,KUidOplDebugger,KNullUid))==KErrNone)
{
User::LeaveIfError(iDebuggerLib.Load(findFile->File().FullName()));
TDebuggerEntryPointL func=(TDebuggerEntryPointL)iDebuggerLib.Lookup(1);
if (!func)
User::Leave(KErrBadLibraryEntryPoint);
iDebuggerBase=(*func)(iDebuggerAPI);
}
CleanupStack::PopAndDestroy(); // findFile
}
COplRuntime::iFlags = aFlags;
COplRuntime::iStack=CStack::NewL(4096,this);
iSeed=0x12345678;
iGlobTbl=new(ELeave) CGlobalsTbl;
TMemoryInfoV1Buf membuf;
UserHal::MemoryInfo(membuf);
TInt maxmem=membuf().iTotalRamInBytes;
SetHeap64(UserHeap::ChunkHeap(NULL,KMin64HeapSize,maxmem));
#ifdef _DEBUG
if (!iHeap64)
{
RDebug::Print(_L("*** Module '%S' is unable to alloc the ChunkHeap."),&aModuleName);
// Looking at defect EDNRANS-4J3K86
// Dump free RAM info.
RDebug::Print(_L("iTotalRamInBytes=0x%x"),maxmem);
RDebug::Print(_L("iMaxFreeRamInBytes=0x%x"),membuf().iMaxFreeRamInBytes);
RDebug::Print(_L("iFreeRamInBytes=0x%x"),membuf().iFreeRamInBytes);
}
#endif
User::LeaveIfNull(iHeap64);
iHeap64->AllocL(KSizeMagicStatics);
iDrawablesCollection = new(ELeave) CDrawablesCollection(ConEnv()->WsSession());
iDrawablesCollection->SetConsoleWinL(*this,iConsole);
#if !defined(__SERIES60__)
iClockUpdater=new(ELeave) COplClockUpdater(*iDrawablesCollection);
iClockUpdater->ConstructL();
#endif
iDbManager=COplDbManager::NewL(*this,*COplRuntime::iStack);
iOplAPI = new(ELeave) OplAPI(this,*iHeap64);
iModulesCollection = new(ELeave) CModulesCollection;
iModulesCollection->Init(ConEnv()->FsSession());
iModulesCollection->LoadModuleL(aModuleName);
TUid uid(iModulesCollection->Uid());
iCommandLine->SetAppUid(uid);
iEikonEnv->UpdateTaskNameL();
iFrame = new(ELeave) CFrame;
COplRuntime::iStack->Push(TInt16(0));
iFrame->ConstructL(*COplRuntime::iStack,*this,iModulesCollection->FindFirstProcedure());
iFrame->FinishConstructionL();
iCoeEnv->Cancel(); // cancel outstanding Ws Event
User::LeaveIfError(iCoeEnv->RootWin().AddPriorityKey(EKeyEscape,EAllStdModifiers,KKillKeyModifier));
User::LeaveIfError(iCoeEnv->RootWin().AddPriorityKey(CTRL('s'),EAllStdModifiers,KPauseKeyModifier));
User::LeaveIfError(iCoeEnv->RootWin().AddPriorityKey(CTRL('q'),EAllStdModifiers,KPauseKeyModifier));
ConEnv()->WsSession().ComputeMode(RWsSession::EPriorityControlComputeOn);
}
void COplRuntime::SequencerL()
{
CWsEventHandler& eventHandler=iIOCollection->WsEventHandler();
TRequestStatus& priorityKeyStatus=eventHandler.PriorityKeyStatus();
// Force HandleAnyCompletedEvents() to be called at least once, even for tiny .OPO files.
TInt opcodeCount=ENumberOfOpcodesToRunBetweenEventChecks;
FOREVER
{
TUint opcode=IP8();
#ifdef _HISTORY
if (iStateFlags&KHistoryEnabled)
{
if (opcode==0xff) ///// extended opcode
{
iHistory.WriteLog(256+IP8());
iIP.uint8--;
}
else
{
if (opcode==0x57)
{
iHistory.FuncWriteLog(IP8());
iIP.uint8--;
}
else
iHistory.WriteLog(opcode);
}
}
#endif // #define _HISTORY
// just to test escape
if (priorityKeyStatus!=KRequestPending)
{
User::WaitForRequest(priorityKeyStatus); // returns straightaway as priorityKeyStatus has already completed
eventHandler.HandlePriorityKeyCompletion();
}
if (opcodeCount<ENumberOfOpcodesToRunBetweenEventChecks)
{
++opcodeCount;
}
else
{
opcodeCount=0;
eventHandler.HandleAnyCompletedEvents(*iCoeEnv, EMaximumNumberOfCompletedEventsToHandlePerEventCheck);
}
if (eventHandler.IsSuspended()) // an line function, so very cheap to call
{
eventHandler.WaitWhileSuspended(*iCoeEnv);
opcodeCount=0;
}
// Main sequencer - good place for breakpoints
OpCode::OpCodeTable[opcode](*COplRuntime::iStack,*this,iFrame); // can leave
}
}
#if defined(__UIQ__)
void COplRuntime::PrepareToExit()
{
CQikAppUi::PrepareToExit();
}
#endif
#if !defined(__SERIES60__)
#if !defined(__UIQ__)
void COplRuntime::PrepareToExit()
{
CEikAppUi::PrepareToExit();
}
void COplRuntime::ActivateNextAppTopViewL()
{
TRuntimeParams params=iCommandLine->RuntimeParams();
TThreadId thisThread=params.iOwnerThreadId;
TInt prev=0;
RWsSession& ws=iEikonEnv->WsSession();
TInt windowGroup=ws.FindWindowGroupIdentifier(prev,thisThread);
CApaWindowGroupName* wgName=CApaWindowGroupName::NewLC(ws,windowGroup);
TVwsViewId viewId(wgName->AppUid(),KNullUid);
CleanupStack::PopAndDestroy(wgName);
// Will leave with KErrNotSupported from LOAK21 (since ViewSrv was removed)
TRAPD(ignore,ActivateViewL(viewId));
}
COplRuntime::~COplRuntime()
{
delete iStartUp;
delete iOplAlertWin;
delete iCommandLine;
delete iCurrentDocumentName;
while (iFrame!=NULL)
delete iFrame;
delete this->iStack;
delete iGlobTbl;
DeleteMenu(); // Must be done before deleting the console (or any control that can gain focus)
delete iDrawablesCollection;
delete iConsole;
delete iModulesCollection;
delete iDbManager;
delete iIOCollection;
delete iOplAPI;
delete iOplDialog;
delete iDebuggerBase;
iDebuggerLib.Close();
delete iDebuggerAPI;
iDir.Close();
iCoeEnv->DeleteResourceFile(iResourceFile);
delete iClockUpdater;
if (iHelpContextNamesArray)
{
iHelpContextNamesArray->Reset();
delete iHelpContextNamesArray;
}
#ifdef _HISTORY
iHistory.Close();
#endif
if (iHeap64)
iHeap64->Close();
#ifdef _DEBUG
DebugPrintThreadHandles(_L("COplRuntime::~COplRuntime()"));
#endif
}
#endif
#endif
TUint32 COplRuntime::IP32()
{
return OplUtil::GetLong(iIP.uint32++);
}
TUint16 COplRuntime::IP16()
{
return OplUtil::GetWord(iIP.uint16++);
}
TReal COplRuntime::IPReal()
{
// GCC compiler flag
#if defined(__DOUBLE_WORDS_SWAPPED__)
union
{
TUint32 uint32[2];
TReal flt;
};
uint32[1]=OplUtil::GetLong(iIP.uint32++);
uint32[0]=OplUtil::GetLong(iIP.uint32++);
return flt;
#else
return OplUtil::GetFloat(iIP.real++);
#endif
}
void COplRuntime::DoGoto()
{
iIP.uint8+=OplUtil::GetWord(iIP.int16);
iIP.uint8--; // avoid -32768-1 overflow
}
void COplRuntime::SetTrap()
{
iTrap=ETrue;
iErrorValue=KErrNone;
}
//void COplRuntime::FlushSignals()
// {
// iIOSponge->Flush();
//
// // redraw cursor if enabled
// Console().DrawCursor(Console().CurrentPos());
// DrawablesCollection().DrawCursorIfOn();
//
// ConEnv()->WsSession().Flush();
// // flush the wserv buffer(removes menu/dialog windows)
// }
class COplMenuBar : public CEikMenuBar
{
public:
void GetHelpContext(TCoeHelpContext& aContext) const;
};
void COplMenuBar::GetHelpContext(TCoeHelpContext& aContext) const
{
/* If this dialog is being displayed by Uikon and the user hits the Help key then
* Cone's CCoeAppUi calls GetHelpContext() for each control on the control stack.
* So, have to return the help context for this control (if the OPL author has
* set one using SetHelp control%,context$) or null.
*
* If the author has set one, it'll be in the dialog'th element of the help context
* array iHelpContextNamesArray.
*/
COplRuntime* rt=TheRuntime(); // expensive call, so cache it here.
TFixedArray<TCoeContextName,KOplLenContextNamesArray>* helpContext=rt->HelpContextNamesArray();
if (helpContext)
{
TCoeContextName context=helpContext->At(EOplHelpMenu);
TUid helpUid=rt->HelpUid();
if (context.Length() && helpUid!=KNullUid)
{
aContext=TCoeHelpContext(helpUid,context);
}
}
}
/*
* Menu stuff
*
Menu's under OPL:
OpCode::mInit // mINIT
CloseMenu() Delete any currently existing menu vars.
PrepareForMenuL() Creates a new COplMenuBar and constructs it.
Create the Task list pane for Crystal.
Creates the Profiles pane for Crystal.
OpCode::mCasc // mCASC
...
OpCode::mCard // mCARD
Add the menu item pairs of hotkey, string to the menu items array, using AddMenuItemL()
Adds the pane title (+icons if mCARDX) using AddMenuTitleL()
MENU
Execute the menu by calling DisplayMenuL(0,0) then kick off the active scheduler.
For the task pane, a dummy card with null string is added. The title card id offset
used is R_CKN_TASKS_MENUPANE_STUB.
*/
void COplRuntime::CloseMenu()
{
RemoveFromStack(iEikonEnv->AppUiFactory()->MenuBar());
DeleteMenu();
}
void COplRuntime::DeleteMenu()
{ // Can be safely called from UIKON dtor, as iAppUiFactoryArray killed before CEikonEnv::DestroyEnvironment() called.
if (iOplMenuBar)
{
delete iOplMenuBar;
iOplMenuBar=NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -