Subversion Repositories Scribus

Rev

Rev 17163 | Rev 22177 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
3779 cbradney 7
/***************************************************************************
8
                                                main.cpp  -  description
9
                                                        -------------------
10
        begin                : Fre Apr  6 21:47:55 CEST 2001
11
        copyright            : (C) 2001 by Franz Schmid
12
        email                : Franz.Schmid@altmuehlnet.de
13
        copyright            : (C) 2004 by Alessandro Rimoldi
14
        email                : http://ideale.ch/contact
15
        copyright            : (C) 2005 by Craig Bradney
16
        email                : cbradney@zip.com.au
17
***************************************************************************/
18
 
19
/***************************************************************************
20
*                                                                         *
21
*   This program is free software; you can redistribute it and/or modify  *
22
*   it under the terms of the GNU General Public License as published by  *
23
*   the Free Software Foundation; either version 2 of the License, or     *
24
*   (at your option) any later version.                                   *
25
*                                                                         *
26
***************************************************************************/
27
 
28
#include <iostream>
29
#include <signal.h>
30
 
31
#ifndef _WIN32
32
#error "This file compiles on win32 platform only"
33
#endif
34
 
5598 jghali 35
#include <stdio.h>
36
#include <fcntl.h>
37
#include <io.h>
38
 
10223 cbradney 39
#include <QApplication>
3779 cbradney 40
#include <exception>
41
using namespace std;
42
 
43
#define BASE_QM "scribus"
5598 jghali 44
#define MAX_LINES 500
3779 cbradney 45
 
46
#include "scribusapp.h"
5248 mrdocs 47
#include "scribuscore.h"
3779 cbradney 48
#include "scribus.h"
49
 
50
#include "scconfig.h"
51
 
15706 jghali 52
#include <windows.h>
5598 jghali 53
#include <wincon.h>
3779 cbradney 54
 
55
int mainApp(ScribusQApp& app);
5598 jghali 56
 
57
// Windows exception handling
3779 cbradney 58
static LONG exceptionFilter(DWORD exceptionCode);
59
static QString exceptionDescription(DWORD exceptionCode);
60
static void defaultCrashHandler(DWORD exceptionCode);
61
 
5598 jghali 62
// Console IO redirection handling
63
void messageHandler( QtMsgType type, const char *msg );
64
bool consoleOptionEnabled(int argc, char* argv[]);
65
void redirectIOToConsole(void);
66
 
67
// Console option arguments declared in scribusapp.cpp
68
extern const char ARG_CONSOLE[];
69
extern const char ARG_CONSOLE_SHORT[];
70
 
5248 mrdocs 71
ScribusCore SCRIBUS_API *ScCore;
4026 craig 72
ScribusMainWindow SCRIBUS_API *ScMW;
3779 cbradney 73
ScribusQApp SCRIBUS_API *ScQApp;
74
bool emergencyActivated;
75
 
76
int main(int argc, char *argv[])
77
{
78
        int result;
79
        emergencyActivated = false;
5598 jghali 80
#if !defined(_CONSOLE)
81
        if (consoleOptionEnabled(argc, argv))
82
        {
83
                redirectIOToConsole();
84
                qInstallMsgHandler( messageHandler );
85
        }
86
#endif
3779 cbradney 87
        ScribusQApp app(argc, argv);
88
        result =  mainApp(app);
89
        return result;
90
}
91
 
92
/*!
93
\fn int mainApp(ScribusQApp& app)
94
\author Franz Schmid
95
\author Alessandro Rimoldi
96
\author Craig Bradney
97
\author Jean Ghali
98
\date Mon Feb  9 14:07:46 CET 2004
99
\brief Launches the Gui
4645 subik 100
\param app a Scribus QApplication object
3779 cbradney 101
\retval int Error code from the execution of Scribus
102
*/
103
int mainApp(ScribusQApp& app)
104
{
18703 jghali 105
        int appRetVal = 0;
4689 mrdocs 106
#ifndef _DEBUG
3779 cbradney 107
        __try
108
        {
4689 mrdocs 109
#endif
3779 cbradney 110
                app.parseCommandLine();
5243 cbradney 111
                if (app.useGUI)
3779 cbradney 112
                {
113
                        appRetVal = app.init();
114
                        if (appRetVal != EXIT_FAILURE)
115
                                appRetVal = app.exec();
116
                }
4689 mrdocs 117
#ifndef _DEBUG
3779 cbradney 118
        }
119
        __except( exceptionFilter(GetExceptionCode()) )
120
        {
121
                defaultCrashHandler( GetExceptionCode() );
122
        }
4689 mrdocs 123
#endif
3779 cbradney 124
        return appRetVal;
125
}
126
 
