gimp.c 41.1 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 <http://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 "libgimpconfig/gimpconfig.h"
27

28
#include "core-types.h"
29

30 31
#include "config/gimprc.h"

32 33
#include "pdb/gimppdb.h"
#include "pdb/gimp-pdb-compat.h"
34
#include "pdb/internal-procs.h"
35

36
#include "plug-in/gimppluginmanager.h"
37
#include "plug-in/gimppluginmanager-restore.h"
38

39
#include "paint/gimp-paint.h"
40

41
#include "text/gimp-fonts.h"
42

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

45
#include "gimp.h"
46
#include "gimp-contexts.h"
47
#include "gimp-gradients.h"
48
#include "gimp-modules.h"
49
#include "gimp-parasites.h"
50
#include "gimp-templates.h"
51
#include "gimp-units.h"
52
#include "gimp-utils.h"
53
#include "gimpbrush-load.h"
54
#include "gimpbrush.h"
55
#include "gimpbrushclipboard.h"
56
#include "gimpbrushgenerated-load.h"
57
#include "gimpbrushpipe-load.h"
58
#include "gimpbuffer.h"
Michael Natterer's avatar
Michael Natterer committed
59
#include "gimpcontext.h"
60
#include "gimpdatafactory.h"
Michael Natterer's avatar
Michael Natterer committed
61 62
#include "gimpdynamics.h"
#include "gimpdynamics-load.h"
63
#include "gimpdocumentlist.h"
64
#include "gimpgradient-load.h"
65
#include "gimpgradient.h"
Martin Nordholts's avatar
Martin Nordholts committed
66
#include "gimpidtable.h"
67
#include "gimpimage.h"
Michael Natterer's avatar
Michael Natterer committed
68
#include "gimpimagefile.h"
69
#include "gimplist.h"
70
#include "gimpmarshal.h"
71
#include "gimppalette-load.h"
72 73
#include "gimppalette.h"
#include "gimpparasitelist.h"
74
#include "gimppattern-load.h"
75
#include "gimppattern.h"
76
#include "gimppatternclipboard.h"
Michael Natterer's avatar
Michael Natterer committed
77
#include "gimptagcache.h"
78
#include "gimptemplate.h"
79
#include "gimptoolinfo.h"
Alexia Death's avatar
Alexia Death committed
80 81
#include "gimptoolpreset.h"
#include "gimptoolpreset-load.h"
82

83
#include "gimp-intl.h"
84 85


86 87
enum
{
88 89
  INITIALIZE,
  RESTORE,
90
  EXIT,
91
  BUFFER_CHANGED,
92
  IMAGE_OPENED,
93 94 95
  LAST_SIGNAL
};

96 97 98 99 100
enum
{
  PROP_0,
  PROP_VERBOSE
};
101

102 103 104 105 106 107 108 109 110 111

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);
112 113
static void      gimp_dispose              (GObject           *object);
static void      gimp_finalize             (GObject           *object);
114

115 116
static gint64    gimp_get_memsize          (GimpObject        *object,
                                            gint64            *gui_size);
117

118 119 120 121 122 123
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);
124

125 126 127 128 129 130
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);
131 132


133
G_DEFINE_TYPE (Gimp, gimp, GIMP_TYPE_OBJECT)
134 135

#define parent_class gimp_parent_class
136

137 138
static guint gimp_signals[LAST_SIGNAL] = { 0, };

139 140 141 142

static void
gimp_class_init (GimpClass *klass)
{
143 144
  GObjectClass    *object_class      = G_OBJECT_CLASS (klass);
  GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
145

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  gimp_signals[INITIALIZE] =
    g_signal_new ("initialize",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, initialize),
                  NULL, NULL,
                  gimp_marshal_VOID__POINTER,
                  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),
                  NULL, NULL,
162 163 164
                  gimp_marshal_VOID__POINTER,
                  G_TYPE_NONE, 1,
                  G_TYPE_POINTER);
165

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

176 177 178 179 180 181 182 183 184
  gimp_signals[BUFFER_CHANGED] =
    g_signal_new ("buffer-changed",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, buffer_changed),
                  NULL, NULL,
                  gimp_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);

