1 /* GIMP - The GNU Image Manipulation Program
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  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * 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 #include "config.h"
19 
20 #include <string.h> /* strlen */
21 
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 #include "config/gimprc.h"
31 
32 #include "gegl/gimp-babl.h"
33 
34 #include "pdb/gimppdb.h"
35 #include "pdb/gimp-pdb-compat.h"
36 #include "pdb/internal-procs.h"
37 
38 #include "plug-in/gimppluginmanager.h"
39 #include "plug-in/gimppluginmanager-restore.h"
40 
41 #include "paint/gimp-paint.h"
42 
43 #include "xcf/xcf.h"
44 #include "file-data/file-data.h"
45 
46 #include "gimp.h"
47 #include "gimp-contexts.h"
48 #include "gimp-data-factories.h"
49 #include "gimp-filter-history.h"
50 #include "gimp-memsize.h"
51 #include "gimp-modules.h"
52 #include "gimp-parasites.h"
53 #include "gimp-templates.h"
54 #include "gimp-units.h"
55 #include "gimp-utils.h"
56 #include "gimpbrush.h"
57 #include "gimpbuffer.h"
58 #include "gimpcontext.h"
59 #include "gimpdynamics.h"
60 #include "gimpdocumentlist.h"
61 #include "gimpgradient.h"
62 #include "gimpidtable.h"
63 #include "gimpimage.h"
64 #include "gimpimagefile.h"
65 #include "gimplist.h"
66 #include "gimpmarshal.h"
67 #include "gimpmybrush.h"
68 #include "gimppalette.h"
69 #include "gimpparasitelist.h"
70 #include "gimppattern.h"
71 #include "gimptemplate.h"
72 #include "gimptoolinfo.h"
73 #include "gimptreeproxy.h"
74 
75 #include "gimp-intl.h"
76 
77 
78 enum
79 {
80   INITIALIZE,
81   RESTORE,
82   EXIT,
83   CLIPBOARD_CHANGED,
84   FILTER_HISTORY_CHANGED,
85   IMAGE_OPENED,
86   LAST_SIGNAL
87 };
88 
89 enum
90 {
91   PROP_0,
92   PROP_VERBOSE
93 };
94 
95 
96 static void      gimp_constructed          (GObject           *object);
97 static void      gimp_set_property         (GObject           *object,
98                                             guint              property_id,
99                                             const GValue      *value,
100                                             GParamSpec        *pspec);
101 static void      gimp_get_property         (GObject           *object,
102                                             guint              property_id,
103                                             GValue            *value,
104                                             GParamSpec        *pspec);
105 static void      gimp_dispose              (GObject           *object);
106 static void      gimp_finalize             (GObject           *object);
107 
108 static gint64    gimp_get_memsize          (GimpObject        *object,
109                                             gint64            *gui_size);
110 
111 static void      gimp_real_initialize      (Gimp              *gimp,
112                                             GimpInitStatusFunc status_callback);
113 static void      gimp_real_restore         (Gimp              *gimp,
114                                             GimpInitStatusFunc status_callback);
115 static gboolean  gimp_real_exit            (Gimp              *gimp,
116                                             gboolean           force);
117 
118 static void      gimp_global_config_notify (GObject           *global_config,
119                                             GParamSpec        *param_spec,
120                                             GObject           *edit_config);
121 static void      gimp_edit_config_notify   (GObject           *edit_config,
122                                             GParamSpec        *param_spec,
123                                             GObject           *global_config);
124 
125 
126 G_DEFINE_TYPE (Gimp, gimp, GIMP_TYPE_OBJECT)
127 
128 #define parent_class gimp_parent_class
129 
130 static guint gimp_signals[LAST_SIGNAL] = { 0, };
131 
132 
133 static void
gimp_class_init(GimpClass * klass)134 gimp_class_init (GimpClass *klass)
135 {
136   GObjectClass    *object_class      = G_OBJECT_CLASS (klass);
137   GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
138 
139   gimp_signals[INITIALIZE] =
140     g_signal_new ("initialize",
141                   G_TYPE_FROM_CLASS (klass),
142                   G_SIGNAL_RUN_LAST,
143                   G_STRUCT_OFFSET (GimpClass, initialize),
144                   NULL, NULL,
145                   gimp_marshal_VOID__POINTER,
146                   G_TYPE_NONE, 1,
147                   G_TYPE_POINTER);
148 
149   gimp_signals[RESTORE] =
150     g_signal_new ("restore",
151                   G_TYPE_FROM_CLASS (klass),
152                   G_SIGNAL_RUN_LAST,
153                   G_STRUCT_OFFSET (GimpClass, restore),
154                   NULL, NULL,
155                   gimp_marshal_VOID__POINTER,
156                   G_TYPE_NONE, 1,
157                   G_TYPE_POINTER);
158 
159   gimp_signals[EXIT] =
160     g_signal_new ("exit",
161                   G_TYPE_FROM_CLASS (klass),
162                   G_SIGNAL_RUN_LAST,
163                   G_STRUCT_OFFSET (GimpClass, exit),
164                   g_signal_accumulator_true_handled, NULL,
165                   gimp_marshal_BOOLEAN__BOOLEAN,
166                   G_TYPE_BOOLEAN, 1,
167                   G_TYPE_BOOLEAN);
168 
169   gimp_signals[CLIPBOARD_CHANGED] =
170     g_signal_new ("clipboard-changed",
171                   G_TYPE_FROM_CLASS (klass),
172                   G_SIGNAL_RUN_LAST,
173                   G_STRUCT_OFFSET (GimpClass, clipboard_changed),
174                   NULL, NULL,
175                   gimp_marshal_VOID__VOID,
176                   G_TYPE_NONE, 0);
177 
178   gimp_signals[FILTER_HISTORY_CHANGED] =
179     g_signal_new ("filter-history-changed",
180                   G_TYPE_FROM_CLASS (klass),
181                   G_SIGNAL_RUN_LAST,
182                   G_STRUCT_OFFSET (GimpClass,
183                                    filter_history_changed),
184                   NULL, NULL,
185                   gimp_marshal_VOID__VOID,
186                   G_TYPE_NONE, 0);
187 
188   gimp_signals[IMAGE_OPENED] =
189     g_signal_new ("image-opened",
190                   G_TYPE_FROM_CLASS (klass),
191                   G_SIGNAL_RUN_LAST,
192                   G_STRUCT_OFFSET (GimpClass, image_opened),
193                   NULL, NULL,
194                   gimp_marshal_VOID__OBJECT,
195                   G_TYPE_NONE, 1, G_TYPE_FILE);
196 
197   object_class->constructed      = gimp_constructed;
198   object_class->set_property     = gimp_set_property;
199   object_class->get_property     = gimp_get_property;
200   object_class->dispose          = gimp_dispose;
201   object_class->finalize         = gimp_finalize;
202 
203   gimp_object_class->get_memsize = gimp_get_memsize;
204 
205   klass->initialize              = gimp_real_initialize;
206   klass->restore                 = gimp_real_restore;
207   klass->exit                    = gimp_real_exit;
208   klass->clipboard_changed       = NULL;
209 
210   g_object_class_install_property (object_class, PROP_VERBOSE,
211                                    g_param_spec_boolean ("verbose", NULL, NULL,
212                                                          FALSE,
213                                                          GIMP_PARAM_READWRITE |
214                                                          G_PARAM_CONSTRUCT_ONLY));
215 }
216 
217 static void
gimp_init(Gimp * gimp)218 gimp_init (Gimp *gimp)
219 {
220   gimp->be_verbose       = FALSE;
221   gimp->no_data          = FALSE;
222   gimp->no_interface     = FALSE;
223   gimp->show_gui         = TRUE;
224   gimp->use_shm          = FALSE;
225   gimp->use_cpu_accel    = TRUE;
226   gimp->message_handler  = GIMP_CONSOLE;
227   gimp->show_playground  = FALSE;
228   gimp->stack_trace_mode = GIMP_STACK_TRACE_NEVER;
229   gimp->pdb_compat_mode  = GIMP_PDB_COMPAT_OFF;
230 
231   gimp_gui_init (gimp);
232 
233   gimp->parasites = gimp_parasite_list_new ();
234 
235   gimp_units_init (gimp);
236 
237   gimp->images = gimp_list_new_weak (GIMP_TYPE_IMAGE, FALSE);
238   gimp_object_set_static_name (GIMP_OBJECT (gimp->images), "images");
239 
240   gimp->next_guide_ID        = 1;
241   gimp->next_sample_point_ID = 1;
242   gimp->image_table          = gimp_id_table_new ();
243   gimp->item_table           = gimp_id_table_new ();
244 
245   gimp->displays = g_object_new (GIMP_TYPE_LIST,
246                                  "children-type", GIMP_TYPE_OBJECT,
247                                  "policy",        GIMP_CONTAINER_POLICY_WEAK,
248                                  "append",        TRUE,
249                                  NULL);
250   gimp_object_set_static_name (GIMP_OBJECT (gimp->displays), "displays");
251   gimp->next_display_ID = 1;
252 
253   gimp->named_buffers = gimp_list_new (GIMP_TYPE_BUFFER, TRUE);
254   gimp_object_set_static_name (GIMP_OBJECT (gimp->named_buffers),
255                                "named buffers");
256 
257   gimp_data_factories_init (gimp);
258 
259   gimp->tool_info_list = g_object_new (GIMP_TYPE_LIST,
260                                        "children-type", GIMP_TYPE_TOOL_INFO,
261                                        "append",        TRUE,
262                                        NULL);
263   gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_info_list),
264                                "tool infos");
265 
266   gimp->tool_item_list = g_object_new (GIMP_TYPE_LIST,
267                                        "children-type", GIMP_TYPE_TOOL_ITEM,
268                                        "append",        TRUE,
269                                        NULL);
270   gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_item_list),
271                                "tool items");
272 
273   gimp->tool_item_ui_list = gimp_tree_proxy_new_for_container (
274     gimp->tool_item_list);
275   gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_item_ui_list),
276                                "ui tool items");
277 
278   gimp->documents = gimp_document_list_new (gimp);
279 
280   gimp->templates = gimp_list_new (GIMP_TYPE_TEMPLATE, TRUE);
281   gimp_object_set_static_name (GIMP_OBJECT (gimp->templates), "templates");
282 }
283 
284 static void
gimp_constructed(GObject * object)285 gimp_constructed (GObject *object)
286 {
287   Gimp *gimp = GIMP (object);
288 
289   G_OBJECT_CLASS (parent_class)->constructed (object);
290 
291   gimp_modules_init (gimp);
292 
293   gimp_paint_init (gimp);
294 
295   gimp->plug_in_manager = gimp_plug_in_manager_new (gimp);
296   gimp->pdb             = gimp_pdb_new (gimp);
297 
298   xcf_init (gimp);
299   file_data_init (gimp);
300 
301   /*  create user and default context  */
302   gimp_contexts_init (gimp);
303 }
304 
305 static void
gimp_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)306 gimp_set_property (GObject           *object,
307                    guint              property_id,
308                    const GValue      *value,
309                    GParamSpec        *pspec)
310 {
311   Gimp *gimp = GIMP (object);
312 
313   switch (property_id)
314     {
315     case PROP_VERBOSE:
316       gimp->be_verbose = g_value_get_boolean (value);
317       break;
318 
319     default:
320       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
321       break;
322     }
323 }
324 
325 static void
gimp_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)326 gimp_get_property (GObject    *object,
327                    guint       property_id,
328                    GValue     *value,
329                    GParamSpec *pspec)
330 {
331   Gimp *gimp = GIMP (object);
332 
333   switch (property_id)
334     {
335     case PROP_VERBOSE:
336       g_value_set_boolean (value, gimp->be_verbose);
337       break;
338 
339     default:
340       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
341       break;
342     }
343 }
344 
345 static void
gimp_dispose(GObject * object)346 gimp_dispose (GObject *object)
347 {
348   Gimp *gimp = GIMP (object);
349 
350   if (gimp->be_verbose)
351     g_print ("EXIT: %s\n", G_STRFUNC);
352 
353   gimp_data_factories_clear (gimp);
354 
355   gimp_filter_history_clear (gimp);
356 
357   g_clear_object (&gimp->edit_config);
358   g_clear_object (&gimp->config);
359 
360   gimp_contexts_exit (gimp);
361 
362   g_clear_object (&gimp->image_new_last_template);
363 
364   G_OBJECT_CLASS (parent_class)->dispose (object);
365 }
366 
367 static void
gimp_finalize(GObject * object)368 gimp_finalize (GObject *object)
369 {
370   Gimp  *gimp      = GIMP (object);
371   GList *standards = NULL;
372 
373   if (gimp->be_verbose)
374     g_print ("EXIT: %s\n", G_STRFUNC);
375 
376   standards = g_list_prepend (standards,
377                               gimp_brush_get_standard (gimp->user_context));
378   standards = g_list_prepend (standards,
379                               gimp_dynamics_get_standard (gimp->user_context));
380   standards = g_list_prepend (standards,
381                               gimp_mybrush_get_standard (gimp->user_context));
382   standards = g_list_prepend (standards,
383                               gimp_pattern_get_standard (gimp->user_context));
384   standards = g_list_prepend (standards,
385                               gimp_gradient_get_standard (gimp->user_context));
386   standards = g_list_prepend (standards,
387                               gimp_palette_get_standard (gimp->user_context));
388 
389   g_clear_object (&gimp->templates);
390   g_clear_object (&gimp->documents);
391 
392   gimp_tool_info_set_standard (gimp, NULL);
393 
394   g_clear_object (&gimp->tool_item_list);
395   g_clear_object (&gimp->tool_item_ui_list);
396 
397   if (gimp->tool_info_list)
398     {
399       gimp_container_foreach (gimp->tool_info_list,
400                               (GFunc) g_object_run_dispose, NULL);
401       g_clear_object (&gimp->tool_info_list);
402     }
403 
404   file_data_exit (gimp);
405   xcf_exit (gimp);
406 
407   g_clear_object (&gimp->pdb);
408 
409   gimp_data_factories_exit (gimp);
410 
411   g_clear_object (&gimp->named_buffers);
412   g_clear_object (&gimp->clipboard_buffer);
413   g_clear_object (&gimp->clipboard_image);
414   g_clear_object (&gimp->displays);
415   g_clear_object (&gimp->item_table);
416   g_clear_object (&gimp->image_table);
417   g_clear_object (&gimp->images);
418   g_clear_object (&gimp->plug_in_manager);
419 
420   if (gimp->module_db)
421     gimp_modules_exit (gimp);
422 
423   gimp_paint_exit (gimp);
424 
425   g_clear_object (&gimp->parasites);
426   g_clear_object (&gimp->default_folder);
427 
428   g_clear_pointer (&gimp->session_name, g_free);
429 
430   if (gimp->context_list)
431     {
432       GList *list;
433 
434       g_warning ("%s: list of contexts not empty upon exit (%d contexts left)\n",
435                  G_STRFUNC, g_list_length (gimp->context_list));
436 
437       for (list = gimp->context_list; list; list = g_list_next (list))
438         g_printerr ("stale context: %s\n", gimp_object_get_name (list->data));
439 
440       g_list_free (gimp->context_list);
441       gimp->context_list = NULL;
442     }
443 
444   g_list_foreach (standards, (GFunc) g_object_unref, NULL);
445   g_list_free (standards);
446 
447   gimp_units_exit (gimp);
448 
449   G_OBJECT_CLASS (parent_class)->finalize (object);
450 }
451 
452 static gint64
gimp_get_memsize(GimpObject * object,gint64 * gui_size)453 gimp_get_memsize (GimpObject *object,
454                   gint64     *gui_size)
455 {
456   Gimp   *gimp    = GIMP (object);
457   gint64  memsize = 0;
458 
459   memsize += gimp_g_list_get_memsize (gimp->user_units, 0 /* FIXME */);
460 
461   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->parasites),
462                                       gui_size);
463 
464   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->paint_info_list),
465                                       gui_size);
466 
467   memsize += gimp_g_object_get_memsize (G_OBJECT (gimp->module_db));
468   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->plug_in_manager),
469                                       gui_size);
470 
471   memsize += gimp_g_list_get_memsize_foreach (gimp->filter_history,
472                                               (GimpMemsizeFunc)
473                                               gimp_object_get_memsize,
474                                               gui_size);
475 
476   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->image_table), 0);
477   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->item_table),  0);
478 
479   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->displays), gui_size);
480 
481   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->clipboard_image),
482                                       gui_size);
483   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->clipboard_buffer),
484                                       gui_size);
485   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->named_buffers),
486                                       gui_size);
487 
488   memsize += gimp_data_factories_get_memsize (gimp, gui_size);
489 
490   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->pdb), gui_size);
491 
492   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->tool_info_list),
493                                       gui_size);
494   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->standard_tool_info),
495                                       gui_size);
496   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->documents),
497                                       gui_size);
498   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->templates),
499                                       gui_size);
500   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->image_new_last_template),
501                                       gui_size);
502 
503   memsize += gimp_g_list_get_memsize (gimp->context_list, 0);
504 
505   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->default_context),
506                                       gui_size);
507   memsize += gimp_object_get_memsize (GIMP_OBJECT (gimp->user_context),
508                                       gui_size);
509 
510   return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
511                                                                   gui_size);
512 }
513 
514 static void
gimp_real_initialize(Gimp * gimp,GimpInitStatusFunc status_callback)515 gimp_real_initialize (Gimp               *gimp,
516                       GimpInitStatusFunc  status_callback)
517 {
518   if (gimp->be_verbose)
519     g_print ("INIT: %s\n", G_STRFUNC);
520 
521   status_callback (_("Initialization"), NULL, 0.0);
522 
523   /*  set the last values used to default values  */
524   gimp->image_new_last_template =
525     gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image));
526 
527   /*  add data objects that need the user context  */
528   gimp_data_factories_add_builtin (gimp);
529 
530   /*  register all internal procedures  */
531   status_callback (NULL, _("Internal Procedures"), 0.2);
532   internal_procs_init (gimp->pdb);
533   gimp_pdb_compat_procs_register (gimp->pdb, gimp->pdb_compat_mode);
534 
535   gimp_plug_in_manager_initialize (gimp->plug_in_manager, status_callback);
536 
537   status_callback (NULL, "", 1.0);
538 }
539 
540 static void
gimp_real_restore(Gimp * gimp,GimpInitStatusFunc status_callback)541 gimp_real_restore (Gimp               *gimp,
542                    GimpInitStatusFunc  status_callback)
543 {
544   if (gimp->be_verbose)
545     g_print ("INIT: %s\n", G_STRFUNC);
546 
547   gimp_plug_in_manager_restore (gimp->plug_in_manager,
548                                 gimp_get_user_context (gimp), status_callback);
549 
550   /*  initialize babl fishes  */
551   status_callback (_("Initialization"), "Babl Fishes", 0.0);
552   gimp_babl_init_fishes (status_callback);
553 
554   gimp->restored = TRUE;
555 }
556 
557 static gboolean
gimp_real_exit(Gimp * gimp,gboolean force)558 gimp_real_exit (Gimp     *gimp,
559                 gboolean  force)
560 {
561   if (gimp->be_verbose)
562     g_print ("EXIT: %s\n", G_STRFUNC);
563 
564   gimp_plug_in_manager_exit (gimp->plug_in_manager);
565   gimp_modules_unload (gimp);
566 
567   gimp_data_factories_save (gimp);
568 
569   gimp_templates_save (gimp);
570   gimp_parasiterc_save (gimp);
571   gimp_unitrc_save (gimp);
572 
573   return FALSE; /* continue exiting */
574 }
575 
576 Gimp *
gimp_new(const gchar * name,const gchar * session_name,GFile * default_folder,gboolean be_verbose,gboolean no_data,gboolean no_fonts,gboolean no_interface,gboolean use_shm,gboolean use_cpu_accel,gboolean console_messages,gboolean show_playground,gboolean show_debug_menu,GimpStackTraceMode stack_trace_mode,GimpPDBCompatMode pdb_compat_mode)577 gimp_new (const gchar       *name,
578           const gchar       *session_name,
579           GFile             *default_folder,
580           gboolean           be_verbose,
581           gboolean           no_data,
582           gboolean           no_fonts,
583           gboolean           no_interface,
584           gboolean           use_shm,
585           gboolean           use_cpu_accel,
586           gboolean           console_messages,
587           gboolean           show_playground,
588           gboolean           show_debug_menu,
589           GimpStackTraceMode stack_trace_mode,
590           GimpPDBCompatMode  pdb_compat_mode)
591 {
592   Gimp *gimp;
593 
594   g_return_val_if_fail (name != NULL, NULL);
595 
596   gimp = g_object_new (GIMP_TYPE_GIMP,
597                        "name",    name,
598                        "verbose", be_verbose ? TRUE : FALSE,
599                        NULL);
600 
601   if (default_folder)
602     gimp->default_folder = g_object_ref (default_folder);
603 
604   gimp->session_name     = g_strdup (session_name);
605   gimp->no_data          = no_data          ? TRUE : FALSE;
606   gimp->no_fonts         = no_fonts         ? TRUE : FALSE;
607   gimp->no_interface     = no_interface     ? TRUE : FALSE;
608   gimp->use_shm          = use_shm          ? TRUE : FALSE;
609   gimp->use_cpu_accel    = use_cpu_accel    ? TRUE : FALSE;
610   gimp->console_messages = console_messages ? TRUE : FALSE;
611   gimp->show_playground  = show_playground  ? TRUE : FALSE;
612   gimp->show_debug_menu  = show_debug_menu  ? TRUE : FALSE;
613   gimp->stack_trace_mode = stack_trace_mode;
614   gimp->pdb_compat_mode  = pdb_compat_mode;
615 
616   return gimp;
617 }
618 
619 /**
620  * gimp_set_show_gui:
621  * @gimp:
622  * @show:
623  *
624  * Test cases that tests the UI typically don't want any windows to be
625  * presented during the test run. Allow them to set this.
626  **/
627 void
gimp_set_show_gui(Gimp * gimp,gboolean show_gui)628 gimp_set_show_gui (Gimp     *gimp,
629                    gboolean  show_gui)
630 {
631   g_return_if_fail (GIMP_IS_GIMP (gimp));
632 
633   gimp->show_gui = show_gui;
634 }
635 
636 /**
637  * gimp_get_show_gui:
638  * @gimp:
639  *
640  * Returns: %TRUE if the GUI should be shown, %FALSE otherwise.
641  **/
642 gboolean
gimp_get_show_gui(Gimp * gimp)643 gimp_get_show_gui (Gimp *gimp)
644 {
645   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
646 
647   return gimp->show_gui;
648 }
649 
650 static void
gimp_global_config_notify(GObject * global_config,GParamSpec * param_spec,GObject * edit_config)651 gimp_global_config_notify (GObject    *global_config,
652                            GParamSpec *param_spec,
653                            GObject    *edit_config)
654 {
655   GValue global_value = G_VALUE_INIT;
656   GValue edit_value   = G_VALUE_INIT;
657 
658   g_value_init (&global_value, param_spec->value_type);
659   g_value_init (&edit_value,   param_spec->value_type);
660 
661   g_object_get_property (global_config, param_spec->name, &global_value);
662   g_object_get_property (edit_config,   param_spec->name, &edit_value);
663 
664   if (g_param_values_cmp (param_spec, &global_value, &edit_value))
665     {
666       g_signal_handlers_block_by_func (edit_config,
667                                        gimp_edit_config_notify,
668                                        global_config);
669 
670       g_object_set_property (edit_config, param_spec->name, &global_value);
671 
672       g_signal_handlers_unblock_by_func (edit_config,
673                                          gimp_edit_config_notify,
674                                          global_config);
675     }
676 
677   g_value_unset (&global_value);
678   g_value_unset (&edit_value);
679 }
680 
681 static void
gimp_edit_config_notify(GObject * edit_config,GParamSpec * param_spec,GObject * global_config)682 gimp_edit_config_notify (GObject    *edit_config,
683                          GParamSpec *param_spec,
684                          GObject    *global_config)
685 {
686   GValue edit_value   = G_VALUE_INIT;
687   GValue global_value = G_VALUE_INIT;
688 
689   g_value_init (&edit_value,   param_spec->value_type);
690   g_value_init (&global_value, param_spec->value_type);
691 
692   g_object_get_property (edit_config,   param_spec->name, &edit_value);
693   g_object_get_property (global_config, param_spec->name, &global_value);
694 
695   if (g_param_values_cmp (param_spec, &edit_value, &global_value))
696     {
697       if (param_spec->flags & GIMP_CONFIG_PARAM_RESTART)
698         {
699 #ifdef GIMP_CONFIG_DEBUG
700           g_print ("NOT Applying edit_config change of '%s' to global_config "
701                    "because it needs restart\n",
702                    param_spec->name);
703 #endif
704         }
705       else
706         {
707 #ifdef GIMP_CONFIG_DEBUG
708           g_print ("Applying edit_config change of '%s' to global_config\n",
709                    param_spec->name);
710 #endif
711           g_signal_handlers_block_by_func (global_config,
712                                            gimp_global_config_notify,
713                                            edit_config);
714 
715           g_object_set_property (global_config, param_spec->name, &edit_value);
716 
717           g_signal_handlers_unblock_by_func (global_config,
718                                              gimp_global_config_notify,
719                                              edit_config);
720         }
721     }
722 
723   g_value_unset (&edit_value);
724   g_value_unset (&global_value);
725 }
726 
727 void
gimp_load_config(Gimp * gimp,GFile * alternate_system_gimprc,GFile * alternate_gimprc)728 gimp_load_config (Gimp  *gimp,
729                   GFile *alternate_system_gimprc,
730                   GFile *alternate_gimprc)
731 {
732   GimpRc *gimprc;
733 
734   g_return_if_fail (GIMP_IS_GIMP (gimp));
735   g_return_if_fail (alternate_system_gimprc == NULL ||
736                     G_IS_FILE (alternate_system_gimprc));
737   g_return_if_fail (alternate_gimprc == NULL ||
738                     G_IS_FILE (alternate_gimprc));
739   g_return_if_fail (gimp->config == NULL);
740   g_return_if_fail (gimp->edit_config == NULL);
741 
742   if (gimp->be_verbose)
743     g_print ("INIT: %s\n", G_STRFUNC);
744 
745   /*  this needs to be done before gimprc loading because gimprc can
746    *  use user defined units
747    */
748   gimp_unitrc_load (gimp);
749 
750   gimprc = gimp_rc_new (G_OBJECT (gimp),
751                         alternate_system_gimprc,
752                         alternate_gimprc,
753                         gimp->be_verbose);
754 
755   gimp->config = GIMP_CORE_CONFIG (gimprc);
756 
757   gimp->edit_config = gimp_config_duplicate (GIMP_CONFIG (gimp->config));
758 
759   g_signal_connect_object (gimp->config, "notify",
760                            G_CALLBACK (gimp_global_config_notify),
761                            gimp->edit_config, 0);
762   g_signal_connect_object (gimp->edit_config, "notify",
763                            G_CALLBACK (gimp_edit_config_notify),
764                            gimp->config, 0);
765 
766   if (! gimp->show_playground)
767     {
768       gboolean    use_opencl;
769       gboolean    use_npd_tool;
770       gboolean    use_seamless_clone_tool;
771 
772       /* Playground preferences is shown by default for unstable
773        * versions and if the associated CLI option was set. Additionally
774        * we want to show it if any of the playground options had been
775        * enabled. Otherwise you might end up getting blocked with a
776        * playground feature and forget where you can even disable it.
777        *
778        * Also we check this once at start when loading config, and not
779        * inside preferences-dialog.c because we don't want to end up
780        * with inconsistent behavior where you open once the Preferences,
781        * deactivate features, then back to preferences and the tab is
782        * gone.
783        */
784 
785       g_object_get (gimp->edit_config,
786                     "use-opencl",                     &use_opencl,
787                     "playground-npd-tool",            &use_npd_tool,
788                     "playground-seamless-clone-tool", &use_seamless_clone_tool,
789                     NULL);
790       if (use_opencl || use_npd_tool || use_seamless_clone_tool)
791         gimp->show_playground = TRUE;
792     }
793 }
794 
795 void
gimp_initialize(Gimp * gimp,GimpInitStatusFunc status_callback)796 gimp_initialize (Gimp               *gimp,
797                  GimpInitStatusFunc  status_callback)
798 {
799   g_return_if_fail (GIMP_IS_GIMP (gimp));
800   g_return_if_fail (status_callback != NULL);
801   g_return_if_fail (GIMP_IS_CORE_CONFIG (gimp->config));
802 
803   if (gimp->be_verbose)
804     g_print ("INIT: %s\n", G_STRFUNC);
805 
806   g_signal_emit (gimp, gimp_signals[INITIALIZE], 0, status_callback);
807 }
808 
809 /**
810  * gimp_restore:
811  * @gimp: a #Gimp object
812  * @error: a #GError for uncessful loading.
813  *
814  * This function always succeeds. If present, @error may be filled for
815  * possible feedback on data which failed to load. It doesn't imply any
816  * fatale error.
817  **/
818 void
gimp_restore(Gimp * gimp,GimpInitStatusFunc status_callback,GError ** error)819 gimp_restore (Gimp                *gimp,
820               GimpInitStatusFunc   status_callback,
821               GError             **error)
822 {
823   g_return_if_fail (GIMP_IS_GIMP (gimp));
824   g_return_if_fail (status_callback != NULL);
825 
826   if (gimp->be_verbose)
827     g_print ("INIT: %s\n", G_STRFUNC);
828 
829   /*  initialize  the global parasite table  */
830   status_callback (_("Looking for data files"), _("Parasites"), 0.0);
831   gimp_parasiterc_load (gimp);
832 
833   /*  initialize the lists of gimp brushes, dynamics, patterns etc.  */
834   gimp_data_factories_load (gimp, status_callback);
835 
836   /*  initialize the template list  */
837   status_callback (NULL, _("Templates"), 0.8);
838   gimp_templates_load (gimp);
839 
840   /*  initialize the module list  */
841   status_callback (NULL, _("Modules"), 0.9);
842   gimp_modules_load (gimp);
843 
844   g_signal_emit (gimp, gimp_signals[RESTORE], 0, status_callback);
845 
846   /* when done, make sure everything is clean, to clean out dirty
847    * states from data objects which reference each other and got
848    * dirtied by loading the referenced object
849    */
850   gimp_data_factories_data_clean (gimp);
851 }
852 
853 /**
854  * gimp_is_restored:
855  * @gimp: a #Gimp object
856  *
857  * Return value: %TRUE if GIMP is completely started, %FALSE otherwise.
858  **/
859 gboolean
gimp_is_restored(Gimp * gimp)860 gimp_is_restored (Gimp *gimp)
861 {
862   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
863 
864   return gimp->restored;
865 }
866 
867 /**
868  * gimp_exit:
869  * @gimp: a #Gimp object
870  * @force: whether to force the application to quit
871  *
872  * Exit this GIMP session. Unless @force is %TRUE, the user is queried
873  * whether unsaved images should be saved and can cancel the operation.
874  **/
875 void
gimp_exit(Gimp * gimp,gboolean force)876 gimp_exit (Gimp     *gimp,
877            gboolean  force)
878 {
879   gboolean  handled;
880   GList    *image_iter;
881 
882   g_return_if_fail (GIMP_IS_GIMP (gimp));
883 
884   if (gimp->be_verbose)
885     g_print ("EXIT: %s\n", G_STRFUNC);
886 
887   g_signal_emit (gimp, gimp_signals[EXIT], 0,
888                  force ? TRUE : FALSE,
889                  &handled);
890 
891   if (handled)
892     return;
893 
894   /* Get rid of images without display. We do this *after* handling the
895    * usual exit callbacks, because the things that are torn down there
896    * might have references to these images (for instance GimpActions
897    * in the UI manager).
898    */
899   while ((image_iter = gimp_get_image_iter (gimp)))
900     {
901       GimpImage *image = image_iter->data;
902 
903       g_object_unref (image);
904     }
905 }
906 
907 GList *
gimp_get_image_iter(Gimp * gimp)908 gimp_get_image_iter (Gimp *gimp)
909 {
910   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
911 
912   return GIMP_LIST (gimp->images)->queue->head;
913 }
914 
915 GList *
gimp_get_display_iter(Gimp * gimp)916 gimp_get_display_iter (Gimp *gimp)
917 {
918   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
919 
920   return GIMP_LIST (gimp->displays)->queue->head;
921 }
922 
923 GList *
gimp_get_image_windows(Gimp * gimp)924 gimp_get_image_windows (Gimp *gimp)
925 {
926   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
927 
928   return g_list_copy (gimp->image_windows);
929 }
930 
931 GList *
gimp_get_paint_info_iter(Gimp * gimp)932 gimp_get_paint_info_iter (Gimp *gimp)
933 {
934   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
935 
936   return GIMP_LIST (gimp->paint_info_list)->queue->head;
937 }
938 
939 GList *
gimp_get_tool_info_iter(Gimp * gimp)940 gimp_get_tool_info_iter (Gimp *gimp)
941 {
942   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
943 
944   return GIMP_LIST (gimp->tool_info_list)->queue->head;
945 }
946 
947 GList *
gimp_get_tool_item_iter(Gimp * gimp)948 gimp_get_tool_item_iter (Gimp *gimp)
949 {
950   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
951 
952   return GIMP_LIST (gimp->tool_item_list)->queue->head;
953 }
954 
955 GList *
gimp_get_tool_item_ui_iter(Gimp * gimp)956 gimp_get_tool_item_ui_iter (Gimp *gimp)
957 {
958   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
959 
960   return GIMP_LIST (gimp->tool_item_ui_list)->queue->head;
961 }
962 
963 GimpObject *
gimp_get_clipboard_object(Gimp * gimp)964 gimp_get_clipboard_object (Gimp *gimp)
965 {
966   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
967 
968   if (gimp->clipboard_image)
969     return GIMP_OBJECT (gimp->clipboard_image);
970 
971   return GIMP_OBJECT (gimp->clipboard_buffer);
972 }
973 
974 void
gimp_set_clipboard_image(Gimp * gimp,GimpImage * image)975 gimp_set_clipboard_image (Gimp      *gimp,
976                           GimpImage *image)
977 {
978   g_return_if_fail (GIMP_IS_GIMP (gimp));
979   g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
980 
981   g_clear_object (&gimp->clipboard_buffer);
982   g_set_object (&gimp->clipboard_image, image);
983 
984   /* we want the signal emission */
985   g_signal_emit (gimp, gimp_signals[CLIPBOARD_CHANGED], 0);
986 }
987 
988 GimpImage *
gimp_get_clipboard_image(Gimp * gimp)989 gimp_get_clipboard_image (Gimp *gimp)
990 {
991   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
992 
993   return gimp->clipboard_image;
994 }
995 
996 void
gimp_set_clipboard_buffer(Gimp * gimp,GimpBuffer * buffer)997 gimp_set_clipboard_buffer (Gimp       *gimp,
998                            GimpBuffer *buffer)
999 {
1000   g_return_if_fail (GIMP_IS_GIMP (gimp));
1001   g_return_if_fail (buffer == NULL || GIMP_IS_BUFFER (buffer));
1002 
1003   g_clear_object (&gimp->clipboard_image);
1004   g_set_object (&gimp->clipboard_buffer, buffer);
1005 
1006   /* we want the signal emission */
1007   g_signal_emit (gimp, gimp_signals[CLIPBOARD_CHANGED], 0);
1008 }
1009 
1010 GimpBuffer *
gimp_get_clipboard_buffer(Gimp * gimp)1011 gimp_get_clipboard_buffer (Gimp *gimp)
1012 {
1013   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1014 
1015   return gimp->clipboard_buffer;
1016 }
1017 
1018 GimpImage *
gimp_create_image(Gimp * gimp,gint width,gint height,GimpImageBaseType type,GimpPrecision precision,gboolean attach_comment)1019 gimp_create_image (Gimp              *gimp,
1020                    gint               width,
1021                    gint               height,
1022                    GimpImageBaseType  type,
1023                    GimpPrecision      precision,
1024                    gboolean           attach_comment)
1025 {
1026   GimpImage *image;
1027 
1028   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1029 
1030   image = gimp_image_new (gimp, width, height, type, precision);
1031 
1032   if (attach_comment)
1033     {
1034       const gchar *comment;
1035 
1036       comment = gimp_template_get_comment (gimp->config->default_image);
1037 
1038       if (comment)
1039         {
1040           GimpParasite *parasite = gimp_parasite_new ("gimp-comment",
1041                                                       GIMP_PARASITE_PERSISTENT,
1042                                                       strlen (comment) + 1,
1043                                                       comment);
1044           gimp_image_parasite_attach (image, parasite, FALSE);
1045           gimp_parasite_free (parasite);
1046         }
1047     }
1048 
1049   return image;
1050 }
1051 
1052 void
gimp_set_default_context(Gimp * gimp,GimpContext * context)1053 gimp_set_default_context (Gimp        *gimp,
1054                           GimpContext *context)
1055 {
1056   g_return_if_fail (GIMP_IS_GIMP (gimp));
1057   g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
1058 
1059   g_set_object (&gimp->default_context, context);
1060 }
1061 
1062 GimpContext *
gimp_get_default_context(Gimp * gimp)1063 gimp_get_default_context (Gimp *gimp)
1064 {
1065   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1066 
1067   return gimp->default_context;
1068 }
1069 
1070 void
gimp_set_user_context(Gimp * gimp,GimpContext * context)1071 gimp_set_user_context (Gimp        *gimp,
1072                        GimpContext *context)
1073 {
1074   g_return_if_fail (GIMP_IS_GIMP (gimp));
1075   g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
1076 
1077   g_set_object (&gimp->user_context, context);
1078 }
1079 
1080 GimpContext *
gimp_get_user_context(Gimp * gimp)1081 gimp_get_user_context (Gimp *gimp)
1082 {
1083   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1084 
1085   return gimp->user_context;
1086 }
1087 
1088 GimpToolInfo *
gimp_get_tool_info(Gimp * gimp,const gchar * tool_id)1089 gimp_get_tool_info (Gimp        *gimp,
1090                     const gchar *tool_id)
1091 {
1092   gpointer info;
1093 
1094   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1095   g_return_val_if_fail (tool_id != NULL, NULL);
1096 
1097   info = gimp_container_get_child_by_name (gimp->tool_info_list, tool_id);
1098 
1099   return (GimpToolInfo *) info;
1100 }
1101 
1102 /**
1103  * gimp_message:
1104  * @gimp:     a pointer to the %Gimp object
1105  * @handler:  either a %GimpProgress or a %GtkWidget pointer
1106  * @severity: severity of the message
1107  * @format:   printf-like format string
1108  * @...:      arguments to use with @format
1109  *
1110  * Present a message to the user. How exactly the message is displayed
1111  * depends on the @severity, the @handler object and user preferences.
1112  **/
1113 void
gimp_message(Gimp * gimp,GObject * handler,GimpMessageSeverity severity,const gchar * format,...)1114 gimp_message (Gimp                *gimp,
1115               GObject             *handler,
1116               GimpMessageSeverity  severity,
1117               const gchar         *format,
1118               ...)
1119 {
1120   va_list args;
1121 
1122   va_start (args, format);
1123 
1124   gimp_message_valist (gimp, handler, severity, format, args);
1125 
1126   va_end (args);
1127 }
1128 
1129 /**
1130  * gimp_message_valist:
1131  * @gimp:     a pointer to the %Gimp object
1132  * @handler:  either a %GimpProgress or a %GtkWidget pointer
1133  * @severity: severity of the message
1134  * @format:   printf-like format string
1135  * @args:     arguments to use with @format
1136  *
1137  * See documentation for gimp_message().
1138  **/
1139 void
gimp_message_valist(Gimp * gimp,GObject * handler,GimpMessageSeverity severity,const gchar * format,va_list args)1140 gimp_message_valist (Gimp                *gimp,
1141                      GObject             *handler,
1142                      GimpMessageSeverity  severity,
1143                      const gchar         *format,
1144                      va_list              args)
1145 {
1146   gchar *message;
1147 
1148   g_return_if_fail (GIMP_IS_GIMP (gimp));
1149   g_return_if_fail (handler == NULL || G_IS_OBJECT (handler));
1150   g_return_if_fail (format != NULL);
1151 
1152   message = g_strdup_vprintf (format, args);
1153 
1154   gimp_show_message (gimp, handler, severity, NULL, message);
1155 
1156   g_free (message);
1157 }
1158 
1159 void
gimp_message_literal(Gimp * gimp,GObject * handler,GimpMessageSeverity severity,const gchar * message)1160 gimp_message_literal (Gimp                *gimp,
1161                       GObject             *handler,
1162                       GimpMessageSeverity  severity,
1163                       const gchar         *message)
1164 {
1165   g_return_if_fail (GIMP_IS_GIMP (gimp));
1166   g_return_if_fail (handler == NULL || G_IS_OBJECT (handler));
1167   g_return_if_fail (message != NULL);
1168 
1169   gimp_show_message (gimp, handler, severity, NULL, message);
1170 }
1171 
1172 void
gimp_filter_history_changed(Gimp * gimp)1173 gimp_filter_history_changed (Gimp *gimp)
1174 {
1175   g_return_if_fail (GIMP_IS_GIMP (gimp));
1176 
1177   g_signal_emit (gimp, gimp_signals[FILTER_HISTORY_CHANGED], 0);
1178 }
1179 
1180 void
gimp_image_opened(Gimp * gimp,GFile * file)1181 gimp_image_opened (Gimp  *gimp,
1182                    GFile *file)
1183 {
1184   g_return_if_fail (GIMP_IS_GIMP (gimp));
1185   g_return_if_fail (G_IS_FILE (file));
1186 
1187   g_signal_emit (gimp, gimp_signals[IMAGE_OPENED], 0, file);
1188 }
1189 
1190 GFile *
gimp_get_temp_file(Gimp * gimp,const gchar * extension)1191 gimp_get_temp_file (Gimp        *gimp,
1192                     const gchar *extension)
1193 {
1194   static gint  id = 0;
1195   static gint  pid;
1196   gchar       *basename;
1197   GFile       *dir;
1198   GFile       *file;
1199 
1200   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1201 
1202   if (id == 0)
1203     pid = gimp_get_pid ();
1204 
1205   if (extension)
1206     basename = g_strdup_printf ("gimp-temp-%d%d.%s", pid, id++, extension);
1207   else
1208     basename = g_strdup_printf ("gimp-temp-%d%d", pid, id++);
1209 
1210   dir = gimp_file_new_for_config_path (GIMP_GEGL_CONFIG (gimp->config)->temp_path,
1211                                        NULL);
1212   if (! g_file_query_exists (dir, NULL))
1213     {
1214       /* Try to make the temp directory if it doesn't exist.
1215        * Ignore any error.
1216        */
1217       g_file_make_directory_with_parents (dir, NULL, NULL);
1218     }
1219   file = g_file_get_child (dir, basename);
1220   g_free (basename);
1221   g_object_unref (dir);
1222 
1223   return file;
1224 }
1225