gimp.c 36.4 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
Nate Summers's avatar
Nate Summers committed
2
 * Copyright (C) 1995-2002 Spencer Kimball, Peter Mattis, and others
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 17 18 19
 */

#include "config.h"

Hans Breuer's avatar
updated  
Hans Breuer committed
20 21
#include <string.h> /* strlen */

22
#include <gdk-pixbuf/gdk-pixbuf.h>
23
#include <gegl.h>
24

25
#include "libgimpbase/gimpbase.h"
26
#include "libgimpbase/gimpbase-private.h"
27
#include "libgimpconfig/gimpconfig.h"
28

29
#include "core-types.h"
30

31 32
#include "config/gimprc.h"

33
#include "gegl/gimp-babl.h"
34

35 36
#include "pdb/gimppdb.h"
#include "pdb/gimp-pdb-compat.h"
37
#include "pdb/internal-procs.h"
38

39
#include "plug-in/gimppluginmanager.h"
40
#include "plug-in/gimppluginmanager-restore.h"
41

42
#include "paint/gimp-paint.h"
43

Michael Natterer's avatar
Michael Natterer committed
44
#include "xcf/xcf.h"
45
#include "file-data/file-data.h"
Michael Natterer's avatar
Michael Natterer committed
46

47
#include "gimp.h"
48
#include "gimp-contexts.h"
49
#include "gimp-data-factories.h"
50
#include "gimp-filter-history.h"
51
#include "gimp-memsize.h"
52
#include "gimp-modules.h"
53
#include "gimp-parasites.h"
54
#include "gimp-templates.h"
55
#include "gimp-units.h"
56
#include "gimp-utils.h"
57
#include "gimpbrush.h"
58
#include "gimpbuffer.h"
Michael Natterer's avatar
Michael Natterer committed
59
#include "gimpcontext.h"
Michael Natterer's avatar
Michael Natterer committed
60
#include "gimpdynamics.h"
61
#include "gimpdocumentlist.h"
62
#include "gimpextensionmanager.h"
63
#include "gimpgradient.h"
Martin Nordholts's avatar
Martin Nordholts committed
64
#include "gimpidtable.h"
65
#include "gimpimage.h"
Michael Natterer's avatar
Michael Natterer committed
66
#include "gimpimagefile.h"
67
#include "gimplist.h"
68
#include "gimpmarshal.h"
69
#include "gimpmybrush.h"
70 71 72
#include "gimppalette.h"
#include "gimpparasitelist.h"
#include "gimppattern.h"
73
#include "gimptemplate.h"
74
#include "gimptoolinfo.h"
75
#include "gimptreeproxy.h"
76

77
#include "gimp-intl.h"
78 79


80 81 82 83 84 85 86 87
/*  we need to register all enum types so they are known to the type
 *  system by name, re-use the files the pdb generated for libgimp
 */
void           gimp_enums_init           (void);
const gchar ** gimp_enums_get_type_names (gint *n_type_names);
#include "libgimp/gimpenums.c.tail"


88 89
enum
{
90 91
  INITIALIZE,
  RESTORE,
92
  EXIT,
93
  CLIPBOARD_CHANGED,
94
  FILTER_HISTORY_CHANGED,
95
  IMAGE_OPENED,
96 97 98
  LAST_SIGNAL
};

99 100 101 102 103
enum
{
  PROP_0,
  PROP_VERBOSE
};
104

105 106 107 108 109 110 111 112 113 114

static void      gimp_constructed          (GObject           *object);
static void      gimp_set_property         (GObject           *object,
                                            guint              property_id,
                                            const GValue      *value,
                                            GParamSpec        *pspec);
static void      gimp_get_property         (GObject           *object,
                                            guint              property_id,
                                            GValue            *value,
                                            GParamSpec        *pspec);
115 116
static void      gimp_dispose              (GObject           *object);
static void      gimp_finalize             (GObject           *object);
117

118 119
static gint64    gimp_get_memsize          (GimpObject        *object,
                                            gint64            *gui_size);
