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