185 186 187 188 189 190
  gimp_signals[IMAGE_OPENED] =
    g_signal_new ("image-opened",
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GimpClass, image_opened),
                  NULL, NULL,
191 192
                  gimp_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1, G_TYPE_FILE);
193

194 195 196
  object_class->constructed      = gimp_constructed;
  object_class->set_property     = gimp_set_property;
  object_class->get_property     = gimp_get_property;
197 198 199 200
  object_class->dispose          = gimp_dispose;
  object_class->finalize         = gimp_finalize;

  gimp_object_class->get_memsize = gimp_get_memsize;
201

202 203
  klass->initialize              = gimp_real_initialize;
  klass->restore                 = gimp_real_restore;
204
  klass->exit                    = gimp_real_exit;
205
  klass->buffer_changed          = NULL;
206 207 208 209 210 211

  g_object_class_install_property (object_class, PROP_VERBOSE,
                                   g_param_spec_boolean ("verbose", NULL, NULL,
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY));
212 213 214 215 216
}

static void
gimp_init (Gimp *gimp)
{
217 218 219
  gimp->be_verbose       = FALSE;
  gimp->no_data          = FALSE;
  gimp->no_interface     = FALSE;
220
  gimp->show_gui         = TRUE;
221
  gimp->use_shm          = FALSE;
222
  gimp->use_cpu_accel    = TRUE;
223 224
  gimp->message_handler  = GIMP_CONSOLE;
  gimp->stack_trace_mode = GIMP_STACK_TRACE_NEVER;
225
  gimp->pdb_compat_mode  = GIMP_PDB_COMPAT_OFF;
226

227
  gimp_gui_init (gimp);
228

229
  gimp->parasites = gimp_parasite_list_new ();
230

231
  gimp->images = gimp_list_new_weak (GIMP_TYPE_IMAGE, FALSE);
232
  gimp_object_set_static_name (GIMP_OBJECT (gimp->images), "images");
233

234
  gimp->next_guide_ID        = 1;
235
  gimp->next_sample_point_ID = 1;
Martin Nordholts's avatar
Martin Nordholts committed
236
  gimp->image_table          = gimp_id_table_new ();
237
  gimp->item_table           = gimp_id_table_new ();
238

239 240 241 242 243
  gimp->displays = g_object_new (GIMP_TYPE_LIST,
                                 "children-type", GIMP_TYPE_OBJECT,
                                 "policy",        GIMP_CONTAINER_POLICY_WEAK,
                                 "append",        TRUE,
                                 NULL);
244
  gimp_object_set_static_name (GIMP_OBJECT (gimp->displays), "displays");
245
  gimp->next_display_ID = 1;
246

247
  gimp->named_buffers = gimp_list_new (GIMP_TYPE_BUFFER, TRUE);
248 249
  gimp_object_set_static_name (GIMP_OBJECT (gimp->named_buffers),
                               "named buffers");
250

251
  gimp->tool_info_list = gimp_list_new (GIMP_TYPE_TOOL_INFO, FALSE);
252 253
  gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_info_list),
                               "tool infos");
254

255
  gimp->templates = gimp_list_new (GIMP_TYPE_TEMPLATE, TRUE);
256
  gimp_object_set_static_name (GIMP_OBJECT (gimp->templates), "templates");
257 258
}

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
static void
gimp_constructed (GObject *object)
{
  Gimp *gimp = GIMP (object);

  G_OBJECT_CLASS (parent_class)->constructed (object);

  gimp_units_init (gimp);
  gimp_modules_init (gimp);

  gimp->plug_in_manager = gimp_plug_in_manager_new (gimp);
  gimp->pdb             = gimp_pdb_new (gimp);

  xcf_init (gimp);

  gimp->documents = gimp_document_list_new (gimp);
}

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;
    }
}

