VirtualBox

Ignore:
Timestamp:
Oct 22, 2008 2:29:55 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
38313
Message:

FE/Qt4: Made it shut up the Selector's progress dialog when a detected failure happens in the Console process that doesn't let it run the VM (to make sure the message that describes the failure is not sent to background).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox4/src/main.cpp

    r13458 r13492  
    6060#endif
    6161
    62 
    63 
    6462/**
    6563 * the signal handler that prints out a backtrace of the call stack.
     
    9391}
    9492
    95 #endif
    96 
     93#endif // defined(DEBUG) && defined(Q_WS_X11) && defined(RT_OS_LINUX)
     94
     95/**
     96 * Qt warning/debug/fatal message handler.
     97 */
    9798static void QtMessageOutput (QtMsgType type, const char *msg)
    9899{
     
    129130#ifndef Q_WS_WIN
    130131/**
    131  * Show all available command line parameters.
    132  */
    133 static void showHelp()
     132 * Shows all available command line parameters.
     133 */
     134static void ShowHelp()
    134135{
    135136    QString mode = "", dflt = "";
     
    172173            dflt.toLatin1().constData());
    173174}
    174 #endif
    175 
    176 extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
     175#endif // ifndef Q_WS_WIN
     176
     177/*
     178 * Initializes Qt and the rest. Must be called before
     179 */
     180static void InitQtAndAll (QIApplication &aApp, int argc = 0, char **argv = NULL)
     181{
     182
     183}
     184
     185////////////////////////////////////////////////////////////////////////////////
     186
     187/**
     188 * The thing. Initializes Qt and all and does the opposite when dissolved.
     189 */
     190class TheThing
     191{
     192public:
     193
     194    TheThing (int &argc, char ** &argv)
     195        : mIsOk (false), mApp (NULL)
     196    { init (&argc, &argv); }
     197
     198    TheThing()
     199        : mIsOk (false), mApp (NULL)
     200    { init(); }
     201
     202    ~TheThing() { uninit(); }
     203
     204    bool isOk() const { return mIsOk; }
     205
     206    QIApplication &app() const { return *mApp; }
     207
     208private:
     209
     210    void init (int *argc = NULL, char ***argv = NULL);
     211    void uninit();
     212
     213    bool mIsOk;
     214
     215#ifdef Q_WS_WIN
     216    HRESULT mInitRC;
     217#endif
     218
     219    QIApplication *mApp;
     220
     221    char mAppRaw [sizeof (QIApplication)];
     222
     223    static int mFakeArgc;
     224    static char *mFakeArgv [2];
     225};
     226
     227int TheThing::mFakeArgc = 0;
     228char *TheThing::mFakeArgv [2] = { NULL, NULL };
     229
     230/**
     231 * Initializer of the thing.
     232 */
     233void TheThing::init (int *argc /*= NULL*/, char ***argv /*= NULL*/)
    177234{
    178235    LogFlowFuncEnter();
     
    188245     * for some unknown reason), see also src/VBox/Main/glue/initterm.cpp. */
    189246    /// @todo find a proper solution that satisfies both OLE and VBox
    190     HRESULT hrc = COMBase::InitializeCOM();
    191 #endif
     247    mInitRC = COMBase::InitializeCOM();
     248#endif
     249
     250    qInstallMsgHandler (QtMessageOutput);
     251
     252    /* guarantee successful allocation */
     253    mApp = new (&mAppRaw) QIApplication (argc != NULL ? *argc : mFakeArgc,
     254                                         argv != NULL ? *argv : mFakeArgv);
     255    Assert (mApp != NULL);
     256
     257    /* Qt4.3 version has the QProcess bug which freezing the application
     258     * for 30 seconds. This bug is internally used at initialization of
     259     * Cleanlooks style. So we have to change this style to another one.
     260     * See http://trolltech.com/developer/task-tracker/index_html?id=179200&method=entry
     261     * for details. */
     262    if (QString (qVersion()).startsWith ("4.3") &&
     263        qobject_cast <QCleanlooksStyle*> (QApplication::style()))
     264        QApplication::setStyle (new QPlastiqueStyle);
     265
     266#ifdef Q_WS_X11
     267    /* Cause Qt4 has the conflict with fontconfig application as a result
     268     * substituting some fonts with non anti-aliased bitmap font we are
     269     * reseting all the substitutes here for the current application font. */
     270# ifndef Q_OS_SOLARIS
     271    QFont::removeSubstitution (QApplication::font().family());
     272# endif /* Q_OS_SOLARIS */
     273#endif
     274
     275#ifdef Q_WS_WIN
     276    /* Drag in the sound drivers and DLLs early to get rid of the delay taking
     277     * place when the main menu bar (or any action from that menu bar) is
     278     * activated for the first time. This delay is especially annoying if it
     279     * happens when the VM is executing in real mode (which gives 100% CPU
     280     * load and slows down the load process that happens on the main GUI
     281     * thread to several seconds). */
     282    PlaySound (NULL, NULL, 0);
     283#endif
     284
     285#ifdef Q_WS_MAC
     286    ::darwinDisableIconsInMenus();
     287#endif /* Q_WS_MAC */
     288
     289#ifdef Q_WS_X11
     290    /* version check (major.minor are sensitive, fix number is ignored) */
     291    QString ver_str = QString::fromLatin1 (QT_VERSION_STR);
     292    QString ver_str_base = ver_str.section ('.', 0, 1);
     293    QString rt_ver_str = QString::fromLatin1 (qVersion());
     294    uint ver =
     295        (ver_str.section ('.', 0, 0).toInt() << 16) +
     296        (ver_str.section ('.', 1, 1).toInt() << 8) +
     297        ver_str.section ('.', 2, 2).toInt();
     298    uint rt_ver =
     299        (rt_ver_str.section ('.', 0, 0).toInt() << 16) +
     300        (rt_ver_str.section ('.', 1, 1).toInt() << 8) +
     301        rt_ver_str.section ('.', 2, 2).toInt();
     302    if (rt_ver < (ver & 0xFFFF00))
     303    {
     304        QString msg =
     305            QApplication::tr ("Executable <b>%1</b> requires Qt %2.x, found Qt %3.")
     306                              .arg (qAppName())
     307                              .arg (ver_str_base)
     308                              .arg (rt_ver_str);
     309        QMessageBox::critical (
     310            0, QApplication::tr ("Incompatible Qt Library Error"),
     311            msg, QMessageBox::Abort, 0);
     312        qFatal (msg.toAscii().constData());
     313    }
     314#endif
     315
     316    /* load a translation based on the current locale */
     317    VBoxGlobal::loadLanguage();
     318
     319#ifdef Q_WS_WIN
     320    /* Check for the COM error after we've initialized Qt */
     321    if (FAILED (mInitRC))
     322    {
     323        vboxProblem().cannotInitCOM (mInitRC);
     324        return;
     325    }
     326#endif
     327
     328    if (!vboxGlobal().isValid())
     329        return;
     330
     331    /* Well, Ok... we are fine */
     332    mIsOk = true;
     333
     334    LogFlowFuncLeave();
     335}
     336
     337/**
     338 * Uninitializer of the thing.
     339 */
     340void TheThing::uninit()
     341{
     342    LogFlowFuncEnter();
     343
     344    if (mApp != NULL)
     345    {
     346        mApp->~QIApplication();
     347        mApp = NULL;
     348    }
     349
     350#ifdef Q_WS_WIN
     351    /* See COMBase::initializeCOM() in init() */
     352    if (SUCCEEDED (mInitRC))
     353        COMBase::CleanupCOM();
     354#endif
     355
     356    LogFlowFuncLeave();
     357}
     358
     359////////////////////////////////////////////////////////////////////////////////
     360
     361/**
     362 * Trusted entry point.
     363 */
     364extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
     365{
     366    LogFlowFuncEnter();
    192367
    193368#ifndef Q_WS_WIN
     
    199374            || !strcmp(argv[i], "--help"))
    200375        {
    201             showHelp();
     376            ShowHelp();
    202377            return 0;
    203378        }
     
    215390#endif
    216391
    217     qInstallMsgHandler (QtMessageOutput);
    218 
    219392    int rc = 1; /* failure */
    220393
    221     /* scope the QIApplication variable */
    222     {
    223         QIApplication a (argc, argv);
    224 
    225         /* Qt4.3 version has the QProcess bug which freezing the application
    226          * for 30 seconds. This bug is internally used at initialization of
    227          * Cleanlooks style. So we have to change this style to another one.
    228          * See http://trolltech.com/developer/task-tracker/index_html?id=179200&method=entry
    229          * for details. */
    230         if (QString (qVersion()).startsWith ("4.3") &&
    231             qobject_cast <QCleanlooksStyle*> (QApplication::style()))
    232             QApplication::setStyle (new QPlastiqueStyle);
    233 
    234 #ifdef Q_WS_X11
    235         /* Cause Qt4 has the conflict with fontconfig application as a result
    236          * substituting some fonts with non anti-aliased bitmap font we are
    237          * reseting all the substitutes here for the current application font. */
    238 # ifndef Q_OS_SOLARIS
    239         QFont::removeSubstitution (QApplication::font().family());
    240 # endif /* Q_OS_SOLARIS */
    241 #endif
    242 
    243 #ifdef Q_WS_WIN
    244         /* Drag in the sound drivers and DLLs early to get rid of the delay taking
    245          * place when the main menu bar (or any action from that menu bar) is
    246          * activated for the first time. This delay is especially annoying if it
    247          * happens when the VM is executing in real mode (which gives 100% CPU
    248          * load and slows down the load process that happens on the main GUI
    249          * thread to several seconds). */
    250         PlaySound (NULL, NULL, 0);
    251 #endif
    252 
    253 #ifdef Q_WS_MAC
    254         ::darwinDisableIconsInMenus();
    255 #endif /* Q_WS_MAC */
    256 
    257 #ifdef Q_WS_X11
    258         /* version check (major.minor are sensitive, fix number is ignored) */
    259         QString ver_str = QString::fromLatin1 (QT_VERSION_STR);
    260         QString ver_str_base = ver_str.section ('.', 0, 1);
    261         QString rt_ver_str = QString::fromLatin1 (qVersion());
    262         uint ver =
    263             (ver_str.section ('.', 0, 0).toInt() << 16) +
    264             (ver_str.section ('.', 1, 1).toInt() << 8) +
    265             ver_str.section ('.', 2, 2).toInt();
    266         uint rt_ver =
    267             (rt_ver_str.section ('.', 0, 0).toInt() << 16) +
    268             (rt_ver_str.section ('.', 1, 1).toInt() << 8) +
    269             rt_ver_str.section ('.', 2, 2).toInt();
    270         if (rt_ver < (ver & 0xFFFF00))
     394    /* scope TheThing */
     395    do
     396    {
     397        TheThing theThing (argc, argv);
     398
     399        if (theThing.isOk())
    271400        {
    272             QString msg =
    273                 QApplication::tr ("Executable <b>%1</b> requires Qt %2.x, found Qt %3.")
    274                                   .arg (qAppName())
    275                                   .arg (ver_str_base)
    276                                   .arg (rt_ver_str);
    277             QMessageBox::critical (
    278                 0, QApplication::tr ("Incompatible Qt Library Error"),
    279                 msg, QMessageBox::Abort, 0);
    280             qFatal (msg.toAscii().constData());
    281         }
    282 #endif
    283 
    284         /* load a translation based on the current locale */
    285         VBoxGlobal::loadLanguage();
    286 
    287         do
    288         {
    289 #ifdef Q_WS_WIN
    290             /* Check for the COM error after we've initialized Qt */
    291             if (FAILED (hrc))
    292             {
    293                 vboxProblem().cannotInitCOM (hrc);
    294                 break;
    295             }
    296 #endif
    297 
    298             if (!vboxGlobal().isValid())
    299                 break;
    300 
    301401#ifndef VBOX_OSE
    302402#ifdef Q_WS_X11
     
    306406#endif
    307407#endif
    308 
    309408            vboxGlobal().checkForAutoConvertedSettings();
    310409
     
    317416                vboxGlobal().setMainWindow (&vboxGlobal().consoleWnd());
    318417                if (vboxGlobal().startMachine (vboxGlobal().managedVMUuid()))
    319                     rc = a.exec();
     418                    rc = theThing.app().exec();
    320419            }
    321420            else if (noSelector)
     
    334433#endif
    335434                vboxGlobal().startEnumeratingMedia();
    336                 rc = a.exec();
     435                rc = theThing.app().exec();
    337436            }
    338437        }
    339         while (0);
    340     }
    341 
    342 #ifdef Q_WS_WIN
    343     /* See COMBase::initializeCOM() above */
    344     if (SUCCEEDED (hrc))
    345         COMBase::CleanupCOM();
    346 #endif
     438    }
     439    while (0);
    347440
    348441    LogFlowFunc (("rc=%d\n", rc));
     
    354447#ifndef VBOX_WITH_HARDENING
    355448
     449/**
     450 * Untrusted entry point. Calls TrustedMain().
     451 */
    356452int main (int argc, char **argv, char **envp)
    357453{
     
    379475#else  /* VBOX_WITH_HARDENING */
    380476
    381 /**
    382  * Hardened main failed, report the error without any unnecessary fuzz.
     477////////////////////////////////////////////////////////////////////////////////
     478
     479/**
     480 * Hardened main failed (TrustedMain() not called), report the error without any
     481 * unnecessary fuzz.
    383482 *
    384483 * @remarks Do not call IPRT here unless really required, it might not be
    385484 *          initialized.
    386485 */
    387 extern "C" DECLEXPORT(void) TrustedError (const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va)
    388 {
     486extern "C" DECLEXPORT(void) TrustedError (const char *pszWhere,
     487                                          SUPINITOP enmWhat, int rc,
     488                                          const char *pszMsgFmt, va_list va)
     489{
     490    TheThing theThing;
     491
    389492    /*
    390      * Init the Qt application object. This is a bit hackish as we
    391      * don't have the argument vector handy.
     493     * Open the direct session to let the spawning progress dialog of the VM
     494     * Selector window disappear. Otherwise, the dialog will pop up after 2
     495     * seconds and become the foreground window hiding the message box we will
     496     * show below.
     497     *
     498     * @todo Note that this is an ugly workaround because the real problem is
     499     * the broken Window Manager on some platforms which allows windows of
     500     * background processes to be raised above the windows of the foreground
     501     * process drawing all the user's attention. The proper solution is to fix
     502     * those broken WMs. A less proper but less ugly workaround is to replace
     503     * VBoxProgressDialog/QProgressDialog with an implementation that doesn't
     504     * try to put itself on top if it is not an active process.
    392505     */
    393     int argc = 0;
    394     char *argv[2] = { NULL, NULL };
    395     QApplication a (argc, &argv[0]);
     506    if (theThing.isOk() && vboxGlobal().isVMConsoleProcess())
     507    {
     508        CSession session =
     509            vboxGlobal().openSession (vboxGlobal().managedVMUuid());
     510        session.Close();
     511    }
    396512
    397513    /*
    398514     * Compose and show the error message.
    399515     */
    400     QString msgTitle = QApplication::tr ("VirtualBox - Error In %1").arg (pszWhere);
    401 
    402     char msgBuf[1024];
     516    QString msgTitle =
     517        QApplication::tr ("VirtualBox - Error In %1").arg (pszWhere);
     518
     519    char msgBuf [1024];
    403520    vsprintf (msgBuf, pszMsgFmt, va);
    404521
    405     QString msgText = QApplication::tr ("%1\n\nrc=%2").arg (msgBuf).arg(rc);
     522    QString msgText = QApplication::tr ("%1\n\nrc=%2").arg (msgBuf).arg (rc);
     523
    406524    switch (enmWhat)
    407525    {
    408526        case kSupInitOp_Driver:
    409             msgText += QApplication::tr ("\n\nMake sure the kernel module has been loaded successfully.");
     527            msgText += QApplication::tr ("\n\nMake sure the kernel module has "
     528                                         "been loaded successfully.");
    410529            break;
    411530        case kSupInitOp_IPRT:
    412531        case kSupInitOp_Integrity:
    413532        case kSupInitOp_RootCheck:
    414             msgText += QApplication::tr ("\n\nIt may help to reinstall VirtualBox."); /* hope this isn't (C), (TM) or (R) Microsoft support ;-) */
     533            msgText += QApplication::tr ("\n\nIt may help to reinstall "
     534                                         "VirtualBox."); /* hope this isn't (C), (TM) or (R) Microsoft support ;-) */
    415535            break;
    416536        default:
     
    425545        QMessageBox::Abort,     /* button0 */
    426546        0);                     /* button1 */
     547
    427548    qFatal (msgText.toAscii().constData());
    428549}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette