Back to index

scribus-ng  1.3.4.dfsg+svn20071115
main_win32.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008                                           main.cpp  -  description
00009                                                  -------------------
00010        begin                : Fre Apr  6 21:47:55 CEST 2001
00011        copyright            : (C) 2001 by Franz Schmid
00012        email                : Franz.Schmid@altmuehlnet.de
00013        copyright            : (C) 2004 by Alessandro Rimoldi
00014        email                : http://ideale.ch/contact
00015        copyright            : (C) 2005 by Craig Bradney
00016        email                : cbradney@zip.com.au
00017 ***************************************************************************/
00018 
00019 /***************************************************************************
00020 *                                                                         *
00021 *   This program is free software; you can redistribute it and/or modify  *
00022 *   it under the terms of the GNU General Public License as published by  *
00023 *   the Free Software Foundation; either version 2 of the License, or     *
00024 *   (at your option) any later version.                                   *
00025 *                                                                         *
00026 ***************************************************************************/
00027 
00028 #include <iostream>
00029 #include <signal.h>
00030 
00031 #ifndef _WIN32
00032 #error "This file compiles on win32 platform only"
00033 #endif
00034 
00035 #include <stdio.h>
00036 #include <fcntl.h>
00037 #include <io.h>
00038 
00039 #include <qapplication.h>
00040 #include <exception>
00041 using namespace std;
00042 
00043 #define BASE_QM "scribus"
00044 #define MAX_LINES 500
00045 
00046 #include "scribusapp.h"
00047 #include "scribuscore.h"
00048 #include "scribus.h"
00049 
00050 #include "scconfig.h"
00051 
00052 #include <wincon.h>
00053 #include <windows.h>
00054 
00055 int mainApp(ScribusQApp& app);
00056 
00057 // Windows exception handling
00058 static LONG exceptionFilter(DWORD exceptionCode);
00059 static QString exceptionDescription(DWORD exceptionCode);
00060 static void defaultCrashHandler(DWORD exceptionCode);
00061 
00062 // Console IO redirection handling
00063 void messageHandler( QtMsgType type, const char *msg );
00064 bool consoleOptionEnabled(int argc, char* argv[]);
00065 void redirectIOToConsole(void);
00066 
00067 // Console option arguments declared in scribusapp.cpp
00068 extern const char ARG_CONSOLE[];
00069 extern const char ARG_CONSOLE_SHORT[];
00070 
00071 ScribusCore SCRIBUS_API *ScCore;
00072 ScribusMainWindow SCRIBUS_API *ScMW;
00073 ScribusQApp SCRIBUS_API *ScQApp;
00074 bool emergencyActivated;
00075 
00076 int main(int argc, char *argv[])
00077 {
00078        int result;
00079        emergencyActivated = false;
00080 #if !defined(_CONSOLE)
00081        if (consoleOptionEnabled(argc, argv))
00082        {
00083               redirectIOToConsole();
00084               qInstallMsgHandler( messageHandler );
00085        }
00086 #endif
00087        ScribusQApp app(argc, argv);
00088        result =  mainApp(app);
00089        return result;
00090 }
00091 
00103 int mainApp(ScribusQApp& app)
00104 {
00105        int appRetVal;
00106 #ifndef _DEBUG
00107        __try
00108        {
00109 #endif
00110               app.parseCommandLine();
00111               if (app.useGUI)
00112               {
00113                      appRetVal = app.init();
00114                      if (appRetVal != EXIT_FAILURE)
00115                             appRetVal = app.exec();
00116               }
00117 #ifndef _DEBUG
00118        }
00119        __except( exceptionFilter(GetExceptionCode()) )
00120        {
00121               defaultCrashHandler( GetExceptionCode() );
00122        }
00123 #endif
00124        return appRetVal;
00125 }
00126 
00135 LONG exceptionFilter(DWORD exceptionCode)
00136 {
00137  LONG result;
00138        switch( exceptionCode )
00139        {
00140        case EXCEPTION_ACCESS_VIOLATION:
00141        case EXCEPTION_DATATYPE_MISALIGNMENT:
00142        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
00143        case EXCEPTION_FLT_DENORMAL_OPERAND:
00144        case EXCEPTION_FLT_DIVIDE_BY_ZERO:
00145        case EXCEPTION_FLT_INEXACT_RESULT:
00146        case EXCEPTION_FLT_INVALID_OPERATION:
00147        case EXCEPTION_FLT_OVERFLOW:
00148        case EXCEPTION_FLT_STACK_CHECK:
00149        case EXCEPTION_FLT_UNDERFLOW:
00150        case EXCEPTION_ILLEGAL_INSTRUCTION:
00151        case EXCEPTION_INT_DIVIDE_BY_ZERO:
00152        case EXCEPTION_INT_OVERFLOW:
00153        case EXCEPTION_INVALID_HANDLE:
00154        case EXCEPTION_NONCONTINUABLE_EXCEPTION:
00155        case EXCEPTION_STACK_OVERFLOW:
00156               result = EXCEPTION_EXECUTE_HANDLER;
00157               break;
00158        case EXCEPTION_BREAKPOINT:
00159        case EXCEPTION_SINGLE_STEP:
00160               result = EXCEPTION_CONTINUE_EXECUTION;
00161               break;
00162        default:
00163               result = EXCEPTION_EXECUTE_HANDLER;
00164               break;
00165        }
00166        return result;
00167 }
00168 
00177 static QString exceptionDescription(DWORD exceptionCode)
00178 {
00179  QString description;
00180        if ( exceptionCode == EXCEPTION_ACCESS_VIOLATION )
00181               description = "EXCEPTION_ACCESS_VIOLATION";
00182        else if ( exceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT )
00183               description = "EXCEPTION_DATATYPE_MISALIGNMENT";
00184        else if ( exceptionCode == EXCEPTION_ARRAY_BOUNDS_EXCEEDED )
00185               description = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
00186        else if ( exceptionCode == EXCEPTION_FLT_DENORMAL_OPERAND )
00187               description = "EXCEPTION_FLT_DENORMAL_OPERAND";
00188        else if ( exceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO )
00189               description = "EXCEPTION_FLT_DIVIDE_BY_ZERO";
00190        else if ( exceptionCode == EXCEPTION_FLT_INEXACT_RESULT )
00191               description = "EXCEPTION_FLT_INEXACT_RESULT";
00192        else if ( exceptionCode == EXCEPTION_FLT_INVALID_OPERATION )
00193               description = "EXCEPTION_FLT_INVALID_OPERATION";
00194        else if ( exceptionCode == EXCEPTION_FLT_OVERFLOW )
00195               description = "EXCEPTION_FLT_OVERFLOW";
00196        else if ( exceptionCode == EXCEPTION_FLT_STACK_CHECK )
00197               description = "EXCEPTION_FLT_STACK_CHECK";
00198        else if ( exceptionCode == EXCEPTION_FLT_UNDERFLOW )
00199               description = "EXCEPTION_FLT_UNDERFLOW";
00200        else if ( exceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION )
00201               description = "EXCEPTION_ILLEGAL_INSTRUCTION";
00202        else if ( exceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO )
00203               description = "EXCEPTION_INT_DIVIDE_BY_ZERO";
00204        else if ( exceptionCode == EXCEPTION_INT_OVERFLOW )
00205               description = "EXCEPTION_INT_OVERFLOW";
00206        else if ( exceptionCode == EXCEPTION_INVALID_HANDLE )
00207               description = "EXCEPTION_INVALID_HANDLE";
00208        else if ( exceptionCode == EXCEPTION_NONCONTINUABLE_EXCEPTION )
00209               description = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
00210        else if ( exceptionCode == EXCEPTION_STACK_OVERFLOW )
00211               description = "EXCEPTION_STACK_OVERFLOW";
00212        else
00213               description = "UNKNOWN EXCEPTION";
00214        return description;
00215 }
00216 
00217 void defaultCrashHandler(DWORD exceptionCode)
00218 {
00219        static int crashRecursionCounter = 0;
00220        crashRecursionCounter++;
00221        if (crashRecursionCounter < 2)
00222        {
00223               emergencyActivated=true;
00224               crashRecursionCounter++;
00225               QString expDesc = exceptionDescription(exceptionCode);
00226               QString expHdr  = QObject::tr("Scribus Crash");
00227               QString expLine = "-------------";
00228               QString expMsg  = QObject::tr("Scribus crashes due to the following exception : %1").arg(expDesc);
00229               std::cout << (const char*) expHdr << std::endl;
00230               std::cout << (const char*) expLine << std::endl;
00231               std::cout << (const char*) expMsg << std::endl;
00232               if (ScribusQApp::useGUI)
00233               {
00234                      ScCore->closeSplash();
00235                      QMessageBox::critical(ScMW, expHdr, expMsg, QObject::tr("&OK"));
00236                      ScMW->emergencySave();
00237                      ScMW->close();
00238               }
00239        }
00240        ExitProcess(255);
00241 }
00242 
00243 void messageHandler( QtMsgType type, const char *msg )
00244 {
00245        cerr << msg << endl;
00246        if( type == QtFatalMsg )
00247        {
00248               if (ScribusQApp::useGUI)
00249               {
00250                      ScCore->closeSplash();
00251                      QString expHdr = QObject::tr("Scribus Crash");
00252                      QString expMsg = msg;
00253                      QMessageBox::critical(ScMW, expHdr, expMsg, QObject::tr("&OK"));
00254                      ScMW->emergencySave();
00255                      ScMW->close();
00256               }
00257               ExitProcess(255);
00258        }
00259 }
00260 
00261 bool consoleOptionEnabled(int argc, char* argv[])
00262 {
00263  bool value = false;
00264        for( int i = 0; i < argc; i++ )
00265        {
00266               if( strcmp(argv[i], ARG_CONSOLE) == 0 ||
00267                      strcmp(argv[i], ARG_CONSOLE_SHORT) == 0 )
00268               {
00269                      value = true;
00270                      break;
00271               }
00272        }
00273        return value;
00274 }
00275 
00276 void redirectIOToConsole(void)
00277 {
00278        int hConHandle;
00279        HANDLE lStdHandle;
00280        CONSOLE_SCREEN_BUFFER_INFO coninfo;
00281        FILE *fp;
00282 
00283        // allocate console
00284        if( GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE )
00285               AllocConsole();
00286        // set the screen buffer to be big enough to let us scroll text
00287        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
00288        coninfo.dwSize.Y = MAX_LINES;
00289        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
00290        //redirect unbuffered STDOUT to the console
00291        lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
00292        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
00293        fp = _fdopen( hConHandle, "w" );
00294        *stdout = *fp;
00295        setvbuf( stdout, NULL, _IONBF, 0 );
00296        // redirect unbuffered STDIN to the console
00297        lStdHandle = GetStdHandle(STD_INPUT_HANDLE);
00298        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
00299        fp = _fdopen( hConHandle, "r" );
00300        *stdin = *fp;
00301        setvbuf( stdin, NULL, _IONBF, 0 );
00302        // redirect unbuffered STDERR to the console
00303        lStdHandle = GetStdHandle(STD_ERROR_HANDLE);
00304        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
00305        fp = _fdopen( hConHandle, "w" );
00306        *stderr = *fp;
00307        setvbuf( stderr, NULL, _IONBF, 0 );
00308        // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 
00309        // point to console as well
00310        ios::sync_with_stdio();
00311 }