317
static void
318 319
gimp_dispose (GObject *object)
{
320
  Gimp *gimp = GIMP (object);
321

322 323 324 325 326
  if (gimp->be_verbose)
    g_print ("EXIT: %s\n", G_STRFUNC);

  if (gimp->brush_factory)
    gimp_data_factory_data_free (gimp->brush_factory);
327

328 329
  if (gimp->dynamics_factory)
    gimp_data_factory_data_free (gimp->dynamics_factory);
330 331 332 333 334 335 336 337 338 339

  if (gimp->pattern_factory)
    gimp_data_factory_data_free (gimp->pattern_factory);

  if (gimp->gradient_factory)
    gimp_data_factory_data_free (gimp->gradient_factory);

  if (gimp->palette_factory)
    gimp_data_factory_data_free (gimp->palette_factory);

Alexia Death's avatar
Alexia Death committed
340 341 342
  if (gimp->tool_preset_factory)
    gimp_data_factory_data_free (gimp->tool_preset_factory);

343 344 345 346 347 348 349 350
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gimp_finalize (GObject *object)
{
  Gimp *gimp = GIMP (object);

351
  if (gimp->be_verbose)
352
    g_print ("EXIT: %s\n", G_STRFUNC);
353

354
  gimp_contexts_exit (gimp);
Michael Natterer's avatar
Michael Natterer committed
355

356 357 358 359 360 361 362 363 364 365 366 367
  if (gimp->image_new_last_template)
    {
      g_object_unref (gimp->image_new_last_template);
      gimp->image_new_last_template = NULL;
    }

  if (gimp->templates)
    {
      g_object_unref (gimp->templates);
      gimp->templates = NULL;
    }

368
  if (gimp->documents)
369
    {
370
      g_object_unref (gimp->documents);
371 372
      gimp->documents = NULL;
    }
Michael Natterer's avatar
Michael Natterer committed
373

374 375
  gimp_tool_info_set_standard (gimp, NULL);

376 377
  if (gimp->tool_info_list)
    {
378 379
      gimp_container_foreach (gimp->tool_info_list,
                              (GFunc) g_object_run_dispose, NULL);
380
      g_object_unref (gimp->tool_info_list);
381 382 383
      gimp->tool_info_list = NULL;
    }

Michael Natterer's avatar
Michael Natterer committed
384 385
  xcf_exit (gimp);

386 387 388 389 390
  if (gimp->pdb)
    {
      g_object_unref (gimp->pdb);
      gimp->pdb = NULL;
    }
Michael Natterer's avatar
Michael Natterer committed
391

392 393
  if (gimp->brush_factory)
    {
394
      g_object_unref (gimp->brush_factory);
395 396 397
      gimp->brush_factory = NULL;
    }

398 399 400 401 402 403
  if (gimp->dynamics_factory)
    {
      g_object_unref (gimp->dynamics_factory);
      gimp->dynamics_factory = NULL;
    }

404 405
  if (gimp->pattern_factory)
    {
406
      g_object_unref (gimp->pattern_factory);
407 408 409 410 411
      gimp->pattern_factory = NULL;
    }

  if (gimp->gradient_factory)
    {
412
      g_object_unref (gimp->gradient_factory);
413 414 415 416 417
      gimp->gradient_factory = NULL;
    }

  if (gimp->palette_factory)
    {
418
      g_object_unref (gimp->palette_factory);
419 420 421
      gimp->palette_factory = NULL;
    }

Alexia Death's avatar
Alexia Death committed
422 423 424 425 426 427
  if (gimp->tool_preset_factory)
    {
      g_object_unref (gimp->tool_preset_factory);
      gimp->tool_preset_factory = NULL;
    }

428 429 430 431 432 433
  if (gimp->tag_cache)
    {
      g_object_unref (gimp->tag_cache);
      gimp->tag_cache = NULL;
    }

434 435 436 437 438 439
  if (gimp->fonts)
    {
      g_object_unref (gimp->fonts);
      gimp->fonts = NULL;
    }

440 441
  if (gimp->named_buffers)
    {
442
      g_object_unref (gimp->named_buffers);
443 444 445 446 447
      gimp->named_buffers = NULL;
    }

  if (gimp->global_buffer)
    {
448
      g_object_unref (gimp->global_buffer);
449 450 451
      gimp->global_buffer = NULL;
    }

452 453 454 455 456 457
  if (gimp->displays)
    {
      g_object_unref (gimp->displays);
      gimp->displays = NULL;
    }

458
  if (gimp->item_table)
459
    {
Martin Nordholts's avatar
Martin Nordholts committed
460
      g_object_unref (gimp->item_table);
461
      gimp->item_table = NULL;
462 463 464 465
    }

  if (gimp->image_table)
    {
Martin Nordholts's avatar
Martin Nordholts committed
466
      g_object_unref (gimp->image_table);
467 468 469
      gimp->image_table = NULL;
    }

470 471
  if (gimp->images)
    {
472
      g_object_unref (gimp->images);
473 474 475
      gimp->images = NULL;
    }

476
  if (gimp->plug_in_manager)
477
    {
478 479
      g_object_unref (gimp->plug_in_manager);
      gimp->plug_in_manager = NULL;
480 481
    }

482
  if (gimp->module_db)
Michael Natterer's avatar
Michael Natterer committed
483 484
    gimp_modules_exit (gimp);

485
  gimp_paint_exit (gimp);
486

487
  if (gimp->parasites)
Sven Neumann's avatar
Sven Neumann committed
488
    {
489
      g_object_unref (gimp->parasites);
Sven Neumann's avatar
Sven Neumann committed
490 491
      gimp->parasites = NULL;
    }
492

493 494 495 496 497 498
  if (gimp->edit_config)
    {
      g_object_unref (gimp->edit_config);
      gimp->edit_config = NULL;
    }

499 500
  if (gimp->default_folder)
    {
501
      g_object_unref (gimp->default_folder);
502 503 504
      gimp->default_folder = NULL;
    }

505 506 507 508 509 510
  if (gimp->session_name)
    {
      g_free (gimp->session_name);
      gimp->session_name = NULL;
    }

Sven Neumann's avatar
Sven Neumann committed
511 512 513 514 515 516
  if (gimp->context_list)
    {
      g_list_free (gimp->context_list);
      gimp->context_list = NULL;
    }

517
  gimp_units_exit (gimp);
518

519
  G_OBJECT_CLASS (parent_class)->finalize (object);
520 521
}

522
static gint64
523
gimp_get_memsize (GimpObject *object,
524
                  gint64     *gui_size)
525
{
526
  Gimp   *gimp    = GIMP (object);
527
  gint64  memsize = 0;
528

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

531 532
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->parasites),
                                      gui_size);
