gimp/app/main.c
Sven Neumann a56949222f HACKING Makefile.am acconfig.h autogen.sh use AM_GLIB_GNU_GETTEXT. Since
2001-09-27  Sven Neumann  <sven@gimp.org>

        * HACKING
        * Makefile.am
        * acconfig.h
        * autogen.sh
        * configure.in: use AM_GLIB_GNU_GETTEXT. Since glib and GTK+ rely on
        gettext being available, we don't need to ship with the option to use
        an included implementation. The intl subdirectory will not be created
        anymore. Had to put the old sed hacks back in that create Makefiles
        from Makefile.in in the extra po directories.

        * almost all Makefile.am: removed $(top_srcdir)/intl from INCLUDES.

        * app/main.c
        * libgimp/stdplugins-intl.h
        * plug-ins/perl/Gimp.xs
        * plug-ins/script-fu/script-fu-intl.h: changed package names to
        gimp14* so the po files don't clash with gimp12.
2001-09-27 15:33:53 +00:00

486 lines
13 KiB
C

/* The GIMP -- an 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"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifndef WAIT_ANY
#define WAIT_ANY -1
#endif
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "core/core-types.h"
#include "appenv.h"
#include "app_procs.h"
#include "errors.h"
#include "libgimp/gimpintl.h"
#ifdef G_OS_WIN32
#include <windows.h>
#else
static void gimp_sigfatal_handler (gint sig_num);
static void gimp_sigchld_handler (gint sig_num);
#endif
/* command line options */
gboolean no_interface = FALSE;
gboolean no_data = FALSE;
gboolean no_splash = FALSE;
gboolean no_splash_image = FALSE;
gboolean be_verbose = FALSE;
gboolean use_shm = FALSE;
gboolean use_debug_handler = FALSE;
gboolean console_messages = FALSE;
gboolean restore_session = FALSE;
StackTraceMode stack_trace_mode = STACK_TRACE_QUERY;
gchar *alternate_gimprc = NULL;
gchar *alternate_system_gimprc = NULL;
gchar **batch_cmds = NULL;
/* other global variables */
gchar *prog_name = NULL; /* our executable name */
MessageHandlerType message_handler = CONSOLE;
gboolean double_speed = FALSE;
/*
* argv processing:
* Arguments are either switches, their associated
* values, or image files. As switches and their
* associated values are processed, those slots in
* the argv[] array are NULLed. We do this because
* unparsed args are treated as images to load on
* startup.
*
* The GTK switches are processed first (X switches are
* processed here, not by any X routines). Then the
* general GIMP switches are processed. Any args
* left are assumed to be image files the GIMP should
* display.
*
* The exception is the batch switch. When this is
* encountered, all remaining args are treated as batch
* commands.
*/
int
main (int argc,
char **argv)
{
gboolean show_version = FALSE;
gboolean show_help = FALSE;
gint i, j;
#ifdef HAVE_PUTENV
gchar *display_env;
#endif
#if 0
g_mem_set_vtable (glib_mem_profiler_table);
g_atexit (g_mem_profile);
#endif
/* Initialize variables */
prog_name = argv[0];
/* Initialize i18n support */
INIT_LOCALE (GETTEXT_PACKAGE);
#ifdef ENABLE_NLS
bindtextdomain ("gimp-libgimp", LOCALEDIR);
#endif
gtk_init (&argc, &argv);
#ifdef HAVE_PUTENV
display_env = g_strconcat ("DISPLAY=", gdk_get_display (), NULL);
putenv (display_env);
#endif
#if defined (HAVE_SHM_H) || defined (G_OS_WIN32)
use_shm = TRUE;
#endif
batch_cmds = g_new (char *, argc);
batch_cmds[0] = NULL;
for (i = 1; i < argc; i++)
{
if ((strcmp (argv[i], "--no-interface") == 0) ||
(strcmp (argv[i], "-i") == 0))
{
no_interface = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--batch") == 0) ||
(strcmp (argv[i], "-b") == 0))
{
argv[i] = NULL;
for (j = 0, i++ ; i < argc; j++, i++)
{
batch_cmds[j] = argv[i];
argv[i] = NULL;
}
batch_cmds[j] = NULL;
if (batch_cmds[0] == NULL) /* We need at least one batch command */
show_help = TRUE;
}
else if (strcmp (argv[i], "--system-gimprc") == 0)
{
argv[i] = NULL;
if (argc <= ++i)
{
show_help = TRUE;
}
else
{
alternate_system_gimprc = argv[i];
argv[i] = NULL;
}
}
else if ((strcmp (argv[i], "--gimprc") == 0) ||
(strcmp (argv[i], "-g") == 0))
{
argv[i] = NULL;
if (argc <= ++i)
{
show_help = TRUE;
}
else
{
alternate_gimprc = argv[i];
argv[i] = NULL;
}
}
else if ((strcmp (argv[i], "--help") == 0) ||
(strcmp (argv[i], "-h") == 0))
{
show_help = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--version") == 0) ||
(strcmp (argv[i], "-v") == 0))
{
show_version = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--no-data") == 0) ||
(strcmp (argv[i], "-d") == 0))
{
no_data = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--no-splash") == 0) ||
(strcmp (argv[i], "-s") == 0))
{
no_splash = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--no-splash-image") == 0) ||
(strcmp (argv[i], "-S") == 0))
{
no_splash_image = TRUE;
argv[i] = NULL;
}
else if (strcmp (argv[i], "--verbose") == 0)
{
be_verbose = TRUE;
argv[i] = NULL;
}
else if (strcmp (argv[i], "--no-shm") == 0)
{
use_shm = FALSE;
argv[i] = NULL;
}
else if (strcmp (argv[i], "--debug-handlers") == 0)
{
use_debug_handler = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--console-messages") == 0) ||
(strcmp (argv[i], "-c") == 0))
{
console_messages = TRUE;
argv[i] = NULL;
}
else if ((strcmp (argv[i], "--restore-session") == 0) ||
(strcmp (argv[i], "-r") == 0))
{
restore_session = TRUE;
argv[i] = NULL;
}
else if (strcmp (argv[i], "--enable-stack-trace") == 0)
{
argv[i] = NULL;
if (argc <= ++i)
{
show_help = TRUE;
}
else
{
if (! strcmp (argv[i], "never"))
stack_trace_mode = STACK_TRACE_NEVER;
else if (! strcmp (argv[i], "query"))
stack_trace_mode = STACK_TRACE_QUERY;
else if (! strcmp (argv[i], "always"))
stack_trace_mode = STACK_TRACE_ALWAYS;
else
show_help = TRUE;
argv[i] = NULL;
}
}
/*
* ANYTHING ELSE starting with a '-' is an error.
*/
else if (argv[i][0] == '-')
{
g_print (_("\nInvalid option \"%s\"\n"), argv[i]);
show_help = TRUE;
}
}
#ifdef G_OS_WIN32
/* Common windoze apps don't have a console at all. So does Gimp
* - if appropiate. This allows to compile as console application
* with all it's benfits (like inheriting the console) but hide
* it, if the user doesn't want it.
*/
if (!show_help && !show_version && !be_verbose && !console_messages)
FreeConsole ();
#endif
if (show_version)
{
g_print ( "%s %s\n", _("GIMP version"), GIMP_VERSION);
}
if (show_help)
{
g_print (_("\nUsage: %s [option ... ] [file ... ]\n\n"), argv[0]);
g_print (_("Options:\n"));
g_print (_(" -b, --batch <commands> Run in batch mode.\n"));
g_print (_(" -c, --console-messages Display warnings to console instead of a dialog box.\n"));
g_print (_(" -d, --no-data Do not load brushes, gradients, palettes, patterns.\n"));
g_print (_(" -i, --no-interface Run without a user interface.\n"));
g_print (_(" -g, --gimprc <gimprc> Use an alternate gimprc file.\n"));
g_print (_(" -h, --help Output this help.\n"));
g_print (_(" -r, --restore-session Try to restore saved session.\n"));
g_print (_(" -s, --no-splash Do not show the startup window.\n"));
g_print (_(" -S, --no-splash-image Do not add an image to the startup window.\n"));
g_print (_(" -v, --version Output version information.\n"));
g_print (_(" --verbose Show startup messages.\n"));
g_print (_(" --no-shm Do not use shared memory between GIMP and plugins.\n"));
g_print (_(" --no-xshm Do not use the X Shared Memory extension.\n"));
g_print (_(" --debug-handlers Enable non-fatal debugging signal handlers.\n"));
g_print (_(" --display <display> Use the designated X display.\n"));
g_print (_(" --system-gimprc <gimprc> Use an alternate system gimprc file.\n"));
g_print (" --enable-stack-trace <never | query | always>\n");
g_print (_(" Debugging mode for fatal signals.\n\n"));
}
if (show_version || show_help)
{
#ifdef G_OS_WIN32
/* Give them time to read the message if it was printed in a
* separate console window. I would really love to have
* some way of asking for confirmation to close the console
* window.
*/
HANDLE console;
DWORD mode;
console = GetStdHandle (STD_OUTPUT_HANDLE);
if (GetConsoleMode (console, &mode) != 0)
{
g_print (_("(This console window will close in ten seconds)\n"));
Sleep(10000);
}
#endif
exit (0);
}
g_log_set_handler ("Gimp",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-Base",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-Core",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-PDB",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-XCF",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-Widgets",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-Tools",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler ("Gimp-GUI",
G_LOG_LEVEL_MESSAGE,
gimp_message_log_func,
NULL);
g_log_set_handler (NULL,
G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
gimp_error_log_func,
NULL);
#ifndef G_OS_WIN32
/* No use catching these on Win32, the user won't get any
* stack trace from glib anyhow. It's better to let Windows inform
* about the program error, and offer debugging (if the user
* has installed MSVC or some other compiler that knows how to
* install itself as a handler for program errors).
*/
/* Handle fatal signals */
gimp_signal_private (SIGHUP, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGINT, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGQUIT, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGABRT, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGBUS, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGSEGV, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGTERM, gimp_sigfatal_handler, 0);
gimp_signal_private (SIGFPE, gimp_sigfatal_handler, 0);
/* Ignore SIGPIPE because plug_in.c handles broken pipes */
gimp_signal_private (SIGPIPE, SIG_IGN, 0);
/* Collect dead children */
gimp_signal_private (SIGCHLD, gimp_sigchld_handler, SA_RESTART);
#endif /* G_OS_WIN32 */
/* Initialize the application */
app_init (argc - 1,
argv + 1);
/* Main application loop */
if (! app_exit_finish_done ())
gtk_main ();
return 0;
}
#ifdef G_OS_WIN32
/* In case we build this as a windowed application */
#ifdef __GNUC__
# ifndef _stdcall
# define _stdcall __attribute__((stdcall))
# endif
#endif
int _stdcall
WinMain (struct HINSTANCE__ *hInstance,
struct HINSTANCE__ *hPrevInstance,
char *lpszCmdLine,
int nCmdShow)
{
return main (__argc, __argv);
}
#endif /* G_OS_WIN32 */
#ifndef G_OS_WIN32
/* gimp core signal handler for fatal signals */
static void
gimp_sigfatal_handler (gint sig_num)
{
switch (sig_num)
{
case SIGHUP:
case SIGINT:
case SIGQUIT:
case SIGABRT:
case SIGTERM:
gimp_terminate (g_strsignal (sig_num));
break;
case SIGBUS:
case SIGSEGV:
case SIGFPE:
default:
gimp_fatal_error (g_strsignal (sig_num));
break;
}
}
/* gimp core signal handler for death-of-child signals */
static void
gimp_sigchld_handler (gint sig_num)
{
gint pid;
gint status;
while (TRUE)
{
pid = waitpid (WAIT_ANY, &status, WNOHANG);
if (pid <= 0)
break;
}
}
#endif /* ! G_OS_WIN32 */