120

121 122 123 124 125 126
static void      gimp_real_initialize      (Gimp              *gimp,
                                            GimpInitStatusFunc status_callback);
static void      gimp_real_restore         (Gimp              *gimp,
                                            GimpInitStatusFunc status_callback);
static gboolean  gimp_real_exit            (Gimp              *gimp,
                                            gboolean           force);
127

128 129 130 131 132 133
static void      gimp_global_config_notify (GObject           *global_config,
                                            GParamSpec        *param_spec,
                                            GObject           *edit_config);
static void      gimp_edit_config_notify   (GObject           *edit_config,
                                            GParamSpec        *param_spec,
                                            GObject           *global_config);
134 135


136
G_DEFINE_TYPE (Gimp, gimp, GIMP_TYPE_OBJECT)
137 138

#define parent_class gimp_parent_class
139

140 141
static guint gimp_signals[LAST_SIGNAL] = { 0, };

142 143 144 145

static void
gimp_class_init (GimpClass *klass)
{
146 147
  GObjectClass    *object_class      = G_OBJECT_CLASS (klass);
  GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
148

149 150 151 152 153
  gimp_signals[INITIALIZE] =
    g_signal_new ("initialize",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, initialize),
154
                  NULL, NULL, NULL,
155 156 157 158 159 160 161 162
                  G_TYPE_NONE, 1,
                  G_TYPE_POINTER);

  gimp_signals[RESTORE] =
    g_signal_new ("restore",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, restore),
163
                  NULL, NULL, NULL,
164 165
                  G_TYPE_NONE, 1,
                  G_TYPE_POINTER);
166

167 168 169 170 171
  gimp_signals[EXIT] =
    g_signal_new ("exit",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, exit),
172
                  g_signal_accumulator_true_handled, NULL,
173 174 175 176
                  gimp_marshal_BOOLEAN__BOOLEAN,
                  G_TYPE_BOOLEAN, 1,
                  G_TYPE_BOOLEAN);

177 178
  gimp_signals[CLIPBOARD_CHANGED] =
    g_signal_new ("clipboard-changed",
179 180
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
181
                  G_STRUCT_OFFSET (GimpClass, clipboard_changed),
182
                  NULL, NULL, NULL,
183 184
                  G_TYPE_NONE, 0);

185 186 187 188 189 190
  gimp_signals[FILTER_HISTORY_CHANGED] =
    g_signal_new ("filter-history-changed",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass,
                                   filter_history_changed),
191
                  NULL, NULL, NULL,
192 193
                  G_TYPE_NONE, 0);

194 195 196 197 198
  gimp_signals[IMAGE_OPENED] =
    g_signal_new ("image-opened",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, image_opened),
199
                  NULL, NULL, NULL,
200
                  G_TYPE_NONE, 1, G_TYPE_FILE);
201

202 203 204
  object_class->constructed      = gimp_constructed;
  object_class->set_property     = gimp_set_property;
  object_class->get_property     = gimp_get_property;
205 206 207 208
  object_class->dispose          = gimp_dispose;
  object_class->finalize         = gimp_finalize;

  gimp_object_class->get_memsize = gimp_get_memsize;
209

210 211
  klass->initialize              = gimp_real_initialize;
  klass->restore                 = gimp_real_restore;
212
  klass->exit                    = gimp_real_exit;
213
  klass->clipboard_changed       = NULL;
214 215 216 217 218 219

  g_object_class_install_property (object_class, PROP_VERBOSE,
                                   g_param_spec_boolean ("verbose", NULL, NULL,
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY));
220 221 222 223 224
}