533

534 535 536
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->paint_info_list),
                                      gui_size);

537
  memsize += gimp_g_object_get_memsize (G_OBJECT (gimp->module_db));
538 539
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->plug_in_manager),
                                      gui_size);
540

Martin Nordholts's avatar
Martin Nordholts committed
541 542
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->image_table), 0);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->item_table),  0);
543

544
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->displays), gui_size);
545

546 547 548 549 550 551 552 553 554
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->global_buffer),
                                      gui_size);

  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->named_buffers),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->fonts),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->brush_factory),
                                      gui_size);
555 556
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->dynamics_factory),
                                      gui_size);
557 558 559 560 561 562
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->pattern_factory),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->gradient_factory),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->palette_factory),
                                      gui_size);
Alexia Death's avatar
Alexia Death committed
563 564
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->tool_preset_factory),
                                      gui_size);
565

566 567 568
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->tag_cache),
                                      gui_size);

569
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->pdb), gui_size);
570

571 572 573 574 575 576 577 578 579 580
  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);
581

582
  memsize += gimp_g_list_get_memsize (gimp->context_list, 0);
583

584 585 586 587
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->default_context),
                                      gui_size);
  memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->user_context),
                                      gui_size);
588

589 590
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                  gui_size);
591 592
}

593 594 595 596 597 598
static void
gimp_real_initialize (Gimp               *gimp,
                      GimpInitStatusFunc  status_callback)
{
  static const GimpDataFactoryLoaderEntry brush_loader_entries[] =
  {
599 600
    { gimp_brush_load,           GIMP_BRUSH_FILE_EXTENSION,           FALSE },
    { gimp_brush_load,           GIMP_BRUSH_PIXMAP_FILE_EXTENSION,    FALSE },
601 602
    { gimp_brush_load_abr,       GIMP_BRUSH_PS_FILE_EXTENSION,        FALSE },
    { gimp_brush_load_abr,       GIMP_BRUSH_PSP_FILE_EXTENSION,       FALSE },
603 604
    { gimp_brush_generated_load, GIMP_BRUSH_GENERATED_FILE_EXTENSION, TRUE  },
    { gimp_brush_pipe_load,      GIMP_BRUSH_PIPE_FILE_EXTENSION,      FALSE }
605 606
  };

607 608
  static const GimpDataFactoryLoaderEntry dynamics_loader_entries[] =
  {
Michael Natterer's avatar
Michael Natterer committed
609
    { gimp_dynamics_load,        GIMP_DYNAMICS_FILE_EXTENSION,        TRUE  }
610
  };
611

612 613
  static const GimpDataFactoryLoaderEntry pattern_loader_entries[] =
  {
614 615
    { gimp_pattern_load,         GIMP_PATTERN_FILE_EXTENSION,         FALSE },
    { gimp_pattern_load_pixbuf,  NULL,                                FALSE }
616 617 618 619
  };

  static const GimpDataFactoryLoaderEntry gradient_loader_entries[] =
  {
620 621 622
    { gimp_gradient_load,        GIMP_GRADIENT_FILE_EXTENSION,        TRUE  },
    { gimp_gradient_load_svg,    GIMP_GRADIENT_SVG_FILE_EXTENSION,    FALSE },
    { gimp_gradient_load,        NULL /* legacy loader */,            TRUE  }
623 624 625 626
  };

  static const GimpDataFactoryLoaderEntry palette_loader_entries[] =
  {
627 628
    { gimp_palette_load,         GIMP_PALETTE_FILE_EXTENSION,         TRUE  },
    { gimp_palette_load,         NULL /* legacy loader */,            TRUE  }
629 630
  };

Alexia Death's avatar
Alexia Death committed
631 632
  static const GimpDataFactoryLoaderEntry tool_preset_loader_entries[] =
  {
633
    { gimp_tool_preset_load,     GIMP_TOOL_PRESET_FILE_EXTENSION,     TRUE  }
Alexia Death's avatar
Alexia Death committed
634 635
  };

636
  GimpData *clipboard_brush;
637
  GimpData *clipboard_pattern;
638

639
  if (gimp->be_verbose)
640
    g_print ("INIT: %s\n", G_STRFUNC);
641

642 643
  status_callback (_("Initialization"), NULL, 0.0);

644 645 646 647 648
  gimp_fonts_init (gimp);

  gimp->brush_factory =
    gimp_data_factory_new (gimp,
                           GIMP_TYPE_BRUSH,
649 650 651 652 653
                           "brush-path", "brush-path-writable",
                           brush_loader_entries,
                           G_N_ELEMENTS (brush_loader_entries),
                           gimp_brush_new,
                           gimp_brush_get_standard);
654 655
  gimp_object_set_static_name (GIMP_OBJECT (gimp->brush_factory),
                               "brush factory");
656

657 658
  gimp->dynamics_factory =
    gimp_data_factory_new (gimp,
659
                           GIMP_TYPE_DYNAMICS,
660
                           "dynamics-path", "dynamics-path-writable",
661 662
                           dynamics_loader_entries,
                           G_N_ELEMENTS (dynamics_loader_entries),
663
                           gimp_dynamics_new,
664 665 666 667
                           gimp_dynamics_get_standard);
  gimp_object_set_static_name (GIMP_OBJECT (gimp->dynamics_factory),
                               "dynamics factory");

668 669 670
  gimp->pattern_factory =
    gimp_data_factory_new (gimp,
                           GIMP_TYPE_PATTERN,
671 672 673 674 675
                           "pattern-path", "pattern-path-writable",
                           pattern_loader_entries,
                           G_N_ELEMENTS (pattern_loader_entries),
                           NULL,
                           gimp_pattern_get_standard);
676 677
  gimp_object_set_static_name (GIMP_OBJECT (gimp->pattern_factory),
                               "pattern factory");
678 679 680 681

  gimp->gradient_factory =
    gimp_data_factory_new (gimp,
                           GIMP_TYPE_GRADIENT,
682 683 684 685 686
                           "gradient-path", "gradient-path-writable",
                           gradient_loader_entries,
                           G_N_ELEMENTS (gradient_loader_entries),
                           gimp_gradient_new,
                           gimp_gradient_get_standard);
687 688
  gimp_object_set_static_name (GIMP_OBJECT (gimp->gradient_factory),
                               "gradient factory");
689 690 691 692

  gimp->palette_factory =
    gimp_data_factory_new (gimp,
                           GIMP_TYPE_PALETTE,
693 694 695 696 697
                           "palette-path", "palette-path-writable",
                           palette_loader_entries,
                           G_N_ELEMENTS (palette_loader_entries),
                           gimp_palette_new,
                           gimp_palette_get_standard);
698 699
  gimp_object_set_static_name (GIMP_OBJECT (gimp->palette_factory),
                               "palette factory");
700

Alexia Death's avatar
Alexia Death committed
701 702 703 704 705 706 707
  gimp->tool_preset_factory =
    gimp_data_factory_new (gimp,
                           GIMP_TYPE_TOOL_PRESET,
                           "tool-preset-path", "tool-preset-path-writable",
                           tool_preset_loader_entries,
                           G_N_ELEMENTS (tool_preset_loader_entries),
                           gimp_tool_preset_new,
708
                           NULL);
Alexia Death's avatar
Alexia Death committed
709 710 711
  gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_preset_factory),
                               "tool preset factory");

