app_procs.c 10.6 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 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
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
18

19
#include "config.h"
20

Elliot Lee's avatar
Elliot Lee committed
21
22
#include <stdio.h>
#include <string.h>
23
#include <stdlib.h>
24

25
#ifdef HAVE_SYS_PARAM_H
Elliot Lee's avatar
Elliot Lee committed
26
#include <sys/param.h>
27
#endif
28

29
30
31
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
Elliot Lee's avatar
Elliot Lee committed
32

33
#include <glib-object.h>
34

35
#include "libgimpbase/gimpbase.h"
36

37
#include "core/core-types.h"
38

39
40
#include "config/gimprc.h"

41
42
#include "base/base.h"

43
#include "core/gimp.h"
Michael Natterer's avatar
Michael Natterer committed
44

Michael Natterer's avatar
Michael Natterer committed
45
#include "file/file-open.h"
46
#include "file/file-utils.h"
Michael Natterer's avatar
Michael Natterer committed
47

48
#ifndef GIMP_CONSOLE_COMPILATION
49
50
#include "dialogs/user-install-dialog.h"

51
#include "gui/gui.h"
52
#endif
53

Elliot Lee's avatar
Elliot Lee committed
54
55
#include "app_procs.h"
#include "batch.h"
56
#include "errors.h"
57
#include "units.h"
Elliot Lee's avatar
Elliot Lee committed
58

59
#include "gimp-intl.h"
60

61
62
63
#ifdef G_OS_WIN32
#include <windows.h>
#endif
64

65

Michael Natterer's avatar
Michael Natterer committed
66
/*  local prototypes  */
Elliot Lee's avatar
Elliot Lee committed
67

68
69
70
71
static void       app_init_update_none    (const gchar *text1,
                                           const gchar *text2,
                                           gdouble      percentage);
static gboolean   app_exit_after_callback (Gimp        *gimp,
72
73
                                           gboolean     kill_it,
                                           GMainLoop   *loop);
Elliot Lee's avatar
Elliot Lee committed
74

75

Michael Natterer's avatar
Michael Natterer committed
76
/*  public functions  */
77

78
gboolean
79
80
81
app_libs_init (gboolean   *no_interface,
               gint       *argc,
               gchar    ***argv)
82
{
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#ifdef GIMP_CONSOLE_COMPILATION
  *no_interface = TRUE;
#endif

  if (*no_interface)
    {
      gchar *basename;

      basename = g_path_get_basename ((*argv)[0]);
      g_set_prgname (basename);
      g_free (basename);

      g_type_init ();

      return TRUE;
    }
#ifndef GIMP_CONSOLE_COMPILATION
  else
    {
      return gui_libs_init (argc, argv);
    }
#endif

  return FALSE;
107
108
}

109
void
110
111
app_abort (gboolean     no_interface,
           const gchar *abort_message)
112
{
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef GIMP_CONSOLE_COMPILATION
  if (no_interface)
#endif
    {
      g_print ("%s\n\n", abort_message);
    }
#ifndef GIMP_CONSOLE_COMPILATION
  else
    {
      gui_abort (abort_message);
    }
#endif

  app_exit (EXIT_FAILURE);
}

void
app_exit (gint status)
{
#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 (status);
150
151
}

152
void
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
app_run (const gchar         *full_prog_name,
         gint                 gimp_argc,
         gchar              **gimp_argv,
         const gchar         *alternate_system_gimprc,
         const gchar         *alternate_gimprc,
         const gchar         *session_name,
         const gchar        **batch_cmds,
         gboolean             no_interface,
         gboolean             no_data,
         gboolean             no_fonts,
         gboolean             no_splash,
         gboolean             be_verbose,
         gboolean             use_shm,
         gboolean             use_cpu_accel,
         gboolean             console_messages,
168
169
         GimpStackTraceMode   stack_trace_mode,
         GimpPDBCompatMode    pdb_compat_mode)