static void
gimp_init (Gimp *gimp)
{
225 226 227
  gimp->be_verbose       = FALSE;
  gimp->no_data          = FALSE;
  gimp->no_interface     = FALSE;
228
  gimp->show_gui         = TRUE;
229
  gimp->use_shm          = FALSE;
230
  gimp->use_cpu_accel    = TRUE;
231
  gimp->message_handler  = GIMP_CONSOLE;
232
  gimp->show_playground  = FALSE;
233
  gimp->stack_trace_mode = GIMP_STACK_TRACE_NEVER;
234
  gimp->pdb_compat_mode  = GIMP_PDB_COMPAT_OFF;
235

236
  gimp_gui_init (gimp);
237

238
  gimp->parasites = gimp_parasite_list_new ();
239

240 241
  gimp_enums_init ();

242 243
  gimp_units_init (gimp);

244
  gimp->images = gimp_list_new_weak (GIMP_TYPE_IMAGE, FALSE);
245
  gimp_object_set_static_name (GIMP_OBJECT (gimp->images), "images");
246

247 248
  gimp->next_guide_id        = 1;
  gimp->next_sample_point_id = 1;
Martin Nordholts's avatar
Martin Nordholts committed
249
  gimp->image_table          = gimp_id_table_new ();
250
  gimp->item_table           = gimp_id_table_new ();
251

252 253 254 255 256
  gimp->displays = g_object_new (GIMP_TYPE_LIST,
                                 "children-type", GIMP_TYPE_OBJECT,
                                 "policy",        GIMP_CONTAINER_POLICY_WEAK,
                                 "append",        TRUE,
                                 NULL);
257
  gimp_object_set_static_name (GIMP_OBJECT (gimp->displays), "displays");
258
  gimp->next_display_id = 1;
259

260
  gimp->named_buffers = gimp_list_new (GIMP_TYPE_BUFFER, TRUE);
261 262
  gimp_object_set_static_name (GIMP_OBJECT (gimp->named_buffers),
                               "named buffers");
263

264 265
  gimp_data_factories_init (gimp);

266 267 268 269
  gimp->tool_info_list = g_object_new (GIMP_TYPE_LIST,
                                       "children-type", GIMP_TYPE_TOOL_INFO,
                                       "append",        TRUE,
                                       NULL);
270 271
  gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_info_list),
                               "tool infos");
272

273 274 275 276 277 278 279
  gimp->tool_item_list = g_object_new (GIMP_TYPE_LIST,
                                       "children-type", GIMP_TYPE_TOOL_ITEM,
                                       "append",        TRUE,
                                       NULL);
  gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_item_list),
                               "tool items");

280 281 282 283 284
  gimp->tool_item_ui_list = gimp_tree_proxy_new_for_container (
    gimp->tool_item_list);
  gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_item_ui_list),
                               "ui tool items");

285 286
  gimp->documents = gimp_document_list_new (gimp);

287
  gimp->templates = gimp_list_new (GIMP_TYPE_TEMPLATE, TRUE);
288
  gimp_object_set_static_name (GIMP_OBJECT (gimp->templates), "templates");
289 290
}

291 292 293 294 295 296 297 298 299
static void
gimp_constructed (GObject *object)
{
  Gimp *gimp = GIMP (object);

  G_OBJECT_CLASS (parent_class)->constructed (object);

  gimp_modules_init (gimp);

300 301
  gimp_paint_init (gimp);

302 303 304
  gimp->extension_manager = gimp_extension_manager_new (gimp);
  gimp->plug_in_manager   = gimp_plug_in_manager_new (gimp);
  gimp->pdb               = gimp_pdb_new (gimp);
305 306

  xcf_init (gimp);
307
  file_data_init (gimp);
308

309 310
  /*  create user and default context  */
  gimp_contexts_init (gimp);
311 312 313 314 315

  /* Initialize the extension manager early as its contents may be used
   * at the very start (e.g. the splash image).
   */
  gimp_extension_manager_initialize (gimp->extension_manager);
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
}