712 713
  gimp->tag_cache = gimp_tag_cache_new ();

714 715 716
  gimp_paint_init (gimp);

  /* Set the last values used to default values. */
717 718
  gimp->image_new_last_template =
    gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image));
719

720 721
  /*  create user and default context  */
  gimp_contexts_init (gimp);
722 723 724 725

  /*  add the builtin FG -> BG etc. gradients  */
  gimp_gradients_init (gimp);

726 727
  /*  add the clipboard brush  */
  clipboard_brush = gimp_brush_clipboard_new (gimp);
728 729
  gimp_data_make_internal (GIMP_DATA (clipboard_brush),
                           "gimp-brush-clipboard");
730
  gimp_container_add (gimp_data_factory_get_container (gimp->brush_factory),
731 732 733
                      GIMP_OBJECT (clipboard_brush));
  g_object_unref (clipboard_brush);

734 735
  /*  add the clipboard pattern  */
  clipboard_pattern = gimp_pattern_clipboard_new (gimp);
736 737
  gimp_data_make_internal (GIMP_DATA (clipboard_pattern),
                           "gimp-pattern-clipboard");
738
  gimp_container_add (gimp_data_factory_get_container (gimp->pattern_factory),
739 740 741
                      GIMP_OBJECT (clipboard_pattern));
  g_object_unref (clipboard_pattern);