Elliot Lee's avatar
Elliot Lee committed
170
{
171
172
173
  GimpInitStatusFunc  update_status_func = NULL;
  Gimp               *gimp;
  GMainLoop          *loop;
174
  gboolean            swap_is_ok;
175
176
177
  gint                i;

  const gchar *log_domains[] =
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  {
    "Gimp",
    "Gimp-Actions",
    "Gimp-Base",
    "Gimp-Composite",
    "Gimp-Config",
    "Gimp-Core",
    "Gimp-Display",
    "Gimp-File",
    "Gimp-GUI",
    "Gimp-Menus",
    "Gimp-PDB",
    "Gimp-Paint-Funcs",
    "Gimp-Plug-In",
    "Gimp-Text",
    "Gimp-Tools",
    "Gimp-Vectors",
    "Gimp-Widgets",
    "Gimp-XCF"
  };
198
199
200
201

  /*  Create an instance of the "Gimp" object which is the root of the
   *  core object system
   */
202
203
204
205
206
207
208
209
  gimp = gimp_new (full_prog_name,
                   session_name,
                   be_verbose,
                   no_data,
                   no_fonts,
                   no_interface,
                   use_shm,
                   console_messages,
210
211
                   stack_trace_mode,
                   pdb_compat_mode);
212

213
  for (i = 0; i < G_N_ELEMENTS (log_domains); i++)
214
    g_log_set_handler (log_domains[i],
215
216
                       G_LOG_LEVEL_MESSAGE,
                       gimp_message_log_func, &gimp);
217
218
219

  g_log_set_handler (NULL,
		     G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
220
		     gimp_error_log_func, &gimp);
221

222
  units_init (gimp);
223

224
  /*  Check if the user's gimp_directory exists
225
   */
226
  if (! g_file_test (gimp_directory (), G_FILE_TEST_IS_DIR))
227
228
229
    {
      /*  not properly installed  */

230
#ifndef GIMP_CONSOLE_COMPILATION
231
      if (no_interface)
232
#endif
233
	{
234
235
236
          const gchar *msg;

          msg = _("GIMP is not properly installed for the current user.\n"
Sven Neumann's avatar
Sven Neumann committed
237
238
                  "User installation was skipped because the '--no-interface' flag was used.\n"
                  "To perform user installation, run the GIMP without the '--no-interface' flag.");
239

240
          g_printerr ("%s\n\n", msg);
241
	}
242
#ifndef GIMP_CONSOLE_COMPILATION
243
244
      else
	{
245
246
247
          user_install_dialog_run (alternate_system_gimprc,
                                   alternate_gimprc,
                                   be_verbose);
248
	}
249
#endif
250
    }
Manish Singh's avatar
Manish Singh committed
251

252
253
254
255
256
257
258
259
260
261
#if defined G_OS_WIN32 && !defined GIMP_CONSOLE_COMPILATION
  /* 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 benefits (like inheriting the console) but hide
   * it, if the user doesn't want it.
   */
  if (!no_interface && !be_verbose && !console_messages)
    FreeConsole ();
#endif

262
  gimp_load_config (gimp, alternate_system_gimprc, alternate_gimprc);
263
264

  /*  initialize lowlevel stuff  */
265
266
  swap_is_ok = base_init (GIMP_BASE_CONFIG (gimp->config),
                          be_verbose, use_cpu_accel);
267

268
#ifndef GIMP_CONSOLE_COMPILATION
Michael Natterer's avatar
Michael Natterer committed
269
  if (! no_interface)
270
    update_status_func = gui_init (gimp, no_splash);
271
#endif
272

273
274
  if (! update_status_func)
    update_status_func = app_init_update_none;
275

276
277
  /*  Create all members of the global Gimp instance which need an already
   *  parsed gimprc, e.g. the data factories
278
   */
279
  gimp_initialize (gimp, update_status_func);
280

281
282
  /*  Load all data files
   */
283
  gimp_restore (gimp, update_status_func);
284

285
286
287
288
289
290
291
292
  /* display a warning when no test swap file could be generated */
  if (! swap_is_ok)
    g_message (_("Unable to open a test swap file. To avoid data loss "
                 "please check the location and permissions of the swap "
                 "directory defined in your Preferences "
                 "(currently \"%s\")."),
               GIMP_BASE_CONFIG (gimp->config)->swap_path);

293
294
295
  /*  enable autosave late so we don't autosave when the
   *  monitor resolution is set in gui_init()
   */
296
  gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE);
