--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbservers/hbthemeserver/hbthemeserverapplication.cpp Fri May 14 16:09:54 2010 +0300
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbServers module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+#include "hbthemeserverapplication_p.h"
+#include "hbthemeserver_p.h"
+#include "hbthemecommon_p.h"
+#include "hbtheme.h"
+
+#include <QWindowsStyle>
+#include <QLibrary>
+#include <QDebug>
+
+#if defined (Q_OS_SYMBIAN)
+#include "hbthemecommon_symbian_p.h"
+#include <eikenv.h>
+#include <apgwgnam.h>
+#endif
+
+static const QLatin1String APP_NAME("HbThemeServer");
+static const QLatin1String RESOURCE_LIB_NAME("HbCore");
+static const QLatin1String TEST_RESOURCE_LIB_NAME("HbTestResources");
+static const QLatin1String WIN32_DEBUG_SUFFIX("d");
+static const QLatin1String MAC_DEBUG_SUFFIX("_debug");
+static const QLatin1String STOP_MESSAGE("stop");
+
+bool HbThemeServerApplication::Options::help = false;
+bool HbThemeServerApplication::Options::start = false;
+bool HbThemeServerApplication::Options::stop = false;
+bool HbThemeServerApplication::Options::persistent = false;
+QString HbThemeServerApplication::Options::error = QString();
+
+HbThemeServerApplication::HbThemeServerApplication(int &argc, char *argv[]) :
+ QtSingleApplication(argc, argv), server(0)
+{
+ setApplicationName(APP_NAME);
+
+#ifdef QT_DEBUG
+ //temporary solution until Hb specific style is ready
+ setStyle(new QWindowsStyle);
+#endif // QT_DEBUG
+
+#if QT_VERSION >= 0x040601
+ setAttribute(Qt::AA_S60DontConstructApplicationPanes);
+#endif // QT_VERSION
+
+ // ignore command line arguments on Symbian
+#ifdef Q_OS_SYMBIAN
+ Options::start = true;
+ Options::persistent = true;
+#else
+ QStringList args = arguments();
+ args.removeFirst(); // ignore argv0
+ const bool wasEmpty = args.isEmpty();
+ const bool restart = args.removeAll(QLatin1String("-restart"));
+ Options::start = args.removeAll(QLatin1String("-start")) || restart;
+ Options::stop = args.removeAll(QLatin1String("-stop")) || restart;
+ Options::persistent = args.removeAll(QLatin1String("-persistent"));
+ Options::help = args.removeAll(QLatin1String("-help")) || args.removeAll(QLatin1String("-h")) || !args.isEmpty() || wasEmpty;
+ if (!args.isEmpty()) {
+ Options::error = tr("Unknown option(s): '%1'").arg(args.join(QLatin1String(" ")));
+ }
+#endif // Q_OS_SYMBIAN
+}
+
+HbThemeServerApplication::~HbThemeServerApplication()
+{
+ delete server;
+}
+
+bool HbThemeServerApplication::initialize()
+{
+#if defined (Q_OS_SYMBIAN)
+ CEikonEnv * env = CEikonEnv::Static();
+ if ( env ) {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(env->WsSession());
+ env->RootWin().SetOrdinalPosition(0, ECoeWinPriorityNeverAtFront); // avoid coming to foreground
+ wgName->SetHidden(ETrue); // hides us from FSW and protects us from OOM FW etc.
+ wgName->SetSystem(ETrue); // Allow only application with PowerManagement cap to shut us down
+ wgName->SetCaptionL(_L("HbThemeServer")); // TODO: use QCoreApplication::applicationName()
+ wgName->SetAppUid(KNullUid);
+ wgName->SetWindowGroupName(env->RootWin());
+ CleanupStack::PopAndDestroy();
+ RThread::RenameMe(_L("HbThemeServer")); // TODO: use QCoreApplication::applicationName()
+ }
+#endif
+
+ // as for theme initialization, an instance needs to be created before starting the server
+ HbTheme::instance();
+
+ // load resource libraries in order to make binary resources accessible
+ bool result = loadLibrary(RESOURCE_LIB_NAME);
+#ifdef HB_DEVELOPER
+ loadLibrary(TEST_RESOURCE_LIB_NAME);
+#endif
+ return result;
+}
+
+int HbThemeServerApplication::exec()
+{
+ if (!server) {
+ server = new HbThemeServer;
+ }
+
+ if (server->startServer()) {
+#if !defined(Q_OS_SYMBIAN) && defined(QT_DEBUG)
+ server->showMinimized();
+#endif
+ return QtSingleApplication::exec();
+ }
+
+ return EXIT_FAILURE;
+}
+
+void HbThemeServerApplication::stop()
+{
+#ifndef Q_OS_SYMBIAN
+ sendMessage(STOP_MESSAGE);
+#endif // Q_OS_SYMBIAN
+}
+
+bool HbThemeServerApplication::loadLibrary(const QString &name)
+{
+ // To load resources embedded in hb library
+ QLibrary library(name);
+ bool result = library.load();
+
+ if (!result) {
+ // Library may not be loaded, if it was built in debug mode and the name in debug mode is
+ // different, change the name to debug version in that scenario
+ QString alternateName = name;
+#ifdef Q_OS_WIN32
+ alternateName += WIN32_DEBUG_SUFFIX;
+#elif defined(Q_OS_MAC)
+ alternateName += MAC_DEBUG_SUFFIX;
+#endif
+ // On symbian library name in debug mode is same as that in release mode,
+ // so no need to do anything for that
+ library.setFileName(alternateName);
+ result = library.load();
+ }
+#ifdef THEME_SERVER_TRACES
+ if (result) {
+ qDebug() << "HbThemeServerApplication::loadLibrary(): loaded library " << name;
+ }
+ else {
+ qDebug() << "HbThemeServerApplication::loadLibrary(): could not load library " << name;
+ }
+#endif // THEME_SERVER_TRACES
+
+ return result;
+}
+
+void HbThemeServerApplication::receiveMessage(const QString &message)
+{
+ if (!server)
+ return;
+
+ if (message == STOP_MESSAGE) {
+ server->stopServer();
+ quit();
+ }
+}
+
+bool HbThemeServerApplication::acquireLock() {
+#ifdef Q_OS_SYMBIAN
+ // Guard against starting multiple copies of the server
+ Lock lock;
+ Lock::State lockState;
+ for(;;) {
+ lockState = lock.acquire();
+ if (lockState == Lock::Acquired) {
+ break;
+ } else if (lockState == Lock::Reserved) {
+ // Process may be starting, wait for server object to be created
+ if (Lock::serverExists()) {
+#ifdef THEME_SERVER_TRACES
+ qDebug() << "HbThemeServer::main: serverExists!!!";
+#endif
+ break;
+ } else {
+ const TInt KTimeout = 100000; // 100 ms
+ User::After(KTimeout);
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (lockState != Lock::Acquired) {
+ // With KErrAlreadyExists client should try to connect, otherwise bail out.
+#ifdef THEME_SERVER_TRACES
+ qDebug() << "HbThemeServer::main: Lock not acquired!!!";
+#endif
+ RProcess::Rendezvous(lockState == Lock::Reserved ? KErrAlreadyExists : KErrGeneral);
+ }
+
+ return (lockState == Lock::Acquired);
+#else
+ return true;
+#endif
+
+
+}
+
+
+#ifdef Q_OS_SYMBIAN
+Lock::Lock()
+{
+ // Using a file for interprocess lock
+ const int NumMessageSlots = 1;
+ if (mFs.Connect(NumMessageSlots) == KErrNone) {
+ mFs.CreatePrivatePath(EDriveC);
+ if (mFs.SetSessionToPrivate(EDriveC) == KErrNone) {
+ _LIT(KFileName, "lockFile");
+ const TUint mode = EFileShareReadersOrWriters;
+ if (mFile.Create(mFs, KFileName, mode) == KErrAlreadyExists) {
+ mFile.Open(mFs, KFileName, mode);
+ }
+ }
+ }
+}
+
+// Try to acquire lock
+Lock::State Lock::acquire()
+{
+ State state = Error;
+ // If process holding the lock crashes, file server releases the lock
+ if (mFile.SubSessionHandle()) {
+ TInt error = mFile.Lock(0, 1);
+ if (error == KErrNone) {
+ state = Acquired;
+ } else if (error == KErrLocked) {
+ state = Reserved;
+ }
+ }
+ return state;
+}
+
+// Check if Symbian server exists
+bool Lock::serverExists()
+{
+ TFindServer findHbServer(KThemeServerName);
+ TFullName name;
+ return findHbServer.Next(name) == KErrNone;
+}
+
+#endif