742
  /*  register all internal procedures  */
Sven Neumann's avatar
Sven Neumann committed
743
  status_callback (NULL, _("Internal Procedures"), 0.2);
744 745
  internal_procs_init (gimp->pdb);
  gimp_pdb_compat_procs_register (gimp->pdb, gimp->pdb_compat_mode);
746

747
  gimp_plug_in_manager_initialize (gimp->plug_in_manager, status_callback);
748 749

  status_callback (NULL, "", 1.0);
750 751 752 753
}

static void
gimp_real_restore (Gimp               *gimp,
754
                   GimpInitStatusFunc  status_callback)
755 756
{
  if (gimp->be_verbose)
757
    g_print ("INIT: %s\n", G_STRFUNC);
758

759 760
  gimp_plug_in_manager_restore (gimp->plug_in_manager,
                                gimp_get_user_context (gimp), status_callback);
761 762

  gimp->restored = TRUE;
763 764
}

765 766
static gboolean
gimp_real_exit (Gimp     *gimp,
767
                gboolean  force)
768
{
769
  if (gimp->be_verbose)
770
    g_print ("EXIT: %s\n", G_STRFUNC);
771

772
  gimp_plug_in_manager_exit (gimp->plug_in_manager);
773
  gimp_modules_unload (gimp);
774

775 776
  gimp_tag_cache_save (gimp->tag_cache);

777
  gimp_data_factory_data_save (gimp->brush_factory);
778
  gimp_data_factory_data_save (gimp->dynamics_factory);
779 780 781
  gimp_data_factory_data_save (gimp->pattern_factory);
  gimp_data_factory_data_save (gimp->gradient_factory);
  gimp_data_factory_data_save (gimp->palette_factory);
Alexia Death's avatar
Alexia Death committed
782 783
  gimp_data_factory_data_save (gimp->tool_preset_factory);

784
  gimp_fonts_reset (gimp);
785

786
  gimp_templates_save (gimp);
787 788 789 790 791 792
  gimp_parasiterc_save (gimp);
  gimp_unitrc_save (gimp);

  return FALSE; /* continue exiting */
}