static void
gimp_set_property (GObject           *object,
                   guint              property_id,
                   const GValue      *value,
                   GParamSpec        *pspec)
{
  Gimp *gimp = GIMP (object);

  switch (property_id)
    {
    case PROP_VERBOSE:
      gimp->be_verbose = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

static void
gimp_get_property (GObject    *object,
                   guint       property_id,
                   GValue     *value,
                   GParamSpec *pspec)
{
  Gimp *gimp = GIMP (object);

  switch (property_id)
    {
    case PROP_VERBOSE:
      g_value_set_boolean (value, gimp->be_verbose);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

358
static void
359 360
gimp_dispose (GObject *object)
{
361
  Gimp *gimp = GIMP (object);
362

363 364 365
  if (gimp->be_verbose)
    g_print ("EXIT: %s\n", G_STRFUNC);

366
  gimp_data_factories_clear (gimp);
Alexia Death's avatar
Alexia Death committed
367

368 369
  gimp_filter_history_clear (gimp);

370 371
  g_clear_object (&gimp->edit_config);
  g_clear_object (&gimp->config);
372 373 374

  gimp_contexts_exit (gimp);

375
  g_clear_object (&gimp->image_new_last_template);
376

377 378 379 380 381 382
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gimp_finalize (GObject *object)
{
383 384
  Gimp  *gimp      = GIMP (object);
  GList *standards = NULL;
385

386
  if (gimp->be_verbose)
387
    g_print ("EXIT: %s\n", G_STRFUNC);
388

389 390 391 392
  standards = g_list_prepend (standards,
                              gimp_brush_get_standard (gimp->user_context));
  standards = g_list_prepend (standards,
                              gimp_dynamics_get_standard (gimp->user_context));
393 394
  standards = g_list_prepend (standards,
                              gimp_mybrush_get_standard (gimp->user_context));
395 396 397 398 399 400 401
  standards = g_list_prepend (standards,
                              gimp_pattern_get_standard (gimp->user_context));
  standards = g_list_prepend (standards,
                              gimp_gradient_get_standard (gimp->user_context));
  standards = g_list_prepend (standards,
                              gimp_palette_get_standard (gimp->user_context));

402 403
  g_clear_object (&gimp->templates);
  g_clear_object (&gimp->documents);
Michael Natterer's avatar
Michael Natterer committed
404

405 406
  gimp_tool_info_set_standard (gimp, NULL);

407 408 409
  g_clear_object (&gimp->tool_item_list);
  g_clear_object (&gimp->tool_item_ui_list);

410 411
  if (gimp->tool_info_list)
    {
412 413
      gimp_container_foreach (gimp->tool_info_list,
                              (GFunc) g_object_run_dispose, NULL);
414
      g_clear_object (&gimp->tool_info_list);
415 416
    }

417
  file_data_exit (gimp);
Michael Natterer's avatar
Michael Natterer committed
418 419
  xcf_exit (gimp);

420
  g_clear_object (&gimp->pdb);
Michael Natterer's avatar
Michael Natterer committed
421

422
  gimp_data_factories_exit (gimp);
423

424 425 426 427 428 429 430 431
  g_clear_object (&gimp->named_buffers);
  g_clear_object (&gimp->clipboard_buffer);
  g_clear_object (&gimp->clipboard_image);
  g_clear_object (&gimp->displays);
  g_clear_object (&gimp->item_table);
  g_clear_object (&gimp->image_table);
  g_clear_object (&gimp->images);
  g_clear_object (&gimp->plug_in_manager);
432
  g_clear_object (&gimp->extension_manager);
433

434
  if (gimp->module_db)
Michael Natterer's avatar
Michael Natterer committed
435 436
    gimp_modules_exit (gimp);

437
  gimp_paint_exit (gimp);
438

439 440
  g_clear_object (&gimp->parasites);
  g_clear_object (&gimp->default_folder);
441

442
  g_clear_pointer (&gimp->session_name, g_free);
443

Sven Neumann's avatar
Sven Neumann committed
444 445
  if (gimp->context_list)
    {
446 447 448 449 450 451 452 453
      GList *list;

      g_warning ("%s: list of contexts not empty upon exit (%d contexts left)\n",
                 G_STRFUNC, g_list_length (gimp->context_list));

      for (list = gimp->context_list; list; list = g_list_next (list))
        g_printerr ("stale context: %s\n", gimp_object_get_name (list->data));

Sven Neumann's avatar
Sven Neumann committed
454 455 456 457
      g_list_free (gimp->context_list);
      gimp->context_list = NULL;
    }

458 459 460
  g_list_foreach (standards, (GFunc) g_object_unref, NULL);
  g_list_free (standards);

461
  gimp_units_exit (gimp);
462

463
  G_OBJECT_CLASS (parent_class)->finalize (object);
464 465
}

466
static gint64
467
gimp_get_memsize (GimpObject *object,
468
                  gint64     *gui_size)
469
{
470
  Gimp   *gimp    = GIMP (object);
471
  gint64  memsize = 0;
472

473
  memsize += gimp_g_list_get_memsize (gimp->user_units, 0 /* FIXME */);
474

475 476
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->parasites),
                                      gui_size);
477

478 479 480
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->paint_info_list),
                                      gui_size);

481
  memsize += gimp_g_object_get_memsize (G_OBJECT (gimp->module_db));
482 483
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->plug_in_manager),
                                      gui_size);