297

298
299
  /*  Parse the rest of the command line arguments as images to load
   */
300
  if (gimp_argc > 0)
Michael Natterer's avatar
Michael Natterer committed
301
    {
302
      gint i;
Michael Natterer's avatar
Michael Natterer committed
303
304
305
306
307

      for (i = 0; i < gimp_argc; i++)
        {
          if (gimp_argv[i])
            {
308
309
              GError *error = NULL;
              gchar  *uri;
310

311
312
313
314
315
316
317
318
319
320
              /*  first try if we got a file uri  */
              uri = g_filename_from_uri (gimp_argv[i], NULL, NULL);

              if (uri)
                {
                  g_free (uri);
                  uri = g_strdup (gimp_argv[i]);
                }
              else
                {
321
                  uri = file_utils_filename_to_uri (gimp->load_procs,
322
323
                                                    gimp_argv[i], &error);
                }
324

325
              if (! uri)
326
                {
327
328
                  g_printerr ("conversion filename -> uri failed: %s\n",
                              error->message);
329
                  g_clear_error (&error);
330
                }
331
332
              else
                {
333
334
                  GimpImage         *gimage;
                  GimpPDBStatusType  status;
335

336
337
                  gimage = file_open_with_display (gimp,
                                                   gimp_get_user_context (gimp),
338
                                                   NULL,
339
                                                   uri,
340
341
342
343
                                                   &status, &error);

                  if (! gimage && status != GIMP_PDB_CANCEL)
                    {
344
                      gchar *filename = file_utils_uri_to_utf8_filename (uri);
345

346
                      g_message (_("Opening '%s' failed: %s"),
347
348
349
350
351
                                 filename, error->message);
                      g_clear_error (&error);

                      g_free (filename);
                   }
352

353
354
                  g_free (uri);
                }
Michael Natterer's avatar
Michael Natterer committed
355
356
357
            }
        }
    }
358

359
#ifndef GIMP_CONSOLE_COMPILATION
360
361
  if (! no_interface)
    gui_post_init (gimp);
362
#endif
363

364
  batch_run (gimp, batch_cmds);
365

366
  loop = g_main_loop_new (NULL, FALSE);
367
368
369
370

  g_signal_connect_after (gimp, "exit",
                          G_CALLBACK (app_exit_after_callback),
                          loop);
371

372
373
374
  gimp_threads_leave (gimp);
  g_main_loop_run (loop);
  gimp_threads_enter (gimp);
375

376
  g_main_loop_unref (loop);
377

378
  g_object_unref (gimp);
379
  base_exit ();
Elliot Lee's avatar
Elliot Lee committed
380
381
}

382

Michael Natterer's avatar
Michael Natterer committed
383
/*  private functions  */
384

385
386
387
388
389
static void
app_init_update_none (const gchar *text1,
                      const gchar *text2,
                      gdouble      percentage)
{
Michael Natterer's avatar
Michael Natterer committed
390
391
}

392
static gboolean
393
394
395
app_exit_after_callback (Gimp      *gimp,
                         gboolean   kill_it,
                         GMainLoop *loop)
Michael Natterer's avatar
Michael Natterer committed
396
{
397
398
  if (gimp->be_verbose)
    g_print ("EXIT: app_exit_after_callback\n");
Elliot Lee's avatar
Elliot Lee committed
399

400
401
402
403
404
405
406
407
408
409
  /*
   *  In stable releases, we simply call exit() here. This speeds up
   *  the process of quitting GIMP and also works around the problem
   *  that plug-ins might still be running.
   *
   *  In unstable releases, we shut down GIMP properly in an attempt
   *  to catch possible problems in our finalizers.
   */

#ifdef GIMP_UNSTABLE
410
  g_main_loop_quit (loop);
411
412
413
414
#else
  exit (EXIT_SUCCESS);
#endif

415
  return FALSE;
Elliot Lee's avatar
Elliot Lee committed
416
}