Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

main.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2003 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #define QTOPIA_INTERNAL_INITAPP
00022 #include "dropins.h"
00023 
00024 /* OPIE */
00025 #include <opie2/odebug.h>
00026 #include <opie2/oapplication.h>
00027 
00028 /* QT */
00029 #include <qpainter.h>
00030 #include <qstrlist.h>
00031 #include <qtimer.h>
00032 #include <qguardedptr.h>
00033 #include <qcopchannel_qws.h>
00034 
00035 #ifdef private
00036 #       undef  private
00037 #endif
00038 #define private public
00039 #include <qtopia/qpeapplication.h>
00040 #undef private
00041 
00042 /* STD */
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <sys/types.h>
00046 #include <sys/stat.h>
00047 
00048 #ifdef _OS_LINUX_
00049 #include <sys/prctl.h>
00050 #ifndef PR_SET_NAME
00051 #define PR_SET_NAME 15
00052 #endif
00053 #endif
00054 
00055 #include <unistd.h>
00056 
00057 
00058 using QuickPrivate::PluginLoader;
00059 
00060 static QPEApplication *app = 0;
00061 static PluginLoader *loader = 0;
00062 static ApplicationInterface *appIface = 0;
00063 static QGuardedPtr<QWidget> mainWindow;
00064 
00065 #ifdef _OS_LINUX_
00066 static char **argv0 = 0;
00067 static int argv_lth;
00068 extern char **environ;
00069 #ifndef SPT_BUFSIZE
00070 #define SPT_BUFSIZE     2048
00071 #endif
00072 #include <stdarg.h>
00073 void setproctitle (const char *fmt,...) {
00074     int        i;
00075     char       buf[SPT_BUFSIZE];
00076     va_list    ap;
00077 
00078     if (!argv0)
00079         return;
00080 
00081     va_start(ap, fmt);
00082     (void) vsnprintf(buf, SPT_BUFSIZE, fmt, ap);
00083     va_end(ap);
00084 
00085     i = strlen (buf);
00086     if (i > argv_lth - 2) {
00087         i = argv_lth - 2;
00088         buf[i] = '\0';
00089     }
00090 
00091     memset(argv0[0], '\0', argv_lth);       /* clear the memory area */
00092     (void) strcpy (argv0[0], buf);
00093 
00094     argv0[1] = NULL;
00095 }
00096 #endif
00097 
00098 
00099 class QuickLauncher : public QObject
00100 {
00101     Q_OBJECT
00102 public:
00103     QuickLauncher() : QObject()
00104     {
00105         QCString ch("QPE/QuickLauncher-");
00106         ch += QString::number(getpid());
00107         qlChannel = new QCopChannel( ch, this);
00108         connect( qlChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00109                  this, SLOT(message(const QCString&,const QByteArray&)) );
00110     }
00111 
00112     static void exec( int /*argc*/, char **argv )
00113     {
00114         QString appName = argv[0];
00115         int sep = appName.findRev( '/' );
00116         if ( sep > 0 )
00117             appName = appName.mid( sep+1 );
00118 
00119         appIface = 0;
00120         if ( ! ( loader->queryInterface(appName, IID_QtopiaApplication, (QUnknownInterface**)&appIface) == QS_OK ) ) {
00121             exit(-1);
00122         }
00123 
00124         mainWindow = appIface->createMainWindow( appName );
00125 
00126         if ( mainWindow ) {
00127             if ( mainWindow->metaObject()->slotNames().contains("setDocument(const QString&)") ) {
00128                 app->showMainDocumentWidget( mainWindow );
00129             } else {
00130                 app->showMainWidget( mainWindow );
00131             }
00132         } else {
00133             owarn << "Could not create application main window" << oendl;
00134             exit(-1);
00135         }
00136     }
00137 
00138 private slots:
00139     void message(const QCString &msg, const QByteArray & data)
00140     {
00141         QStrList argList;
00142 
00143         if ( msg == "execute(QStrList)" ) {
00144             delete qlChannel;
00145             QDataStream stream( data, IO_ReadOnly );
00146             QStrList argList;
00147             stream >> argList;
00148             odebug << "QuickLauncher execute: " << argList.at(0) << oendl;
00149             doQuickLaunch( argList );
00150             delete this;
00151         } else if ( msg == "execute(QString)" ) {
00152             delete qlChannel;
00153             QDataStream stream( data, IO_ReadOnly );
00154             QString arg;
00155             stream >> arg;
00156             odebug << "QuickLauncher execute: " << arg << oendl;
00157             QStrList argList;
00158             argList.append( arg.utf8() );
00159             doQuickLaunch( argList );
00160             delete this;
00161         }
00162     }
00163 
00164 private:
00165     void doQuickLaunch( QStrList &argList )
00166     {
00167         static int myargc = argList.count();
00168         static char **myargv = new char *[myargc + 1];
00169 
00170         for ( int j = 0; j < myargc; j++ ) {
00171             myargv[j] = new char [strlen(argList.at(j))+1];
00172             strcpy( myargv[j], argList.at(j) );
00173         }
00174 
00175         myargv[myargc] = NULL;
00176 #ifdef _OS_LINUX_
00177         // Change name of process
00178         setproctitle(myargv[0]);
00179         prctl( PR_SET_NAME, (unsigned long)myargv[0], 0, 0, 0 );
00180 #endif
00181 
00182         connect(app, SIGNAL(lastWindowClosed()), app, SLOT(hideOrQuit()));
00183         app->exit_loop();
00184         app->initApp( myargc, myargv );
00185         exec( myargc, myargv );
00186     }
00187 
00188 private:
00189     QCopChannel *qlChannel;
00190 };
00191 
00192 int main( int argc, char** argv )
00193 {
00194     app = new Opie::Core::OApplication( argc, argv );
00195 
00196     loader = new PluginLoader( "application" );
00197 
00198     unsetenv( "LD_BIND_NOW" );
00199 
00200     QCString arg0 = argv[0];
00201     int sep = arg0.findRev( '/' );
00202 
00203     if ( sep > 0 )
00204         arg0 = arg0.mid( sep+1 );
00205 
00206     if ( arg0 != "quicklauncher" ) {
00207         odebug << "QuickLauncher invoked as: " << arg0.data() << oendl;
00208         QuickLauncher::exec( argc, argv );
00209     } else {
00210 #ifdef _OS_LINUX_
00211         // Setup to change proc title
00212         int i;
00213         char **envp = environ;
00214         /* Move the environment so we can reuse the memory.
00215          * (Code borrowed from sendmail.) */
00216         for (i = 0; envp[i] != NULL; i++)
00217             continue;
00218         environ = (char **) malloc(sizeof(char *) * (i + 1));
00219         if (environ == NULL)
00220             return -1;
00221         for (i = 0; envp[i] != NULL; i++)
00222             if ((environ[i] = strdup(envp[i])) == NULL)
00223                 return -1;
00224         environ[i] = NULL;
00225 
00226         argv0 = argv;
00227         if (i > 0)
00228             argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0];
00229         else
00230             argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0];
00231 #endif
00232         (void)new QuickLauncher();
00233         odebug << "QuickLauncher running" << oendl;
00234         // Pre-load default fonts
00235         QFontMetrics fm( QApplication::font() );
00236         fm.ascent(); // causes font load.
00237         QFont f( QApplication::font() );
00238         f.setWeight( QFont::Bold );
00239         QFontMetrics fmb( f );
00240         fmb.ascent(); // causes font load.
00241 
00242         // Each of the following force internal structures/internal
00243         // initialization to be performed.  This may mean allocating
00244         // memory that is not needed by all applications.
00245         Resource::loadPixmap("new"); // do internal init
00246 
00247         /* make sure libopie gets lined in */
00248         {
00249             Opie::Ui::OWait item;
00250         }
00251 
00252         // Create a widget to force initialization of title bar images, etc.
00253         QObject::disconnect(app, SIGNAL(lastWindowClosed()), app, SLOT(hideOrQuit()));
00254         QWidget *w = new QWidget(0,0,Qt::WDestructiveClose|Qt::WStyle_ContextHelp|Qt::WStyle_Tool);
00255         w->setGeometry( -100, -100, 10, 10 );
00256         w->show();
00257         QTimer::singleShot( 0, w, SLOT(close()) );
00258 
00259         app->enter_loop();
00260     }
00261 
00262     int rv = app->exec();
00263 
00264     if ( mainWindow )
00265         delete (QWidget*)mainWindow;
00266     delete app;
00267 
00268     if ( appIface )
00269         loader->releaseInterface( appIface );
00270     delete loader;
00271 
00272 
00273     // Neither QLibrary nor my Dropin is a QObject and they don't depend
00274     // on a qApp so we destroy QWidget::destroyMapper() without
00275     // crashing the app
00276     //
00277     // The problem is there are some 'static' resources not freed
00278     // in the apps and on destructing these objects are not available
00279     // anymore. In future fix up the apps but for now
00280     // we just skip deletion and hope things go well -zecke
00281     //    delete app;
00282     // hack instead -zecke
00283     //    delete app->pidChannel;
00284     //    app->pidChannel = 0;
00285 
00286     return rv;
00287 }
00288 
00289 #include "main.moc"

Generated on Sat Nov 5 16:15:25 2005 for OPIE by  doxygen 1.4.2