793
Gimp *
794
gimp_new (const gchar       *name,
795
          const gchar       *session_name,
796
          GFile             *default_folder,
797
          gboolean           be_verbose,
Michael Natterer's avatar
Michael Natterer committed
798
          gboolean           no_data,
799
          gboolean           no_fonts,
Michael Natterer's avatar
Michael Natterer committed
800
          gboolean           no_interface,
801
          gboolean           use_shm,
802
          gboolean           use_cpu_accel,
803
          gboolean           console_messages,
804 805
          GimpStackTraceMode stack_trace_mode,
          GimpPDBCompatMode  pdb_compat_mode)
806 807 808
{
  Gimp *gimp;

809 810
  g_return_val_if_fail (name != NULL, NULL);

811
  gimp = g_object_new (GIMP_TYPE_GIMP,
812 813
                       "name",    name,
                       "verbose", be_verbose ? TRUE : FALSE,
814
                       NULL);
815

816 817 818
  if (default_folder)
    gimp->default_folder = g_object_ref (default_folder);

819
  gimp->session_name     = g_strdup (session_name);
820
  gimp->no_data          = no_data          ? TRUE : FALSE;
821
  gimp->no_fonts         = no_fonts         ? TRUE : FALSE;
822 823
  gimp->no_interface     = no_interface     ? TRUE : FALSE;
  gimp->use_shm          = use_shm          ? TRUE : FALSE;
824
  gimp->use_cpu_accel    = use_cpu_accel    ? TRUE : FALSE;
825
  gimp->console_messages = console_messages ? TRUE : FALSE;
Michael Natterer's avatar
Michael Natterer committed
826
  gimp->stack_trace_mode = stack_trace_mode;
827
  gimp->pdb_compat_mode  = pdb_compat_mode;
Michael Natterer's avatar
Michael Natterer committed
828

829 830 831
  return gimp;
}

832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
/**
 * 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;
}

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
static void
gimp_global_config_notify (GObject    *global_config,
                           GParamSpec *param_spec,
                           GObject    *edit_config)
{
  GValue global_value = { 0, };
  GValue edit_value   = { 0, };

  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)
{
  GValue edit_value   = { 0, };
  GValue global_value = { 0, };

  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))
    {
910
      if (param_spec->flags & GIMP_CONFIG_PARAM_RESTART)
911
        {
Sven Neumann's avatar
Sven Neumann committed
912
#ifdef GIMP_CONFIG_DEBUG
913 914 915
          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
916
#endif
917 918 919
        }
      else
        {
Sven Neumann's avatar
Sven Neumann committed
920
#ifdef GIMP_CONFIG_DEBUG
921 922
          g_print ("Applying edit_config change of '%s' to global_config\n",
                   param_spec->name);
Sven Neumann's avatar
Sven Neumann committed
923
#endif
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
          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
941 942 943
gimp_load_config (Gimp  *gimp,
                  GFile *alternate_system_gimprc,
                  GFile *alternate_gimprc)
944
{
945 946
  GimpRc *gimprc;

947
  g_return_if_fail (GIMP_IS_GIMP (gimp));
948 949 950 951
  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));
952 953 954
  g_return_if_fail (gimp->config == NULL);
  g_return_if_fail (gimp->edit_config == NULL);

955
  if (gimp->be_verbose)
956
    g_print ("INIT: %s\n", G_STRFUNC);
957 958 959 960 961 962 963 964 965 966 967

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

  gimprc = gimp_rc_new (alternate_system_gimprc,
                        alternate_gimprc,
                        gimp->be_verbose);

  gimp->config = GIMP_CORE_CONFIG (gimprc);
968

969
  gimp->edit_config = gimp_config_duplicate (GIMP_CONFIG (gimp->config));
970 971 972 973 974 975 976 977 978

  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);
}

979
void
980 981
gimp_initialize (Gimp               *gimp,
                 GimpInitStatusFunc  status_callback)
982 983
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));
984
  g_return_if_fail (status_callback != NULL);
985
  g_return_if_fail (GIMP_IS_CORE_CONFIG (gimp->config));
986

987
  if (gimp->be_verbose)
988
    g_print ("INIT: %s\n", G_STRFUNC);
989

990
  g_signal_emit (gimp, gimp_signals[INITIALIZE], 0, status_callback);
991 992 993
}

void
994
gimp_restore (Gimp               *gimp,
995
              GimpInitStatusFunc  status_callback)
996 997
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));
998
  g_return_if_fail (status_callback != NULL);
999

1000
  if (gimp->be_verbose)
1001
    g_print ("INIT: %s\n", G_STRFUNC);
1002

1003
  /*  initialize  the global parasite table  */
