gimp/plug-ins/screenshot/screenshot.c

666 lines
25 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Screenshot plug-in
* Copyright 1998-2007 Sven Neumann <sven@gimp.org>
* Copyright 2003 Henrik Brix Andersen <brix@gimp.org>
* Copyright 2012 Simone Karin Lehmann - OS X patches
* Copyright 2016 Michael Natterer <mitch@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (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
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "screenshot.h"
plug-ins: implementation of the Freedesktop portal for screenshot. I am told by the GNOME/Flatpak people that this is what we will ultimately need to implement. Basically this portal is supposed to work everywhere, in sandboxes (Flatpak, hopefully Snap too?), but also out of sandboxes, i.e. in GNOME and KDE, whether Wayland or X11. So that should be the unique API we will have to implement in the end, and every desktop environment/sandbox will need to implement this API (which is good!). Apparently it is not part of default GNOME yet, but has to be installed separately (on Fedora, package is xdg-desktop-portal-gtk for GNOME and xdg-desktop-portal-kde for KDE). Now there are currently many shortcomings, and in particular, the screenshot API has apparently no advanced features (at all!). No window snap, no rectangular selection, no delaying, no choice on including cursor or decoration, nothing! Apparently this is normal that the API presents no feature, because "the API itself is not meant to specify the details how the screenshot is obtained. Instead the portal will present the user a dialog to take a screenshot, and that screenshot will be given back to the sandboxed app". This is acceptable behavior, except that currently, the dialog has none of the basic features so this is a very bad regression. This is why I test the freedesktop API last, which basically means it will likely never be actually used. That's on purpose. At least, the code is in and will be easy to improve later. Of course, when the Freedesktop portal for screenshot will finally be featureful, it is meant to be tested first. See: https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.Screenshot.xml
2017-12-16 09:15:57 +08:00
#include "screenshot-freedesktop.h"
#include "screenshot-osx.h"
#include "screenshot-x11.h"
#include "screenshot-win32.h"
1999-11-23 06:38:02 +08:00
#include "libgimp/stdplugins-intl.h"
/* Defines */
#define PLUG_IN_PROC "plug-in-screenshot"
#define PLUG_IN_BINARY "screenshot"
#define PLUG_IN_ROLE "gimp-screenshot"
typedef struct _Screenshot Screenshot;
typedef struct _ScreenshotClass ScreenshotClass;
struct _Screenshot
{
GimpPlugIn parent_instance;
};
struct _ScreenshotClass
{
GimpPlugInClass parent_class;
};
#define SCREENSHOT_TYPE (screenshot_get_type ())
#define SCREENSHOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCREENSHOT_TYPE, Screenshot))
GType screenshot_get_type (void) G_GNUC_CONST;
static GList * screenshot_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * screenshot_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * screenshot_run (GimpProcedure *procedure,
GimpProcedureConfig *config,
gpointer run_data);
static GimpPDBStatusType shoot (GdkMonitor *monitor,
GimpImage **image,
GimpProcedureConfig *config,
GError **error);
static gboolean shoot_dialog (GimpProcedure *procedure,
GimpProcedureConfig *config,
GdkMonitor **monitor);
static gboolean shoot_quit_timeout (gpointer data);
static gboolean shoot_delay_timeout (gpointer data);
G_DEFINE_TYPE (Screenshot, screenshot, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (SCREENSHOT_TYPE)
DEFINE_STD_SET_I18N
static ScreenshotBackend backend = SCREENSHOT_BACKEND_NONE;
static ScreenshotCapabilities capabilities = 0;
static void
screenshot_class_init (ScreenshotClass *klass)
{
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
plug_in_class->query_procedures = screenshot_query_procedures;
plug_in_class->create_procedure = screenshot_create_procedure;
plug_in_class->set_i18n = STD_SET_I18N;
}
static void
screenshot_init (Screenshot *screenshot)
{
}
static GList *
screenshot_query_procedures (GimpPlugIn *plug_in)
{
return g_list_append (NULL, g_strdup (PLUG_IN_PROC));
}
static GimpProcedure *
screenshot_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
if (! strcmp (name, PLUG_IN_PROC))
{
procedure = gimp_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
screenshot_run, NULL, NULL);
gimp_procedure_set_menu_label (procedure, _("_Screenshot..."));
gimp_procedure_add_menu_path (procedure, "<Image>/File/Create");
gimp_procedure_set_documentation
(procedure,
_("Create an image from an area of the screen"),
"The plug-in takes screenshots of an "
"interactively selected window or of the desktop, "
"either the whole desktop or an interactively "
"selected region. When called non-interactively, it "
"may grab the root window or use the window-id "
"passed as a parameter. The last four parameters "
"are optional and can be used to specify the corners "
"of the region to be grabbed."
"On Mac OS X, "
"when called non-interactively, the plug-in"
"only can take screenshots of the entire root window."
"Grabbing a window or a region is not supported"
"non-interactively. To grab a region or a particular"
"window, you need to use the interactive mode.",
name);
gimp_procedure_set_attribution (procedure,
"Sven Neumann <sven@gimp.org>, "
"Henrik Brix Andersen <brix@gimp.org>,"
"Simone Karin Lehmann",
"1998 - 2008",
"v1.1 (2008/04)");
gimp_procedure_set_icon_pixbuf (procedure,
gdk_pixbuf_new_from_resource ("/org/gimp/screenshot-icons/screenshot-icon.png", NULL));
gimp_procedure_add_enum_argument (procedure, "run-mode",
"Run mode",
"The run mode",
GIMP_TYPE_RUN_MODE,
GIMP_RUN_NONINTERACTIVE,
G_PARAM_READWRITE);
/* TODO: Windows does not currently implement selecting by region to grab,
* so we'll hide this option for now */
gimp_procedure_add_choice_argument (procedure, "shoot-type",
_("Shoot _area"),
_("The shoot type"),
gimp_choice_new_with_values ("window", SHOOT_WINDOW, _("Take a screenshot of a single window"), NULL,
"screen", SHOOT_ROOT, _("Take a screenshot of the entire screen"), NULL,
#ifndef G_OS_WIN32
"region", SHOOT_REGION, _("Select a region to grab"), NULL,
#endif
NULL),
"window",
G_PARAM_READWRITE);
gimp_procedure_add_int_argument (procedure, "x1",
"X1",
"Region left x coord for SHOOT-WINDOW",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE);
gimp_procedure_add_int_argument (procedure, "y1",
"Y1",
"Region top y coord for SHOOT-WINDOW",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE);
gimp_procedure_add_int_argument (procedure, "x2",
"X2",
"Region right x coord for SHOOT-WINDOW",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE);
gimp_procedure_add_int_argument (procedure, "y2",
"Y2",
"Region bottom y coord for SHOOT-WINDOW",
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE);
gimp_procedure_add_boolean_argument (procedure, "include-pointer",
_("Include _mouse pointer"),
_("Your pointing device's cursor will be part of the image"),
FALSE,
G_PARAM_READWRITE);
/* Since no backends allow window screenshot non-interactively so far, no
* need to expose this argument to the API.
*/
gimp_procedure_add_boolean_aux_argument (procedure, "include-decoration",
_("Include window _decoration"),
_("Title bar, window borders and shadow will be part of the image"),
#ifdef PLATFORM_OSX
/* on OS X, this just means shoot the shadow, default to nope */
FALSE,
#else
TRUE,
#endif
G_PARAM_READWRITE);
gimp_procedure_add_int_aux_argument (procedure, "selection-delay",
_("Selection d_elay"),
_("Delay before selection of the window or the region"),
0, 20, 0,
G_PARAM_READWRITE);
gimp_procedure_add_int_aux_argument (procedure, "screenshot-delay",
_("Screenshot dela_y"),
_("Delay before snapping the screenshot"),
0, 20, 0,
G_PARAM_READWRITE);
gimp_procedure_add_choice_argument (procedure, "color-profile",
_("Color _Profile"),
"",
gimp_choice_new_with_values ("monitor", SCREENSHOT_PROFILE_POLICY_MONITOR, _("Tag image with monitor profile"), NULL,
"srgb", SCREENSHOT_PROFILE_POLICY_SRGB, _("Convert image with sRGB"), NULL,
NULL),
"monitor",
G_PARAM_READWRITE);
gimp_procedure_add_image_return_value (procedure, "image",
"Image",
"Output image",
FALSE,
G_PARAM_READWRITE);
}
return procedure;
}
static GimpValueArray *
screenshot_run (GimpProcedure *procedure,
GimpProcedureConfig *config,
gpointer run_data)
{
GimpValueArray *return_vals;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpRunMode run_mode;
GdkMonitor *monitor = NULL;
GimpImage *image = NULL;
GError *error = NULL;
ShootType shoot_type;
ScreenshotProfilePolicy profile_policy;
gegl_init (NULL, NULL);
g_object_get (config, "run-mode", &run_mode, NULL);
shoot_type = gimp_procedure_config_get_choice_id (GIMP_PROCEDURE_CONFIG (config),
"shoot-type");
if (! gdk_init_check (NULL, NULL))
{
g_set_error_literal (&error, GIMP_PLUG_IN_ERROR, 0, _("GDK initialization failed."));
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
error);
}
#ifdef PLATFORM_OSX
if (! backend && screenshot_osx_available ())
{
backend = SCREENSHOT_BACKEND_OSX;
capabilities = screenshot_osx_get_capabilities ();
}
#endif
#ifdef G_OS_WIN32
if (! backend && screenshot_win32_available ())
{
backend = SCREENSHOT_BACKEND_WIN32;
capabilities = screenshot_win32_get_capabilities ();
}
#endif
#ifdef GDK_WINDOWING_X11
if (! backend && screenshot_x11_available ())
{
backend = SCREENSHOT_BACKEND_X11;
capabilities = screenshot_x11_get_capabilities ();
}
#endif
if (! backend && screenshot_freedesktop_available ())
plug-ins: implementation of the Freedesktop portal for screenshot. I am told by the GNOME/Flatpak people that this is what we will ultimately need to implement. Basically this portal is supposed to work everywhere, in sandboxes (Flatpak, hopefully Snap too?), but also out of sandboxes, i.e. in GNOME and KDE, whether Wayland or X11. So that should be the unique API we will have to implement in the end, and every desktop environment/sandbox will need to implement this API (which is good!). Apparently it is not part of default GNOME yet, but has to be installed separately (on Fedora, package is xdg-desktop-portal-gtk for GNOME and xdg-desktop-portal-kde for KDE). Now there are currently many shortcomings, and in particular, the screenshot API has apparently no advanced features (at all!). No window snap, no rectangular selection, no delaying, no choice on including cursor or decoration, nothing! Apparently this is normal that the API presents no feature, because "the API itself is not meant to specify the details how the screenshot is obtained. Instead the portal will present the user a dialog to take a screenshot, and that screenshot will be given back to the sandboxed app". This is acceptable behavior, except that currently, the dialog has none of the basic features so this is a very bad regression. This is why I test the freedesktop API last, which basically means it will likely never be actually used. That's on purpose. At least, the code is in and will be easy to improve later. Of course, when the Freedesktop portal for screenshot will finally be featureful, it is meant to be tested first. See: https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.Screenshot.xml
2017-12-16 09:15:57 +08:00
{
backend = SCREENSHOT_BACKEND_FREEDESKTOP;
capabilities = screenshot_freedesktop_get_capabilities ();
}
if (backend == SCREENSHOT_BACKEND_NONE)
{
g_set_error_literal (&error, GIMP_PLUG_IN_ERROR, 0,
_("No screenshot backends available."));
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
error);
}
/* how are we running today? */
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_ui_init (PLUG_IN_BINARY);
/* In interactive mode, coords are always reset. */
g_object_set (config,
"x1", 0, "y1", 0,
"x2", 0, "y2", 0,
NULL);
if ((shoot_type == SHOOT_WINDOW &&
! (capabilities & SCREENSHOT_CAN_SHOOT_WINDOW)) ||
(shoot_type == SHOOT_REGION &&
! (capabilities & SCREENSHOT_CAN_SHOOT_REGION)))
{
/* Shoot root is the only type of shoot which is definitely
* shared by all screenshot backends (basically just snap the
* whole display setup).
*/
g_object_set (config, "shoot-type", "screen", NULL);
}
/* Get information from the dialog. Freedesktop portal comes with
* its own dialog.
*/
if (backend != SCREENSHOT_BACKEND_FREEDESKTOP)
{
if (! shoot_dialog (procedure, config, &monitor))
status = GIMP_PDB_CANCEL;
}
else
{
/* This is ugly but in reality we have no idea on which monitor
* a screenshot was taken from with portals. It's like a
* better-than-nothing trick for easy single-display cases.
*/
monitor = gdk_display_get_monitor (gdk_display_get_default (), 0);
}
break;
case GIMP_RUN_NONINTERACTIVE:
if (backend == SCREENSHOT_BACKEND_FREEDESKTOP)
{
/* With portals, even the basic full screenshot is interactive. */
status = GIMP_PDB_CALLING_ERROR;
}
else if (! (capabilities & SCREENSHOT_CAN_PICK_NONINTERACTIVELY))
{
if (shoot_type == SHOOT_WINDOW ||
shoot_type == SHOOT_REGION)
status = GIMP_PDB_CALLING_ERROR;
}
break;
case GIMP_RUN_WITH_LAST_VALS:
break;
default:
break;
}
if (status == GIMP_PDB_SUCCESS)
status = shoot (monitor, &image, config, &error);
if (status == GIMP_PDB_SUCCESS)
{
gchar *comment = gimp_get_default_comment ();
gimp_image_undo_disable (image);
profile_policy = gimp_procedure_config_get_choice_id (GIMP_PROCEDURE_CONFIG (config),
"color-profile");
if (run_mode == GIMP_RUN_NONINTERACTIVE)
profile_policy = SCREENSHOT_PROFILE_POLICY_MONITOR;
if (profile_policy == SCREENSHOT_PROFILE_POLICY_SRGB)
{
GimpColorProfile *srgb_profile = gimp_color_profile_new_rgb_srgb ();
gimp_image_convert_color_profile (image,
srgb_profile,
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
TRUE);
g_object_unref (srgb_profile);
}
if (comment)
{
GimpParasite *parasite;
parasite = gimp_parasite_new ("gimp-comment",
GIMP_PARASITE_PERSISTENT,
strlen (comment) + 1, comment);
gimp_image_attach_parasite (image, parasite);
gimp_parasite_free (parasite);
g_free (comment);
}
gimp_image_undo_enable (image);
if (run_mode == GIMP_RUN_INTERACTIVE)
{
guint select_delay;
gimp_display_new (image);
g_object_get (config,
"selection-delay", &select_delay,
NULL);
/* Give some sort of feedback that the shot is done */
if (select_delay > 0)
{
gdk_display_beep (gdk_monitor_get_display (monitor));
/* flush so the beep makes it to the server */
gdk_display_flush (gdk_monitor_get_display (monitor));
}
}
}
return_vals = gimp_procedure_new_return_values (procedure, status, error);
if (status == GIMP_PDB_SUCCESS)
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
return return_vals;
}
2005-06-15 02:25:33 +08:00
/* The main Screenshot function */
static GimpPDBStatusType
shoot (GdkMonitor *monitor,
GimpImage **image,
GimpProcedureConfig *config,
GError **error)
{
#if defined(PLATFORM_OSX) || defined(G_OS_WIN32)
ShootType shoot_type;
#endif
gboolean decorate;
guint select_delay;
guint screenshot_delay;
gboolean show_cursor;
g_object_get (config,
"screenshot-delay", &screenshot_delay,
"selection-delay", &select_delay,
"include-decoration", &decorate,
"include-pointer", &show_cursor,
NULL);
#if defined(PLATFORM_OSX) || defined(G_OS_WIN32)
shoot_type = gimp_procedure_config_get_choice_id (GIMP_PROCEDURE_CONFIG (config),
"shoot-type");
#endif
#ifdef PLATFORM_OSX
if (backend == SCREENSHOT_BACKEND_OSX)
return screenshot_osx_shoot (shoot_type,
select_delay, screenshot_delay,
decorate, show_cursor,
image, error);
#endif
#ifdef G_OS_WIN32
if (backend == SCREENSHOT_BACKEND_WIN32)
return screenshot_win32_shoot (shoot_type, screenshot_delay, show_cursor,
monitor, image, error);
#endif
plug-ins: implementation of the Freedesktop portal for screenshot. I am told by the GNOME/Flatpak people that this is what we will ultimately need to implement. Basically this portal is supposed to work everywhere, in sandboxes (Flatpak, hopefully Snap too?), but also out of sandboxes, i.e. in GNOME and KDE, whether Wayland or X11. So that should be the unique API we will have to implement in the end, and every desktop environment/sandbox will need to implement this API (which is good!). Apparently it is not part of default GNOME yet, but has to be installed separately (on Fedora, package is xdg-desktop-portal-gtk for GNOME and xdg-desktop-portal-kde for KDE). Now there are currently many shortcomings, and in particular, the screenshot API has apparently no advanced features (at all!). No window snap, no rectangular selection, no delaying, no choice on including cursor or decoration, nothing! Apparently this is normal that the API presents no feature, because "the API itself is not meant to specify the details how the screenshot is obtained. Instead the portal will present the user a dialog to take a screenshot, and that screenshot will be given back to the sandboxed app". This is acceptable behavior, except that currently, the dialog has none of the basic features so this is a very bad regression. This is why I test the freedesktop API last, which basically means it will likely never be actually used. That's on purpose. At least, the code is in and will be easy to improve later. Of course, when the Freedesktop portal for screenshot will finally be featureful, it is meant to be tested first. See: https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.Screenshot.xml
2017-12-16 09:15:57 +08:00
if (backend == SCREENSHOT_BACKEND_FREEDESKTOP)
return screenshot_freedesktop_shoot (monitor, image, error);
#ifdef GDK_WINDOWING_X11
if (backend == SCREENSHOT_BACKEND_X11)
return screenshot_x11_shoot (config, monitor, image, error);
#endif
return GIMP_PDB_CALLING_ERROR; /* silence compiler */
}
2005-06-15 02:25:33 +08:00
/* Screenshot dialog */
static gboolean
shoot_dialog (GimpProcedure *procedure,
GimpProcedureConfig *config,
GdkMonitor **monitor)
{
GtkWidget *dialog;
GimpValueArray *values;
GValue value = G_VALUE_INIT;
gboolean run;
dialog = gimp_procedure_dialog_new (procedure,
GIMP_PROCEDURE_CONFIG (config),
_("Screenshot"));
gimp_procedure_dialog_set_ok_label (GIMP_PROCEDURE_DIALOG (dialog), _("S_nap"));
if (capabilities & SCREENSHOT_CAN_SHOOT_POINTER ||
capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS)
{
if (! (capabilities & SCREENSHOT_CAN_SHOOT_POINTER))
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"contents-box",
"include-decoration",
NULL);
else if (! (capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS))
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"contents-box",
"include-pointer",
NULL);
else
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"contents-box",
"include-decoration",
"include-pointer",
NULL);
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
"contents-frame-title",
_("Contents"), FALSE, FALSE);
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
"contents-frame", "contents-frame-title",
FALSE, "contents-box");
if (capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS)
{
values = gimp_value_array_new (1);
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "window");
gimp_value_array_append (values, &value);
g_value_unset (&value);
gimp_procedure_dialog_set_sensitive_if_in (GIMP_PROCEDURE_DIALOG (dialog),
"include-decoration",
NULL, "shoot-type",
values, TRUE);
}
if (capabilities & SCREENSHOT_CAN_SHOOT_POINTER)
{
values = gimp_value_array_new (1);
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "region");
gimp_value_array_append (values, &value);
g_value_unset (&value);
gimp_procedure_dialog_set_sensitive_if_in (GIMP_PROCEDURE_DIALOG (dialog),
"include-pointer",
NULL, "shoot-type",
values, FALSE);
}
}
if (capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT)
{
if (capabilities & SCREENSHOT_CAN_PICK_WINDOW)
{
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"delay-box",
"selection-delay",
"screenshot-delay",
NULL);
values = gimp_value_array_new (1);
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, "screen");
gimp_value_array_append (values, &value);
g_value_unset (&value);
gimp_procedure_dialog_set_sensitive_if_in (GIMP_PROCEDURE_DIALOG (dialog),
"selection-delay",
NULL, "shoot-type",
values, FALSE);
}
else
{
gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
"delay-box", "screenshot-delay", NULL);
}
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
"delay-frame-title",
_("Delay"), FALSE, FALSE);
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
"delay-frame", "delay-frame-title",
FALSE, "delay-box");
}
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "shoot-type", NULL);
if ((capabilities & SCREENSHOT_CAN_SHOOT_POINTER) ||
(capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS))
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "contents-frame", NULL);
if (capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT)
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "delay-frame", NULL);
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "color-profile", NULL);
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
/* Get the screen on which we are running */
if (run)
*monitor = gimp_widget_get_monitor (dialog);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_widget_destroy (dialog);
if (run)
{
/* A short timeout to give the server a chance to
* redraw the area that was obscured by our dialog.
*/
g_timeout_add (100, shoot_quit_timeout, NULL);
gtk_main ();
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
return run;
}
static gboolean
shoot_quit_timeout (gpointer data)
{
gtk_main_quit ();
return FALSE;
}
static gboolean
shoot_delay_timeout (gpointer data)
{
gint *seconds_left = data;
(*seconds_left)--;
if (!*seconds_left)
gtk_main_quit ();
return *seconds_left;
}
/* public functions */
void
screenshot_wait_delay (gint seconds)
{
g_timeout_add (1000, shoot_delay_timeout, &seconds);
gtk_main ();
}