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 <gdk-pixbuf/gdk-pixbuf.h>
21 #include <gegl.h>
22 
23 #include "libgimpbase/gimpbase.h"
24 
25 #include "core-types.h"
26 
27 #include "gimp.h"
28 #include "gimp-gui.h"
29 #include "gimpcontainer.h"
30 #include "gimpcontext.h"
31 #include "gimpimage.h"
32 #include "gimpprogress.h"
33 #include "gimpwaitable.h"
34 
35 #include "about.h"
36 
37 #include "gimp-intl.h"
38 
39 
40 void
gimp_gui_init(Gimp * gimp)41 gimp_gui_init (Gimp *gimp)
42 {
43   g_return_if_fail (GIMP_IS_GIMP (gimp));
44 
45   gimp->gui.ungrab                 = NULL;
46   gimp->gui.threads_enter          = NULL;
47   gimp->gui.threads_leave          = NULL;
48   gimp->gui.set_busy               = NULL;
49   gimp->gui.unset_busy             = NULL;
50   gimp->gui.show_message           = NULL;
51   gimp->gui.help                   = NULL;
52   gimp->gui.get_program_class      = NULL;
53   gimp->gui.get_display_name       = NULL;
54   gimp->gui.get_user_time          = NULL;
55   gimp->gui.get_theme_dir          = NULL;
56   gimp->gui.get_icon_theme_dir     = NULL;
57   gimp->gui.display_get_by_id      = NULL;
58   gimp->gui.display_get_id         = NULL;
59   gimp->gui.display_get_window_id  = NULL;
60   gimp->gui.display_create         = NULL;
61   gimp->gui.display_delete         = NULL;
62   gimp->gui.displays_reconnect     = NULL;
63   gimp->gui.progress_new           = NULL;
64   gimp->gui.progress_free          = NULL;
65   gimp->gui.pdb_dialog_set         = NULL;
66   gimp->gui.pdb_dialog_close       = NULL;
67   gimp->gui.recent_list_add_file   = NULL;
68   gimp->gui.recent_list_load       = NULL;
69   gimp->gui.get_mount_operation    = NULL;
70   gimp->gui.query_profile_policy   = NULL;
71 }
72 
73 void
gimp_gui_ungrab(Gimp * gimp)74 gimp_gui_ungrab (Gimp *gimp)
75 {
76   g_return_if_fail (GIMP_IS_GIMP (gimp));
77 
78   if (gimp->gui.ungrab)
79     gimp->gui.ungrab (gimp);
80 }
81 
82 void
gimp_threads_enter(Gimp * gimp)83 gimp_threads_enter (Gimp *gimp)
84 {
85   g_return_if_fail (GIMP_IS_GIMP (gimp));
86 
87   if (gimp->gui.threads_enter)
88     gimp->gui.threads_enter (gimp);
89 }
90 
91 void
gimp_threads_leave(Gimp * gimp)92 gimp_threads_leave (Gimp *gimp)
93 {
94   g_return_if_fail (GIMP_IS_GIMP (gimp));
95 
96   if (gimp->gui.threads_leave)
97     gimp->gui.threads_leave (gimp);
98 }
99 
100 void
gimp_set_busy(Gimp * gimp)101 gimp_set_busy (Gimp *gimp)
102 {
103   g_return_if_fail (GIMP_IS_GIMP (gimp));
104 
105   /* FIXME: gimp_busy HACK */
106   gimp->busy++;
107 
108   if (gimp->busy == 1)
109     {
110       if (gimp->gui.set_busy)
111         gimp->gui.set_busy (gimp);
112     }
113 }
114 
115 static gboolean
gimp_idle_unset_busy(gpointer data)116 gimp_idle_unset_busy (gpointer data)
117 {
118   Gimp *gimp = data;
119 
120   gimp_unset_busy (gimp);
121 
122   gimp->busy_idle_id = 0;
123 
124   return FALSE;
125 }
126 
127 void
gimp_set_busy_until_idle(Gimp * gimp)128 gimp_set_busy_until_idle (Gimp *gimp)
129 {
130   g_return_if_fail (GIMP_IS_GIMP (gimp));
131 
132   if (! gimp->busy_idle_id)
133     {
134       gimp_set_busy (gimp);
135 
136       gimp->busy_idle_id = g_idle_add_full (G_PRIORITY_HIGH,
137                                             gimp_idle_unset_busy, gimp,
138                                             NULL);
139     }
140 }
141 
142 void
gimp_unset_busy(Gimp * gimp)143 gimp_unset_busy (Gimp *gimp)
144 {
145   g_return_if_fail (GIMP_IS_GIMP (gimp));
146   g_return_if_fail (gimp->busy > 0);
147 
148   /* FIXME: gimp_busy HACK */
149   gimp->busy--;
150 
151   if (gimp->busy == 0)
152     {
153       if (gimp->gui.unset_busy)
154         gimp->gui.unset_busy (gimp);
155     }
156 }
157 
158 void
gimp_show_message(Gimp * gimp,GObject * handler,GimpMessageSeverity severity,const gchar * domain,const gchar * message)159 gimp_show_message (Gimp                *gimp,
160                    GObject             *handler,
161                    GimpMessageSeverity  severity,
162                    const gchar         *domain,
163                    const gchar         *message)
164 {
165   const gchar *desc = (severity == GIMP_MESSAGE_ERROR) ? "Error" : "Message";
166 
167   g_return_if_fail (GIMP_IS_GIMP (gimp));
168   g_return_if_fail (handler == NULL || G_IS_OBJECT (handler));
169   g_return_if_fail (message != NULL);
170 
171   if (! domain)
172     domain = GIMP_ACRONYM;
173 
174   if (! gimp->console_messages)
175     {
176       if (gimp->gui.show_message)
177         {
178           gimp->gui.show_message (gimp, handler, severity,
179                                   domain, message);
180           return;
181         }
182       else if (GIMP_IS_PROGRESS (handler) &&
183                gimp_progress_message (GIMP_PROGRESS (handler), gimp,
184                                       severity, domain, message))
185         {
186           /* message has been handled by GimpProgress */
187           return;
188         }
189     }
190 
191   gimp_enum_get_value (GIMP_TYPE_MESSAGE_SEVERITY, severity,
192                        NULL, NULL, &desc, NULL);
193   g_printerr ("%s-%s: %s\n\n", domain, desc, message);
194 }
195 
196 void
gimp_wait(Gimp * gimp,GimpWaitable * waitable,const gchar * format,...)197 gimp_wait (Gimp         *gimp,
198            GimpWaitable *waitable,
199            const gchar  *format,
200            ...)
201 {
202   va_list  args;
203   gchar   *message;
204 
205   g_return_if_fail (GIMP_IS_GIMP (gimp));
206   g_return_if_fail (GIMP_IS_WAITABLE (waitable));
207   g_return_if_fail (format != NULL);
208 
209   if (gimp_waitable_wait_for (waitable, 0.5 * G_TIME_SPAN_SECOND))
210     return;
211 
212   va_start (args, format);
213 
214   message = g_strdup_vprintf (format, args);
215 
216   va_end (args);
217 
218   if (! gimp->console_messages &&
219       gimp->gui.wait           &&
220       gimp->gui.wait (gimp, waitable, message))
221     {
222       return;
223     }
224 
225   /* Translator:  This message is displayed while GIMP is waiting for
226    * some operation to finish.  The %s argument is a message describing
227    * the operation.
228    */
229   g_printerr (_("Please wait: %s\n"), message);
230 
231   gimp_waitable_wait (waitable);
232 
233   g_free (message);
234 }
235 
236 void
gimp_help(Gimp * gimp,GimpProgress * progress,const gchar * help_domain,const gchar * help_id)237 gimp_help (Gimp         *gimp,
238            GimpProgress *progress,
239            const gchar  *help_domain,
240            const gchar  *help_id)
241 {
242   g_return_if_fail (GIMP_IS_GIMP (gimp));
243   g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
244 
245   if (gimp->gui.help)
246     gimp->gui.help (gimp, progress, help_domain, help_id);
247 }
248 
249 const gchar *
gimp_get_program_class(Gimp * gimp)250 gimp_get_program_class (Gimp *gimp)
251 {
252   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
253 
254   if (gimp->gui.get_program_class)
255     return gimp->gui.get_program_class (gimp);
256 
257   return NULL;
258 }
259 
260 gchar *
gimp_get_display_name(Gimp * gimp,gint display_ID,GObject ** screen,gint * monitor)261 gimp_get_display_name (Gimp     *gimp,
262                        gint      display_ID,
263                        GObject **screen,
264                        gint     *monitor)
265 {
266   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
267   g_return_val_if_fail (screen != NULL, NULL);
268   g_return_val_if_fail (monitor != NULL, NULL);
269 
270   if (gimp->gui.get_display_name)
271     return gimp->gui.get_display_name (gimp, display_ID, screen, monitor);
272 
273   *screen  = NULL;
274   *monitor = 0;
275 
276   return NULL;
277 }
278 
279 /**
280  * gimp_get_user_time:
281  * @gimp:
282  *
283  * Returns the timestamp of the last user interaction. The timestamp is
284  * taken from events caused by user interaction such as key presses or
285  * pointer movements. See gdk_x11_display_get_user_time().
286  *
287  * Return value: the timestamp of the last user interaction
288  */
289 guint32
gimp_get_user_time(Gimp * gimp)290 gimp_get_user_time (Gimp *gimp)
291 {
292   g_return_val_if_fail (GIMP_IS_GIMP (gimp), 0);
293 
294   if (gimp->gui.get_user_time)
295     return gimp->gui.get_user_time (gimp);
296 
297   return 0;
298 }
299 
300 GFile *
gimp_get_theme_dir(Gimp * gimp)301 gimp_get_theme_dir (Gimp *gimp)
302 {
303   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
304 
305   if (gimp->gui.get_theme_dir)
306     return gimp->gui.get_theme_dir (gimp);
307 
308   return NULL;
309 }
310 
311 GFile *
gimp_get_icon_theme_dir(Gimp * gimp)312 gimp_get_icon_theme_dir (Gimp *gimp)
313 {
314   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
315 
316   if (gimp->gui.get_icon_theme_dir)
317     return gimp->gui.get_icon_theme_dir (gimp);
318 
319   return NULL;
320 }
321 
322 GimpObject *
gimp_get_window_strategy(Gimp * gimp)323 gimp_get_window_strategy (Gimp *gimp)
324 {
325   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
326 
327   if (gimp->gui.get_window_strategy)
328     return gimp->gui.get_window_strategy (gimp);
329 
330   return NULL;
331 }
332 
333 GimpObject *
gimp_get_empty_display(Gimp * gimp)334 gimp_get_empty_display (Gimp *gimp)
335 {
336   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
337 
338   if (gimp->gui.get_empty_display)
339     return gimp->gui.get_empty_display (gimp);
340 
341   return NULL;
342 }
343 
344 GimpObject *
gimp_get_display_by_ID(Gimp * gimp,gint ID)345 gimp_get_display_by_ID (Gimp *gimp,
346                         gint  ID)
347 {
348   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
349 
350   if (gimp->gui.display_get_by_id)
351     return gimp->gui.display_get_by_id (gimp, ID);
352 
353   return NULL;
354 }
355 
356 gint
gimp_get_display_ID(Gimp * gimp,GimpObject * display)357 gimp_get_display_ID (Gimp       *gimp,
358                      GimpObject *display)
359 {
360   g_return_val_if_fail (GIMP_IS_GIMP (gimp), -1);
361   g_return_val_if_fail (GIMP_IS_OBJECT (display), -1);
362 
363   if (gimp->gui.display_get_id)
364     return gimp->gui.display_get_id (display);
365 
366   return -1;
367 }
368 
369 guint32
gimp_get_display_window_id(Gimp * gimp,GimpObject * display)370 gimp_get_display_window_id (Gimp       *gimp,
371                             GimpObject *display)
372 {
373   g_return_val_if_fail (GIMP_IS_GIMP (gimp), -1);
374   g_return_val_if_fail (GIMP_IS_OBJECT (display), -1);
375 
376   if (gimp->gui.display_get_window_id)
377     return gimp->gui.display_get_window_id (display);
378 
379   return -1;
380 }
381 
382 GimpObject *
gimp_create_display(Gimp * gimp,GimpImage * image,GimpUnit unit,gdouble scale,GObject * screen,gint monitor)383 gimp_create_display (Gimp      *gimp,
384                      GimpImage *image,
385                      GimpUnit   unit,
386                      gdouble    scale,
387                      GObject   *screen,
388                      gint       monitor)
389 {
390   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
391   g_return_val_if_fail (image == NULL || GIMP_IS_IMAGE (image), NULL);
392   g_return_val_if_fail (screen == NULL || G_IS_OBJECT (screen), NULL);
393 
394   if (gimp->gui.display_create)
395     return gimp->gui.display_create (gimp, image, unit, scale, screen, monitor);
396 
397   return NULL;
398 }
399 
400 void
gimp_delete_display(Gimp * gimp,GimpObject * display)401 gimp_delete_display (Gimp       *gimp,
402                      GimpObject *display)
403 {
404   g_return_if_fail (GIMP_IS_GIMP (gimp));
405   g_return_if_fail (GIMP_IS_OBJECT (display));
406 
407   if (gimp->gui.display_delete)
408     gimp->gui.display_delete (display);
409 }
410 
411 void
gimp_reconnect_displays(Gimp * gimp,GimpImage * old_image,GimpImage * new_image)412 gimp_reconnect_displays (Gimp      *gimp,
413                          GimpImage *old_image,
414                          GimpImage *new_image)
415 {
416   g_return_if_fail (GIMP_IS_GIMP (gimp));
417   g_return_if_fail (GIMP_IS_IMAGE (old_image));
418   g_return_if_fail (GIMP_IS_IMAGE (new_image));
419 
420   if (gimp->gui.displays_reconnect)
421     gimp->gui.displays_reconnect (gimp, old_image, new_image);
422 }
423 
424 GimpProgress *
gimp_new_progress(Gimp * gimp,GimpObject * display)425 gimp_new_progress (Gimp       *gimp,
426                    GimpObject *display)
427 {
428   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
429   g_return_val_if_fail (display == NULL || GIMP_IS_OBJECT (display), NULL);
430 
431   if (gimp->gui.progress_new)
432     return gimp->gui.progress_new (gimp, display);
433 
434   return NULL;
435 }
436 
437 void
gimp_free_progress(Gimp * gimp,GimpProgress * progress)438 gimp_free_progress (Gimp         *gimp,
439                     GimpProgress *progress)
440 {
441   g_return_if_fail (GIMP_IS_GIMP (gimp));
442   g_return_if_fail (GIMP_IS_PROGRESS (progress));
443 
444   if (gimp->gui.progress_free)
445     gimp->gui.progress_free (gimp, progress);
446 }
447 
448 gboolean
gimp_pdb_dialog_new(Gimp * gimp,GimpContext * context,GimpProgress * progress,GimpContainer * container,const gchar * title,const gchar * callback_name,const gchar * object_name,...)449 gimp_pdb_dialog_new (Gimp          *gimp,
450                      GimpContext   *context,
451                      GimpProgress  *progress,
452                      GimpContainer *container,
453                      const gchar   *title,
454                      const gchar   *callback_name,
455                      const gchar   *object_name,
456                      ...)
457 {
458   gboolean retval = FALSE;
459 
460   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
461   g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
462   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
463   g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
464   g_return_val_if_fail (title != NULL, FALSE);
465   g_return_val_if_fail (callback_name != NULL, FALSE);
466 
467   if (gimp->gui.pdb_dialog_new)
468     {
469       va_list args;
470 
471       va_start (args, object_name);
472 
473       retval = gimp->gui.pdb_dialog_new (gimp, context, progress,
474                                          container, title,
475                                          callback_name, object_name,
476                                          args);
477 
478       va_end (args);
479     }
480 
481   return retval;
482 }
483 
484 gboolean
gimp_pdb_dialog_set(Gimp * gimp,GimpContainer * container,const gchar * callback_name,const gchar * object_name,...)485 gimp_pdb_dialog_set (Gimp          *gimp,
486                      GimpContainer *container,
487                      const gchar   *callback_name,
488                      const gchar   *object_name,
489                      ...)
490 {
491   gboolean retval = FALSE;
492 
493   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
494   g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
495   g_return_val_if_fail (callback_name != NULL, FALSE);
496   g_return_val_if_fail (object_name != NULL, FALSE);
497 
498   if (gimp->gui.pdb_dialog_set)
499     {
500       va_list args;
501 
502       va_start (args, object_name);
503 
504       retval = gimp->gui.pdb_dialog_set (gimp, container, callback_name,
505                                          object_name, args);
506 
507       va_end (args);
508     }
509 
510   return retval;
511 }
512 
513 gboolean
gimp_pdb_dialog_close(Gimp * gimp,GimpContainer * container,const gchar * callback_name)514 gimp_pdb_dialog_close (Gimp          *gimp,
515                        GimpContainer *container,
516                        const gchar   *callback_name)
517 {
518   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
519   g_return_val_if_fail (GIMP_IS_CONTAINER (container), FALSE);
520   g_return_val_if_fail (callback_name != NULL, FALSE);
521 
522   if (gimp->gui.pdb_dialog_close)
523     return gimp->gui.pdb_dialog_close (gimp, container, callback_name);
524 
525   return FALSE;
526 }
527 
528 gboolean
gimp_recent_list_add_file(Gimp * gimp,GFile * file,const gchar * mime_type)529 gimp_recent_list_add_file (Gimp        *gimp,
530                            GFile       *file,
531                            const gchar *mime_type)
532 {
533   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
534   g_return_val_if_fail (G_IS_FILE (file), FALSE);
535 
536   if (gimp->gui.recent_list_add_file)
537     return gimp->gui.recent_list_add_file (gimp, file, mime_type);
538 
539   return FALSE;
540 }
541 
542 void
gimp_recent_list_load(Gimp * gimp)543 gimp_recent_list_load (Gimp *gimp)
544 {
545   g_return_if_fail (GIMP_IS_GIMP (gimp));
546 
547   if (gimp->gui.recent_list_load)
548     gimp->gui.recent_list_load (gimp);
549 }
550 
551 GMountOperation *
gimp_get_mount_operation(Gimp * gimp,GimpProgress * progress)552 gimp_get_mount_operation (Gimp         *gimp,
553                           GimpProgress *progress)
554 {
555   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
556   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
557 
558   if (gimp->gui.get_mount_operation)
559     return gimp->gui.get_mount_operation (gimp, progress);
560 
561   return g_mount_operation_new ();
562 }
563 
564 GimpColorProfilePolicy
gimp_query_profile_policy(Gimp * gimp,GimpImage * image,GimpContext * context,GimpColorProfile ** dest_profile,GimpColorRenderingIntent * intent,gboolean * bpc,gboolean * dont_ask)565 gimp_query_profile_policy (Gimp                      *gimp,
566                            GimpImage                 *image,
567                            GimpContext               *context,
568                            GimpColorProfile         **dest_profile,
569                            GimpColorRenderingIntent  *intent,
570                            gboolean                  *bpc,
571                            gboolean                  *dont_ask)
572 {
573   g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_COLOR_PROFILE_POLICY_KEEP);
574   g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_COLOR_PROFILE_POLICY_KEEP);
575   g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_COLOR_PROFILE_POLICY_KEEP);
576   g_return_val_if_fail (dest_profile != NULL, GIMP_COLOR_PROFILE_POLICY_KEEP);
577 
578   if (gimp->gui.query_profile_policy)
579     return gimp->gui.query_profile_policy (gimp, image, context,
580                                            dest_profile,
581                                            intent, bpc,
582                                            dont_ask);
583 
584   return GIMP_COLOR_PROFILE_POLICY_KEEP;
585 }
586