1004
  status_callback (_("Looking for data files"), _("Parasites"), 0.0);
1005
  gimp_parasiterc_load (gimp);
1006 1007

  /*  initialize the list of gimp brushes    */
1008
  status_callback (NULL, _("Brushes"), 0.1);
1009 1010
  gimp_data_factory_data_init (gimp->brush_factory, gimp->user_context,
                               gimp->no_data);
1011

Michael Natterer's avatar
Michael Natterer committed
1012
  /*  initialize the list of gimp dynamics   */
1013
  status_callback (NULL, _("Dynamics"), 0.2);
1014 1015
  gimp_data_factory_data_init (gimp->dynamics_factory, gimp->user_context,
                               gimp->no_data);
1016

1017
  /*  initialize the list of gimp patterns   */
1018
  status_callback (NULL, _("Patterns"), 0.3);
1019 1020
  gimp_data_factory_data_init (gimp->pattern_factory, gimp->user_context,
                               gimp->no_data);
1021 1022

  /*  initialize the list of gimp palettes   */
1023
  status_callback (NULL, _("Palettes"), 0.4);
1024 1025
  gimp_data_factory_data_init (gimp->palette_factory, gimp->user_context,
                               gimp->no_data);
1026 1027

  /*  initialize the list of gimp gradients  */
1028
  status_callback (NULL, _("Gradients"), 0.5);
1029 1030
  gimp_data_factory_data_init (gimp->gradient_factory, gimp->user_context,
                               gimp->no_data);
1031

1032
  /*  initialize the list of fonts  */
1033
  status_callback (NULL, _("Fonts (this may take a while)"), 0.6);
1034 1035
  if (! gimp->no_fonts)
    gimp_fonts_load (gimp);
1036

1037 1038 1039 1040 1041 1042 1043
  /*  initialize the list of gimp tool presets if we have a GUI  */
  if (! gimp->no_interface)
    {
      status_callback (NULL, _("Tool Presets"), 0.65);
      gimp_data_factory_data_init (gimp->tool_preset_factory, gimp->user_context,
                                   gimp->no_data);
    }
Alexia Death's avatar
Alexia Death committed
1044

1045
  /*  initialize the template list  */
1046
  status_callback (NULL, _("Templates"), 0.7);
1047 1048
  gimp_templates_load (gimp);

1049
  /*  initialize the module list  */
1050
  status_callback (NULL, _("Modules"), 0.8);
Michael Natterer's avatar
Michael Natterer committed
1051
  gimp_modules_load (gimp);
1052

1053
  /* update tag cache */
1054
  status_callback (NULL, _("Updating tag cache"), 0.9);
1055 1056 1057
  gimp_tag_cache_load (gimp->tag_cache);
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->brush_factory));
1058 1059
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->dynamics_factory));
1060 1061 1062 1063 1064 1065
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->pattern_factory));
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->gradient_factory));
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->palette_factory));
Alexia Death's avatar
Alexia Death committed
1066 1067
  gimp_tag_cache_add_container (gimp->tag_cache,
                                gimp_data_factory_get_container (gimp->tool_preset_factory));