484

485 486 487 488 489
  memsize += gimp_g_list_get_memsize_foreach (gimp->filter_history,
                                              (GimpMemsizeFunc)
                                              gimp_object_get_memsize,
                                              gui_size);

Martin Nordholts's avatar
Martin Nordholts committed
490 491
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->image_table), 0);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->item_table),  0);
492

493
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->displays), gui_size);
494

495 496
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->clipboard_image),
                                      gui_size);
497
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->clipboard_buffer),
498
                                      gui_size);
499 500
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->named_buffers),
                                      gui_size);
501

502
  memsize += gimp_data_factories_get_memsize (gimp, gui_size);
503

504
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->pdb), gui_size);
505

506 507 508 509 510 511 512 513 514 515
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->tool_info_list),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->standard_tool_info),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->documents),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->templates),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->image_new_last_template),
                                      gui_size);
516

517
  memsize += gimp_g_list_get_memsize (gimp->context_list, 0);
518

519 520 521 522
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->default_context),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->user_context),
                                      gui_size);
523

524 525
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
526 527
}

528 529 530 531 532
static void
gimp_real_initialize (Gimp               *gimp,
                      GimpInitStatusFunc  status_callback)
{
  if (gimp->be_verbose)
533
    g_print ("INIT: %s\n", G_STRFUNC);
534

535 536
  status_callback (_("Initialization"), NULL, 0.0);

537
  /*  set the last values used to default values  */
538 539
  gimp->image_new_last_template =
    gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image));
540

541 542
  /*  add data objects that need the user context  */
  gimp_data_factories_add_builtin (gimp);
543

544
  /*  register all internal procedures  */
Sven Neumann's avatar
Sven Neumann committed
545
  status_callback (NULL, _("Internal Procedures"), 0.2);
546 547
  internal_procs_init (gimp->pdb);
  gimp_pdb_compat_procs_register (gimp->pdb, gimp->pdb_compat_mode);
548

549
  gimp_plug_in_manager_initialize (gimp->plug_in_manager, status_callback);
550 551

  status_callback (NULL, "", 1.0);
552 553 554 555
}

static void
gimp_real_restore (Gimp               *gimp,
556
                   GimpInitStatusFunc  status_callback)
557 558
{
  if (gimp->be_verbose)
559
    g_print ("INIT: %s\n", G_STRFUNC);
560

561 562
  gimp_plug_in_manager_restore (gimp->plug_in_manager,
                                gimp_get_user_context (gimp), status_callback);
563

564 565 566 567
  /*  initialize babl fishes  */
  status_callback (_("Initialization"), "Babl Fishes", 0.0);
  gimp_babl_init_fishes (status_callback);

568
  gimp->restored = TRUE;
569 570
}

571 572
static gboolean
gimp_real_exit (Gimp     *gimp,
573
                gboolean  force)
