src/hbservers/hbthemeserver/main.cpp
changeset 2 06ff229162e9
parent 1 f7ac710697a9
child 3 11d3954df52a
equal deleted inserted replaced
1:f7ac710697a9 2:06ff229162e9
    21 ** If you have questions regarding the use of this file, please contact
    21 ** If you have questions regarding the use of this file, please contact
    22 ** Nokia at developer.feedback@nokia.com.
    22 ** Nokia at developer.feedback@nokia.com.
    23 **
    23 **
    24 ****************************************************************************/
    24 ****************************************************************************/
    25 
    25 
    26 #include <QApplication>
    26 #include "hbthemeserverapplication_p.h"
    27 #include <QLibrary>
    27 #include <QTextStream>
    28 #include <QDebug>
    28 #include <cstdlib>
    29 
    29 
    30 #include "hbthemeserver_p.h"
    30 void showHelp(const QString &argv0, const QString &error = QString())
    31 #include "hbthemecommon_p.h"
       
    32 #include "hbtheme.h"
       
    33 #if defined (Q_OS_SYMBIAN)
       
    34 #include "hbthemecommon_symbian_p.h"
       
    35 #include <eikenv.h>
       
    36 #include <apgwgnam.h>
       
    37 #endif
       
    38 #include <qtsingleapplication.h>
       
    39 #include <QWindowsStyle>
       
    40 
       
    41 static const QLatin1String RESOURCE_LIB_NAME("HbCore");
       
    42 static const QLatin1String TEST_RESOURCE_LIB_NAME("HbTestResources");
       
    43 static const QLatin1String WIN32_DEBUG_SUFFIX("d");
       
    44 static const QLatin1String MAC_DEBUG_SUFFIX("_debug");
       
    45 
       
    46 #ifdef Q_OS_SYMBIAN
       
    47 class Lock
       
    48 {
    31 {
    49 public:
    32     QTextStream qerr(stderr);
    50     enum State {
    33     qerr << "Hb Theme Server" << endl;
    51         Reserved,
    34     if (!error.isEmpty()) {
    52         Acquired,
    35         qerr << argv0 << ": " << error << endl;
    53         Error
       
    54     };
       
    55     Lock();
       
    56     ~Lock(){close();}
       
    57     void close(){mFile.Close(); mFs.Close();}
       
    58     State acquire();
       
    59     static bool serverExists();
       
    60 
       
    61 private:
       
    62     RFs mFs;
       
    63     RFile mFile;
       
    64 };
       
    65 
       
    66 Lock::Lock()
       
    67 {
       
    68     // Using a file for interprocess lock
       
    69     const int NumMessageSlots = 1;
       
    70     if (mFs.Connect(NumMessageSlots) == KErrNone) {
       
    71         mFs.CreatePrivatePath(EDriveC);
       
    72         if (mFs.SetSessionToPrivate(EDriveC) == KErrNone) {
       
    73             _LIT(KFileName, "lockFile");
       
    74             const TUint mode = EFileShareReadersOrWriters;
       
    75             if (mFile.Create(mFs, KFileName, mode) == KErrAlreadyExists) {
       
    76                 mFile.Open(mFs, KFileName, mode);
       
    77             }
       
    78         }
       
    79     }
    36     }
    80 }
    37     qerr << "Usage: " << argv0 << " [options]" << endl;
    81 
    38     qerr << endl;
    82 // Try to acquire lock
    39     qerr << "Options:" << endl;
    83 Lock::State Lock::acquire()
    40     qerr << "  -start               start a new server" << endl;
    84 {
    41     qerr << "  -restart             same as -stop -start" << endl;
    85     State state = Error;
    42     qerr << "  -stop                stop an existing server instance" << endl;
    86     // If process holding the lock crashes, file server releases the lock
    43     qerr << "  -persistent          keep server running when the last client disconnects" << endl;
    87     if (mFile.SubSessionHandle()) {
    44     qerr << "  -h, -help            display this information" << endl;
    88         TInt error = mFile.Lock(0, 1);
       
    89         if (error == KErrNone) {
       
    90             state = Acquired;
       
    91         } else if (error == KErrLocked) {
       
    92             state = Reserved;
       
    93         }
       
    94     }
       
    95     return state;
       
    96 }
       
    97 
       
    98 // Check if Symbian server exists
       
    99 bool Lock::serverExists()
       
   100 {
       
   101     TFindServer findHbServer(KThemeServerName);
       
   102     TFullName name;
       
   103     return findHbServer.Next(name) == KErrNone;
       
   104 }
       
   105 
       
   106 #endif
       
   107 /* 
       
   108     This function loads library which keeps resources of default theme
       
   109 */
       
   110 bool loadResourceLibrary(QString resourceLibName)
       
   111 {
       
   112     bool loadSuccess;
       
   113     // To load resources embedded in hb library
       
   114     QLibrary hbLib(resourceLibName);
       
   115     loadSuccess = hbLib.load();
       
   116     
       
   117     if ( !loadSuccess ) {
       
   118         // Library may not be loaded, if it was built in debug mode and the name in debug mode is
       
   119         // different, change the name to debug version in that scenario
       
   120 #ifdef Q_OS_WIN32
       
   121         resourceLibName += WIN32_DEBUG_SUFFIX;
       
   122 #elif defined(Q_OS_MAC)
       
   123         resourceLibName += MAC_DEBUG_SUFFIX;
       
   124 #endif
       
   125         // On symbian library name in debug mode is same as that in release mode,
       
   126         // so no need to do anything for that
       
   127         hbLib.setFileName(resourceLibName);
       
   128         loadSuccess = hbLib.load();
       
   129     }
       
   130 #ifdef THEME_SERVER_TRACES
       
   131     if (loadSuccess) {
       
   132         qDebug() << "Loaded library " << resourceLibName;
       
   133     }
       
   134     else {
       
   135         qDebug() << "Could not load library " << resourceLibName;
       
   136     }
       
   137 #endif // THEME_SERVER_TRACES
       
   138 
       
   139     return loadSuccess;
       
   140 }
    45 }
   141 
    46 
   142 int main(int argc, char *argv[])
    47 int main(int argc, char *argv[])
   143 {
    48 {
   144 #ifdef QT_DEBUG
    49     if(!HbThemeServerApplication::acquireLock()) {
   145     //temporary solution until Hb specific style is ready
       
   146     QApplication::setStyle( new QWindowsStyle );
       
   147 #endif // QT_DEBUG
       
   148 #if QT_VERSION >= 0x040601
       
   149     QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes);
       
   150 #endif // QT_VERSION
       
   151 #ifdef THEME_SERVER_TRACES
       
   152         qDebug() << "HbThemeServer::main: START!!!";
       
   153 #endif
       
   154 #ifdef Q_OS_SYMBIAN
       
   155     // Guard against starting multiple copies of the server
       
   156     Lock lock;
       
   157     Lock::State lockState;
       
   158     for(;;) {
       
   159         lockState = lock.acquire();
       
   160         if (lockState == Lock::Acquired) {
       
   161             break;
       
   162         } else if (lockState == Lock::Reserved) {
       
   163             // Process may be starting, wait for server object to be created
       
   164             if (Lock::serverExists()) {
       
   165 #ifdef THEME_SERVER_TRACES
       
   166         qDebug() << "HbThemeServer::main: serverExists!!!";
       
   167 #endif
       
   168                 break;
       
   169             } else {
       
   170                 const TInt KTimeout = 100000; // 100 ms
       
   171                 User::After(KTimeout);
       
   172             }
       
   173         } else {
       
   174             break;
       
   175         }
       
   176     }
       
   177     if (lockState != Lock::Acquired) {
       
   178         // With KErrAlreadyExists client should try to connect, otherwise bail out.
       
   179 #ifdef THEME_SERVER_TRACES
       
   180         qDebug() << "HbThemeServer::main: Lock not acquired!!!";
       
   181 #endif
       
   182         RProcess::Rendezvous(lockState == Lock::Reserved ? KErrAlreadyExists:KErrGeneral);
       
   183         return KErrNone;
       
   184     }
       
   185 #endif // Q_OS_SYMBIAN
       
   186 #ifdef THEME_SERVER_TRACES
       
   187         qDebug() << "HbThemeServer::main: start construction QtSingleApplication!!!";
       
   188 #endif
       
   189     QtSingleApplication  app(argc, argv );
       
   190 
       
   191     if (app.isRunning()) {
       
   192 #ifdef THEME_SERVER_TRACES
       
   193         qDebug() << "HbThemeServer::main: first instance already running!!!";
       
   194 #endif
       
   195         return 0;
    50         return 0;
   196     }
    51     }
       
    52     
       
    53     HbThemeServerApplication app(argc, argv);
   197 
    54 
   198 #ifdef THEME_SERVER_TRACES
    55     if (HbThemeServerApplication::Options::help) {
   199     qDebug() << "HbThemeServer::main: I'm first instance!!!";
    56         showHelp(argv[0], HbThemeServerApplication::Options::error);
   200 #endif
    57         return EXIT_SUCCESS;
   201         
       
   202 #if defined (Q_OS_SYMBIAN)
       
   203     CEikonEnv * env = CEikonEnv::Static();
       
   204     if ( env ) {
       
   205         CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(env->WsSession());
       
   206         env->RootWin().SetOrdinalPosition(0, ECoeWinPriorityNeverAtFront); // avoid coming to foreground
       
   207         wgName->SetHidden(ETrue); // hides us from FSW and protects us from OOM FW etc.
       
   208         wgName->SetSystem(ETrue); // Allow only application with PowerManagement cap to shut us down    
       
   209         wgName->SetCaptionL(_L("HbThemeServer"));
       
   210         wgName->SetAppUid(KNullUid);
       
   211         wgName->SetWindowGroupName(env->RootWin());
       
   212         CleanupStack::PopAndDestroy();
       
   213         RThread::RenameMe(_L("HbThemeServer"));
       
   214     }
    58     }
   215 #endif
       
   216     HbTheme::instance(); //for theme initialization, instance needs to be created before starting the server.
       
   217     loadResourceLibrary(RESOURCE_LIB_NAME);
       
   218 #ifdef HB_DEVELOPER
       
   219     loadResourceLibrary(TEST_RESOURCE_LIB_NAME);
       
   220 #endif
       
   221 
    59 
   222     HbThemeServer server;
    60     if (HbThemeServerApplication::Options::stop) {
       
    61         app.stop();
       
    62     }
   223 
    63 
   224     bool success = server.startServer();
    64     if (app.isRunning() || !HbThemeServerApplication::Options::start) {
   225     
    65         return EXIT_SUCCESS;
   226     if ( !success ) {
       
   227 #ifdef THEME_SERVER_TRACES
       
   228         qDebug() << "HbThemeServer::main: server not started!!!";
       
   229 #endif
       
   230         return -1;
       
   231     }
    66     }
   232     
       
   233 #ifdef THEME_SERVER_TRACES
       
   234     qDebug() << "HbThemeServer::main: server started!!!";
       
   235 #endif
       
   236 
    67 
   237 #ifndef Q_OS_SYMBIAN
    68     if (app.initialize()) {
   238 #ifdef QT_DEBUG
    69         return app.exec();
   239     server.showMinimized();
    70     }
   240 #endif
       
   241 #endif // Q_OS_SYMBIAN
       
   242 
    71 
   243     int result = app.exec();
    72     return EXIT_FAILURE;
   244 #ifdef THEME_SERVER_TRACES
       
   245         qDebug() << "HbThemeServer::main: out from exec, with result code: " << result;
       
   246 #endif
       
   247     return result; 
       
   248 }
    73 }