127
/*!
128
\fn int exceptionFilter(DWORD exceptionCode)
129
\author Jean Ghali
130
\date Sun Oct 30 14:30:30 CET 2005
131
\brief describe the behavior to be adopted against specific exception
12071 subik 132
\param exceptionCode the value returned by GetExceptionCode()
133
\retval LONG EXCEPTION_EXECUTE_HANDLER if handler is to be executed or EXCEPTION_CONTINUE_EXECUTION if not
3779 cbradney 134
*/
135
LONG exceptionFilter(DWORD exceptionCode)
136
{
13502 jghali 137
        LONG result;
3779 cbradney 138
        switch( exceptionCode )
139
        {
140
        case EXCEPTION_ACCESS_VIOLATION:
141
        case EXCEPTION_DATATYPE_MISALIGNMENT:
142
        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
143
        case EXCEPTION_FLT_DENORMAL_OPERAND:
144
        case EXCEPTION_FLT_DIVIDE_BY_ZERO:
145
        case EXCEPTION_FLT_INEXACT_RESULT:
146
        case EXCEPTION_FLT_INVALID_OPERATION:
147
        case EXCEPTION_FLT_OVERFLOW:
148
        case EXCEPTION_FLT_STACK_CHECK:
149
        case EXCEPTION_FLT_UNDERFLOW:
150
        case EXCEPTION_ILLEGAL_INSTRUCTION:
151
        case EXCEPTION_INT_DIVIDE_BY_ZERO:
152
        case EXCEPTION_INT_OVERFLOW:
153
        case EXCEPTION_INVALID_HANDLE:
154
        case EXCEPTION_NONCONTINUABLE_EXCEPTION:
155
        case EXCEPTION_STACK_OVERFLOW:
156
                result = EXCEPTION_EXECUTE_HANDLER;
157
                break;
158
        case EXCEPTION_BREAKPOINT:
159
        case EXCEPTION_SINGLE_STEP:
160
                result = EXCEPTION_CONTINUE_EXECUTION;
161
                break;
162
        default:
163
                result = EXCEPTION_EXECUTE_HANDLER;
164
                break;
165
        }
166
        return result;
167
}
168
 
169
/*!
170
\fn int exceptionDescription(DWORD exceptionCode)
171
\author Jean Ghali
172
\date Sun Oct 30 14:30:30 CET 2005
173
\brief return a string describing a specific exception
12071 subik 174
\param exceptionCode the value returned by GetExceptionCode()
175
\retval QString describing the specified exception
3779 cbradney 176
*/
177
static QString exceptionDescription(DWORD exceptionCode)
178
{
11613 jghali 179
        QString description;
3779 cbradney 180
        if ( exceptionCode == EXCEPTION_ACCESS_VIOLATION )
181
                description = "EXCEPTION_ACCESS_VIOLATION";
182
        else if ( exceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT )
183
                description = "EXCEPTION_DATATYPE_MISALIGNMENT";
184
        else if ( exceptionCode == EXCEPTION_ARRAY_BOUNDS_EXCEEDED )
185
                description = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
186
        else if ( exceptionCode == EXCEPTION_FLT_DENORMAL_OPERAND )
187
                description = "EXCEPTION_FLT_DENORMAL_OPERAND";
188
        else if ( exceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO )
189
                description = "EXCEPTION_FLT_DIVIDE_BY_ZERO";
190
        else if ( exceptionCode == EXCEPTION_FLT_INEXACT_RESULT )
191
                description = "EXCEPTION_FLT_INEXACT_RESULT";
192
        else if ( exceptionCode == EXCEPTION_FLT_INVALID_OPERATION )
193
                description = "EXCEPTION_FLT_INVALID_OPERATION";
194
        else if ( exceptionCode == EXCEPTION_FLT_OVERFLOW )
195
                description = "EXCEPTION_FLT_OVERFLOW";
196
        else if ( exceptionCode == EXCEPTION_FLT_STACK_CHECK )
197
                description = "EXCEPTION_FLT_STACK_CHECK";
198
        else if ( exceptionCode == EXCEPTION_FLT_UNDERFLOW )
199
                description = "EXCEPTION_FLT_UNDERFLOW";
11613 jghali 200
        else if ( exceptionCode == EXCEPTION_GUARD_PAGE )
201
                description = "EXCEPTION_GUARD_PAGE";
3779 cbradney 202
        else if ( exceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION )
203
                description = "EXCEPTION_ILLEGAL_INSTRUCTION";
11613 jghali 204
        else if ( exceptionCode == EXCEPTION_IN_PAGE_ERROR )
205
                description = "EXCEPTION_IN_PAGE_ERROR";
3779 cbradney 206
        else if ( exceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO )
207
                description = "EXCEPTION_INT_DIVIDE_BY_ZERO";
208
        else if ( exceptionCode == EXCEPTION_INT_OVERFLOW )
209
                description = "EXCEPTION_INT_OVERFLOW";
11613 jghali 210
        else if ( exceptionCode == EXCEPTION_INVALID_DISPOSITION )
211
                description = "EXCEPTION_INVALID_DISPOSITION";
3779 cbradney 212
        else if ( exceptionCode == EXCEPTION_INVALID_HANDLE )
213
                description = "EXCEPTION_INVALID_HANDLE";
214
        else if ( exceptionCode == EXCEPTION_NONCONTINUABLE_EXCEPTION )
215
                description = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
11613 jghali 216
        else if ( exceptionCode == EXCEPTION_PRIV_INSTRUCTION )
217
                description = "EXCEPTION_PRIV_INSTRUCTION";
3779 cbradney 218
        else if ( exceptionCode == EXCEPTION_STACK_OVERFLOW )
219
                description = "EXCEPTION_STACK_OVERFLOW";
220
        else
221
                description = "UNKNOWN EXCEPTION";
222
        return description;
223
}
224
 