574
{
575
  if (gimp->be_verbose)
576
    g_print ("EXIT: %s\n", G_STRFUNC);
577

578
  gimp_plug_in_manager_exit (gimp->plug_in_manager);
579
  gimp_extension_manager_exit (gimp->extension_manager);
580
  gimp_modules_unload (gimp);
581

582
  gimp_data_factories_save (gimp);
Alexia Death's avatar
Alexia Death committed
583

584
  gimp_templates_save (gimp);
585 586 587 588 589 590
  gimp_parasiterc_save (gimp);
  gimp_unitrc_save (gimp);

  return FALSE; /* continue exiting */
}

591
Gimp *
592
gimp_new (const gchar       *name,
593
          const gchar       *session_name,
594
          GFile             *default_folder,
595
          gboolean           be_verbose,
Michael Natterer's avatar
Michael Natterer committed
596
          gboolean           no_data,
597
          gboolean           no_fonts,
Michael Natterer's avatar
Michael Natterer committed
598
          gboolean           no_interface,
599
          gboolean           use_shm,
600
          gboolean           use_cpu_accel,
601
          gboolean           console_messages,
602
          gboolean           show_playground,
603
          gboolean           show_debug_menu,
604 605
          GimpStackTraceMode stack_trace_mode,
          GimpPDBCompatMode  pdb_compat_mode)
606 607 608
{
  Gimp *gimp;

609 610
  g_return_val_if_fail (name != NULL, NULL);

611
  gimp = g_object_new (GIMP_TYPE_GIMP,
612 613
                       "name",    name,
                       "verbose", be_verbose ? TRUE : FALSE,
614
                       NULL);
615

616 617 618
  if (default_folder)
    gimp->default_folder = g_object_ref (default_folder);

619
  gimp->session_name     = g_strdup (session_name);
620
  gimp->no_data          = no_data          ? TRUE : FALSE;
621
  gimp->no_fonts         = no_fonts         ? TRUE : FALSE;
622 623
  gimp->no_interface     = no_interface     ? TRUE : FALSE;
  gimp->use_shm          = use_shm          ? TRUE : FALSE;
624
  gimp->use_cpu_accel    = use_cpu_accel    ? TRUE : FALSE;
625
  gimp->console_messages = console_messages ? TRUE : FALSE;
626
  gimp->show_playground  = show_playground  ? TRUE : FALSE;
627
  gimp->show_debug_menu  = show_debug_menu  ? TRUE : FALSE;
Michael Natterer's avatar
Michael Natterer committed
628
  gimp->stack_trace_mode = stack_trace_mode;
629
  gimp->pdb_compat_mode  = pdb_compat_mode;
Michael Natterer's avatar
Michael Natterer committed
630

631 632 633
  return gimp;
}

634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
/**
 * gimp_set_show_gui:
 * @gimp:
 * @show:
 *
 * Test cases that tests the UI typically don't want any windows to be
 * presented during the test run. Allow them to set this.
 **/
void
gimp_set_show_gui (Gimp     *gimp,
                   gboolean  show_gui)
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));

  gimp->show_gui = show_gui;
}

/**
 * gimp_get_show_gui:
 * @gimp:
 *
 * Returns: %TRUE if the GUI should be shown, %FALSE otherwise.
 **/
gboolean
gimp_get_show_gui (Gimp *gimp)
{
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);

  return gimp->show_gui;
}

665 666 667 668 669
static void
gimp_global_config_notify (GObject    *global_config,
                           GParamSpec *param_spec,
                           GObject    *edit_config)
{
670 671
  GValue global_value = G_VALUE_INIT;
  GValue edit_value   = G_VALUE_INIT;
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700

  g_value_init (&global_value, param_spec->value_type);
  g_value_init (&edit_value,   param_spec->value_type);

  g_object_get_property (global_config, param_spec->name, &global_value);
  g_object_get_property (edit_config,   param_spec->name, &edit_value);

  if (g_param_values_cmp (param_spec, &global_value, &edit_value))
    {
      g_signal_handlers_block_by_func (edit_config,
                                       gimp_edit_config_notify,
                                       global_config);

      g_object_set_property (edit_config, param_spec->name, &global_value);

      g_signal_handlers_unblock_by_func (edit_config,
                                         gimp_edit_config_notify,
                                         global_config);
    }

  g_value_unset (&global_value);
  g_value_unset (&edit_value);
}

