gimp/app/errors.c
Tor Lillqvist 92cdceed77 Make the handling of console output make more sense Win32. Should mostly
2007-01-26  Tor Lillqvist  <tml@novell.com>

	Make the handling of console output make more sense Win32. Should
	mostly fix #400927.
	    
	* app/app_procs.c (app_exit): Drop the Win32 "This console window
	will close in ten seconds" message from here.
	(app_run): Drop the call to FreeConsole() from here. GIMP is built
	as a GUI executable on Windows, and in case we do open a fresh
	console window in main() (see below), we shouldn't then
	immediately close it here.

	* app/errors.c (errors_init): Drop printing the "You can mimize
	this window, but don't close it" message on Win32 from here.

	* app/main.c (gimp_open_console_window): New Win32-only
	function. If either stdout or stderr are unconnected, open a new
	console window and connect stdout and/or stderr to it as
	needed. Set the console title to "GIMP output. You can minimize
	this window, but don't close it." Register an atexit function that
	waits for the user to close the console window.
	(wait_console_window): New Win32-only function. Registered as an
	atexit function when GIMP has opened a new console window. Prompts
	the user to type any character to close the window.
	(main, gimp_show_version): Always call gimp_open_console_window()
	in the unstable version. As the "This is a development version of
	GIMP. Debug messages may appear here" message says, one point of
	the unstable version is that debug messages should be visible, so
	I think it makes sense to always see them in an unstable
	version. In stable versions, call gimp_open_console_window() only
	if options that cause output that the user wants to see were
	given, like --help and --version.


svn path=/trunk/; revision=21781
2007-01-26 20:47:36 +00:00

242 lines
5.9 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#define _GNU_SOURCE /* need the POSIX signal API */
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "core/core-types.h"
#include "core/gimp.h"
#include "errors.h"
#ifdef G_OS_WIN32
#include <windows.h>
#endif
/* private variables */
static Gimp *the_errors_gimp = NULL;
static gboolean use_debug_handler = FALSE;
static GimpStackTraceMode stack_trace_mode = GIMP_STACK_TRACE_QUERY;
static gchar *full_prog_name = NULL;
/* local function prototypes */
static G_GNUC_NORETURN void gimp_eek (const gchar *reason,
const gchar *message,
gboolean use_handler);
static void gimp_message_log_func (const gchar *log_domain,
GLogLevelFlags flags,
const gchar *message,
gpointer data);
static void gimp_error_log_func (const gchar *domain,
GLogLevelFlags flags,
const gchar *message,
gpointer data) G_GNUC_NORETURN;
/* public functions */
void
errors_init (Gimp *gimp,
const gchar *_full_prog_name,
gboolean _use_debug_handler,
GimpStackTraceMode _stack_trace_mode)
{
const gchar * const log_domains[] =
{
"Gimp",
"Gimp-Actions",
"Gimp-Base",
"Gimp-Composite",
"Gimp-Config",
"Gimp-Core",
"Gimp-Dialogs",
"Gimp-Display",
"Gimp-File",
"Gimp-GUI",
"Gimp-Menus",
"Gimp-PDB",
"Gimp-Paint",
"Gimp-Paint-Funcs",
"Gimp-Plug-In",
"Gimp-Text",
"Gimp-Tools",
"Gimp-Vectors",
"Gimp-Widgets",
"Gimp-XCF"
};
gint i;
g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (_full_prog_name != NULL);
g_return_if_fail (full_prog_name == NULL);
#ifdef GIMP_UNSTABLE
g_printerr ("This is a development version of GIMP. "
"Debug messages may appear here.\n\n");
#endif /* GIMP_UNSTABLE */
the_errors_gimp = gimp;
use_debug_handler = _use_debug_handler ? TRUE : FALSE;
stack_trace_mode = _stack_trace_mode;
full_prog_name = g_strdup (_full_prog_name);
for (i = 0; i < G_N_ELEMENTS (log_domains); i++)
g_log_set_handler (log_domains[i],
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func, gimp);
g_log_set_handler (NULL,
G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
gimp_error_log_func, gimp);
}
void
gimp_fatal_error (const gchar *fmt, ...)
{
va_list args;
gchar *message;
va_start (args, fmt);
message = g_strdup_vprintf (fmt, args);
va_end (args);
gimp_eek ("fatal error", message, TRUE);
}
void
gimp_terminate (const gchar *fmt, ...)
{
va_list args;
gchar *message;
va_start (args, fmt);
message = g_strdup_vprintf (fmt, args);
va_end (args);
gimp_eek ("terminated", message, use_debug_handler);
}
/* private functions */
static void
gimp_message_log_func (const gchar *log_domain,
GLogLevelFlags flags,
const gchar *message,
gpointer data)
{
Gimp *gimp = data;
if (gimp)
{
gimp_show_message (gimp, NULL, GIMP_MESSAGE_WARNING, NULL, message);
}
else
{
g_printerr ("%s: %s\n\n",
gimp_filename_to_utf8 (full_prog_name), message);
}
}
static void
gimp_error_log_func (const gchar *domain,
GLogLevelFlags flags,
const gchar *message,
gpointer data)
{
gimp_fatal_error (message);
}
static void
gimp_eek (const gchar *reason,
const gchar *message,
gboolean use_handler)
{
#ifndef G_OS_WIN32
g_printerr ("%s: %s: %s\n", gimp_filename_to_utf8 (full_prog_name),
reason, message);
if (use_handler)
{
switch (stack_trace_mode)
{
case GIMP_STACK_TRACE_NEVER:
break;
case GIMP_STACK_TRACE_QUERY:
{
sigset_t sigset;
sigemptyset (&sigset);
sigprocmask (SIG_SETMASK, &sigset, NULL);
if (the_errors_gimp)
gimp_gui_ungrab (the_errors_gimp);
g_on_error_query (full_prog_name);
}
break;
case GIMP_STACK_TRACE_ALWAYS:
{
sigset_t sigset;
sigemptyset (&sigset);
sigprocmask (SIG_SETMASK, &sigset, NULL);
g_on_error_stack_trace (full_prog_name);
}
break;
default:
break;
}
}
#else
/* g_on_error_* don't do anything reasonable on Win32. */
MessageBox (NULL, g_strdup_printf ("%s: %s", reason, message),
full_prog_name, MB_OK|MB_ICONERROR);
#endif /* ! G_OS_WIN32 */
exit (EXIT_FAILURE);
}