225
void defaultCrashHandler(DWORD exceptionCode)
226
{
227
        static int crashRecursionCounter = 0;
228
        crashRecursionCounter++;
229
        if (crashRecursionCounter < 2)
230
        {
231
                emergencyActivated=true;
232
                crashRecursionCounter++;
233
                QString expDesc = exceptionDescription(exceptionCode);
5598 jghali 234
                QString expHdr  = QObject::tr("Scribus Crash");
235
                QString expLine = "-------------";
236
                QString expMsg  = QObject::tr("Scribus crashes due to the following exception : %1").arg(expDesc);
10723 jghali 237
                std::cout << (const char*) expHdr.toAscii().data() << std::endl;
238
                std::cout << (const char*) expLine.toAscii().data() << std::endl;
239
                std::cout << (const char*) expMsg.toAscii().data() << std::endl;
3779 cbradney 240
                if (ScribusQApp::useGUI)
241
                {
5248 mrdocs 242
                        ScCore->closeSplash();
4026 craig 243
                        QMessageBox::critical(ScMW, expHdr, expMsg, QObject::tr("&OK"));
244
                        ScMW->emergencySave();
245
                        ScMW->close();
3779 cbradney 246
                }
247
        }
248
        ExitProcess(255);
249
}
5598 jghali 250
 
251
void messageHandler( QtMsgType type, const char *msg )
252
{
253
        cerr << msg << endl;
254
        if( type == QtFatalMsg )
255
        {
256
                if (ScribusQApp::useGUI)
257
                {
258
                        ScCore->closeSplash();
259
                        QString expHdr = QObject::tr("Scribus Crash");
260
                        QString expMsg = msg;
261
                        QMessageBox::critical(ScMW, expHdr, expMsg, QObject::tr("&OK"));
262
                        ScMW->emergencySave();
263
                        ScMW->close();
264
                }
265
                ExitProcess(255);
266
        }
267
}
268
 
269
bool consoleOptionEnabled(int argc, char* argv[])
270
{
13502 jghali 271
        bool value = false;
5598 jghali 272
        for( int i = 0; i < argc; i++ )
273
        {
274
                if( strcmp(argv[i], ARG_CONSOLE) == 0 ||
275
                        strcmp(argv[i], ARG_CONSOLE_SHORT) == 0 )
276
                {
277
                        value = true;
278
                        break;
279
                }
280
        }
281
        return value;
282
}
283
 
284
void redirectIOToConsole(void)
285
{
286
        int hConHandle;
287
        HANDLE lStdHandle;
288
        CONSOLE_SCREEN_BUFFER_INFO coninfo;
289
        FILE *fp;
290
 
291
        // allocate console
292
        if( GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE )
293
                AllocConsole();
294
        // set the screen buffer to be big enough to let us scroll text
295
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
296
        coninfo.dwSize.Y = MAX_LINES;
297
        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
298
        //redirect unbuffered STDOUT to the console
299
        lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
300
        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
301
        fp = _fdopen( hConHandle, "w" );
302
        *stdout = *fp;
303
        setvbuf( stdout, NULL, _IONBF, 0 );
304
        // redirect unbuffered STDIN to the console
305
        lStdHandle = GetStdHandle(STD_INPUT_HANDLE);
306
        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
307
        fp = _fdopen( hConHandle, "r" );
308
        *stdin = *fp;
309
        setvbuf( stdin, NULL, _IONBF, 0 );
310
        // redirect unbuffered STDERR to the console
311
        lStdHandle = GetStdHandle(STD_ERROR_HANDLE);
312
        hConHandle = _open_osfhandle((intptr_t) lStdHandle, _O_TEXT);
313
        fp = _fdopen( hConHandle, "w" );
314
        *stderr = *fp;
315
        setvbuf( stderr, NULL, _IONBF, 0 );
316
        // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 
317
        // point to console as well
318
        ios::sync_with_stdio();
319
}