static void
gimp_edit_config_notify (GObject    *edit_config,
                         GParamSpec *param_spec,
                         GObject    *global_config)
{
701 702
  GValue edit_value   = G_VALUE_INIT;
  GValue global_value = G_VALUE_INIT;
703 704 705 706 707 708 709 710 711

  g_value_init (&edit_value,   param_spec->value_type);
  g_value_init (&global_value, param_spec->value_type);

  g_object_get_property (edit_config,   param_spec->name, &edit_value);
  g_object_get_property (global_config, param_spec->name, &global_value);

  if (g_param_values_cmp (param_spec, &edit_value, &global_value))
    {
712
      if (param_spec->flags & GIMP_CONFIG_PARAM_RESTART)
713
        {
Sven Neumann's avatar
Sven Neumann committed
714
#ifdef GIMP_CONFIG_DEBUG
715 716 717
          g_print ("NOT Applying edit_config change of '%s' to global_config "
                   "because it needs restart\n",
                   param_spec->name);
Sven Neumann's avatar
Sven Neumann committed
718
#endif
719 720 721
        }
      else
        {
Sven Neumann's avatar
Sven Neumann committed
722
#ifdef GIMP_CONFIG_DEBUG
723 724
          g_print ("Applying edit_config change of '%s' to global_config\n",
                   param_spec->name);
Sven Neumann's avatar
Sven Neumann committed
725
#endif
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
          g_signal_handlers_block_by_func (global_config,
                                           gimp_global_config_notify,
                                           edit_config);

          g_object_set_property (global_config, param_spec->name, &edit_value);

          g_signal_handlers_unblock_by_func (global_config,
                                             gimp_global_config_notify,
                                             edit_config);
        }
    }

  g_value_unset (&edit_value);
  g_value_unset (&global_value);
}

void
743 744 745
gimp_load_config (Gimp  *gimp,
                  GFile *alternate_system_gimprc,
                  GFile *alternate_gimprc)
746
{
747 748
  GimpRc *gimprc;

749
  g_return_if_fail (GIMP_IS_GIMP (gimp));
750 751 752 753
  g_return_if_fail (alternate_system_gimprc == NULL ||
                    G_IS_FILE (alternate_system_gimprc));
  g_return_if_fail (alternate_gimprc == NULL ||
                    G_IS_FILE (alternate_gimprc));
754 755 756
  g_return_if_fail (gimp->config == NULL);
  g_return_if_fail (gimp->edit_config == NULL);

757
  if (gimp->be_verbose)
758
    g_print ("INIT: %s\n", G_STRFUNC);
759 760 761 762 763 764

  /*  this needs to be done before gimprc loading because gimprc can
   *  use user defined units
   */
  gimp_unitrc_load (gimp);

765 766
  gimprc = gimp_rc_new (G_OBJECT (gimp),
                        alternate_system_gimprc,
767 768 769 770
                        alternate_gimprc,
                        gimp->be_verbose);

  gimp->config = GIMP_CORE_CONFIG (gimprc);
771

772
  gimp->edit_config = gimp_config_duplicate (GIMP_CONFIG (gimp->config));
773 774 775 776 777 778 779

  g_signal_connect_object (gimp->config, "notify",
                           G_CALLBACK (gimp_global_config_notify),
                           gimp->edit_config, 0);
  g_signal_connect_object (gimp->edit_config, "notify",
                           G_CALLBACK (gimp_edit_config_notify),
                           gimp->config, 0);
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807

  if (! gimp->show_playground)
    {
      gboolean    use_opencl;
      gboolean    use_npd_tool;
      gboolean    use_seamless_clone_tool;

      /* Playground preferences is shown by default for unstable
       * versions and if the associated CLI option was set. Additionally
       * we want to show it if any of the playground options had been
       * enabled. Otherwise you might end up getting blocked with a
       * playground feature and forget where you can even disable it.
       *
       * Also we check this once at start when loading config, and not
       * inside preferences-dialog.c because we don't want to end up
       * with inconsistent behavior where you open once the Preferences,
       * deactivate features, then back to preferences and the tab is
       * gone.
       */

      g_object_get (gimp->edit_config,
                    "use-opencl",                     &use_opencl,
                    "playground-npd-tool",            &use_npd_tool,
                    "playground-seamless-clone-tool", &use_seamless_clone_tool,
                    NULL);
      if (use_opencl || use_npd_tool || use_seamless_clone_tool)
        gimp->show_playground = TRUE;
    }
808 809
}

