main_epoc_qt.cpp

Go to the documentation of this file.
00001 // Defines a main function for running CL2 standalone, without being
00002 // attached to any application.
00003 // 
00004 // It is difficult to get init and cleanup right in such a way that
00005 // QtCoreApplication is happy, and some of the code here closely
00006 // mirrors code in Qt's s60main.
00007 
00008 #include <exception> // for uncaught exception (keep this first)
00009 
00010 #include "application_config.h"
00011 #include "ac_app_context_private.h"
00012 #include "kr_controller.h"
00013 #include "client-run.h"
00014 #include "epoc-ao-gerror.hpp"
00015 #include "er_errors.h"
00016 
00017 #include "common/utilities.h"
00018 
00019 #include <e32std.h>
00020 #include <e32base.h>
00021 
00022 #include <estlib.h> // __crt0
00023 
00024 #include <QtCore/QCoreApplication>
00025 #include <QtGlobal>
00026 #include <QTimer>
00027 
00028 #include <stdlib.h> // abort
00029 
00030 // Immediate process exit.
00031 extern "C" void ExitApplication()
00032 {
00033   logt("ExitApplication");
00034   User::Exit(KErrGeneral);
00035 }
00036 
00037 // Orderly shutdown. This is only done via a Lua binding, and there it
00038 // is useful to be able to send a response before exiting, hence a
00039 // proper shutdown.
00040 extern "C" void ShutdownApplication()
00041 {
00042   logt("ShutdownApplication");
00043   QCoreApplication::quit();
00044 }
00045 
00046 NONSHARABLE_CLASS(CMainObj) : 
00047   public CBase,
00048   public MAppContextInitObserver
00049 {
00050  public:
00051   static CMainObj* NewL();
00052   ~CMainObj();
00053  private:
00054   void ConstructL();
00055  private: // MAppContextInitObserver
00056   void AppContextReady(TInt aError);
00057  private:
00058   kr_Controller* controller;
00059 };
00060 
00061 CMainObj* CMainObj::NewL()
00062 {
00063   CMainObj* obj = new (ELeave) CMainObj;
00064   CleanupStack::PushL(obj);
00065   obj->ConstructL();
00066   CleanupStack::Pop(obj);
00067   return obj;
00068 }
00069 
00070 CMainObj::~CMainObj()
00071 {
00072   if (controller) {
00073     logt("destroying controller");
00074     kr_Controller_destroy(controller);
00075     logt("controller destroyed");
00076   }
00077 }
00078 
00079 void CMainObj::ConstructL()
00080 {
00081   // Invokes AppContextReady upon completion.
00082   ac_AppContext_PlatInitAsyncL(ac_get_global_AppContext(), *this);
00083 }
00084 
00085 void CMainObj::AppContextReady(TInt aError)
00086 {
00087   logt("app context ready");
00088 
00089   if (aError) {
00090     er_log_symbian(er_FATAL, aError, "error in app ctx async init");
00091     return; // not reached
00092   }
00093 
00094   GError* localError = NULL;
00095 
00096   controller = kr_Controller_new(&localError);
00097   if (!controller) {
00098     er_log_gerror(er_FATAL|er_FREE, localError, "error in controller creation");
00099     return; // not reached
00100   }
00101     
00102   if (!kr_Controller_start(controller, &localError)) {
00103     er_log_gerror(er_FATAL|er_FREE, localError, "error starting controller");
00104     return; // not reached
00105   }
00106 }
00107 
00108 // May throw exceptions, but not leave.
00109 static TInt QtMainE(int argc, char *argv[], char *envp[])
00110 {
00111   // This seems a fairly heavy-duty class. It may be unsafe to try to
00112   // do anything really after it gets destroyed. Hence we complete
00113   // cleanup for CL2 engine before letting it fall out of scope.
00114   QCoreApplication app(argc, argv);
00115   
00116   TInt errCode = 0;
00117   CMainObj* mainObj = NULL;
00118 
00119   // Creates application context.
00120   errCode = cl2GlobalInit();
00121   if (errCode) {
00122     logt("error in global init");
00123     goto gifail;
00124   }
00125 
00126   logg("compiled against Qt %s", QT_VERSION_STR);
00127   logg("running with Qt %s", qVersion());
00128 
00129   logg("argc is %d", argc);
00130   for (int i=0; i<argc; i++)
00131     logg("arg %d is '%s'", i, argv[i]);
00132 
00133   // Handles async initialization tasks. If and when those complete,
00134   // the controller is created and set up with things to do.
00135   TRAP(errCode, mainObj = CMainObj::NewL());
00136   if (errCode) {
00137     logt("error creating main object");
00138     goto mofail;
00139   }
00140 
00141   // This invokation actually runs the controller in an event loop.
00142   try {
00143     errCode = qApp->exec();
00144     logg("qApp->exec() returned with %d", errCode);
00145   } catch (const std::exception &ex) {
00146     logg("Qt error exception: %s", ex.what());
00147     errCode = qt_symbian_exception2Error(ex);
00148   }
00149 
00150   // Deletes controller.
00151   delete mainObj;
00152 
00153  mofail:
00154   // Deletes application context.
00155   cl2GlobalCleanup();
00156 
00157  gifail:
00158   logg("exit code %d", errCode);
00159   return errCode;
00160 }
00161 
00162 static TInt QtMainWrapper()
00163 {
00164   // These must persist for as long as QCoreApplication does.
00165   int argc = 0;
00166   char **argv = 0;
00167   char **envp = 0;
00168   __crt0(argc, argv, envp);
00169   TRAPD(errCode, QT_TRYCATCH_LEAVING(errCode = QtMainE(argc, argv, envp);));
00170   delete[] argv;
00171   delete[] envp;
00172   return errCode;
00173 }
00174 
00175 GLDEF_C TInt E32Main()
00176 {
00177   CTrapCleanup *cleanupStack = q_check_ptr(CTrapCleanup::New());
00178   TRAPD(errCode, errCode = QtMainWrapper());
00179   delete cleanupStack;
00180   return errCode;
00181 }
00182 
00183 /**
00184 
00185 Copyright 2009 Helsinki Institute for Information Technology (HIIT)
00186 and the authors. All rights reserved.
00187 
00188 Authors: Tero Hasu <tero.hasu@hut.fi>
00189 
00190 Permission is hereby granted, free of charge, to any person
00191 obtaining a copy of this software and associated documentation files
00192 (the "Software"), to deal in the Software without restriction,
00193 including without limitation the rights to use, copy, modify, merge,
00194 publish, distribute, sublicense, and/or sell copies of the Software,
00195 and to permit persons to whom the Software is furnished to do so,
00196 subject to the following conditions:
00197 
00198 The above copyright notice and this permission notice shall be
00199 included in all copies or substantial portions of the Software.
00200 
00201 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00202 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00203 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00204 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00205 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00206 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00207 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00208 SOFTWARE.
00209 
00210  **/

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1