810
void
811 812
gimp_initialize (Gimp               *gimp,
                 GimpInitStatusFunc  status_callback)
813 814
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));
815
  g_return_if_fail (status_callback != NULL);
816
  g_return_if_fail (GIMP_IS_CORE_CONFIG (gimp->config));
817

818
  if (gimp->be_verbose)
819
    g_print ("INIT: %s\n", G_STRFUNC);
820

821
  g_signal_emit (gimp, gimp_signals[INITIALIZE], 0, status_callback);
822 823
}

824 825 826 827 828 829 830 831 832
/**
 * gimp_restore:
 * @gimp: a #Gimp object
 * @error: a #GError for uncessful loading.
 *
 * This function always succeeds. If present, @error may be filled for
 * possible feedback on data which failed to load. It doesn't imply any
 * fatale error.
 **/
833
void
834 835 836
gimp_restore (Gimp                *gimp,
              GimpInitStatusFunc   status_callback,
              GError             **error)
837 838
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));
839
  g_return_if_fail (status_callback != NULL);
840

841
  if (gimp->be_verbose)
842
    g_print ("INIT: %s\n", G_STRFUNC);
843

844
  /*  initialize  the global parasite table  */
845
  status_callback (_("Looking for data files"), _("Parasites"), 0.0);
846
  gimp_parasiterc_load (gimp);
847

848 849
  /*  initialize the lists of gimp brushes, dynamics, patterns etc.  */
  gimp_data_factories_load (gimp, status_callback);
Alexia Death's avatar
Alexia Death committed
850

851
  /*  initialize the template list  */
852
  status_callback (NULL, _("Templates"), 0.8);
853 854
  gimp_templates_load (gimp);

855
  /*  initialize the module list  */
856
  status_callback (NULL, _("Modules"), 0.9);
Michael Natterer's avatar
Michael Natterer committed
857
  gimp_modules_load (gimp);
858

859
  g_signal_emit (gimp, gimp_signals[RESTORE], 0, status_callback);
860 861

  /* when done, make sure everything is clean, to clean out dirty
862
   * states from data objects which reference each other and got
863 864
   * dirtied by loading the referenced object
   */
865
  gimp_data_factories_data_clean (gimp);
866
}
867

868 869 870 871
/**
 * gimp_is_restored:
 * @gimp: a #Gimp object
 *
872
 * Returns: %TRUE if GIMP is completely started, %FALSE otherwise.
873 874 875 876 877 878 879 880 881
 **/
gboolean
gimp_is_restored (Gimp *gimp)
{
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);

  return gimp->restored;
}

882 883 884 885 886 887 888 889
/**
 * gimp_exit:
 * @gimp: a #Gimp object
 * @force: whether to force the application to quit
 *
 * Exit this GIMP session. Unless @force is %TRUE, the user is queried
 * whether unsaved images should be saved and can cancel the operation.
 **/
890
void
891
gimp_exit (Gimp     *gimp,
892
           gboolean  force)
893
{
894 895
  gboolean  handled;
  GList    *image_iter;
896

897 898
  g_return_if_fail (GIMP_IS_GIMP (gimp));