mirror of https://github.com/GNOME/gimp.git
plug-ins: port screenshot to GimpProcedureDialog and gimp_procedure_new2().
A lot less lines for the same functionalities! This includes improvements too: * "include-pointer" as new PDB argument; * settings storage thanks to GimpProcedureDialog; * it should hopefully work better in non-interactive (though it's untested). The macOS and Windows screenshots are untested after this change, though they should still work the same. Please report if there is any problem!
This commit is contained in:
parent
60aeff5623
commit
f6da799c11
|
@ -123,10 +123,9 @@ screenshot_freedesktop_dbus_signal (GDBusProxy *proxy,
|
|||
}
|
||||
|
||||
GimpPDBStatusType
|
||||
screenshot_freedesktop_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
screenshot_freedesktop_shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
{
|
||||
GVariant *retval;
|
||||
GVariantBuilder *options;
|
||||
|
@ -149,15 +148,6 @@ screenshot_freedesktop_shoot (ScreenshotValues *shootvals,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (shootvals->shoot_type != SHOOT_ROOT)
|
||||
{
|
||||
/* This should not happen. */
|
||||
return GIMP_PDB_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
if (shootvals->screenshot_delay > 0)
|
||||
screenshot_delay (shootvals->screenshot_delay);
|
||||
|
||||
options = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
/* "interactive" option will display the options first (otherwise, it
|
||||
* makes a screenshot first, then proposes to tweak. Since version 2
|
||||
|
|
|
@ -23,8 +23,7 @@ gboolean screenshot_freedesktop_available (void);
|
|||
|
||||
ScreenshotCapabilities screenshot_freedesktop_get_capabilities (void);
|
||||
|
||||
GimpPDBStatusType screenshot_freedesktop_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpPDBStatusType screenshot_freedesktop_shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
|
||||
|
|
|
@ -74,10 +74,13 @@ screenshot_osx_get_capabilities (void)
|
|||
}
|
||||
|
||||
GimpPDBStatusType
|
||||
screenshot_osx_shoot (ScreenshotValues *shootvals,
|
||||
GdkScreen *screen,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
screenshot_osx_shoot (ShootType shoot_type,
|
||||
guint select_delay,
|
||||
guint screenshot_delay,
|
||||
gboolean decorate,
|
||||
gboolean show_cursor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *mode = " ";
|
||||
const gchar *cursor = " ";
|
||||
|
@ -86,30 +89,30 @@ screenshot_osx_shoot (ScreenshotValues *shootvals,
|
|||
gchar *quoted;
|
||||
gchar *command = NULL;
|
||||
|
||||
switch (shootvals->shoot_type)
|
||||
switch (shoot_type)
|
||||
{
|
||||
case SHOOT_REGION:
|
||||
if (shootvals->select_delay > 0)
|
||||
screenshot_delay (shootvals->select_delay);
|
||||
if (select_delay > 0)
|
||||
screenshot_wait_delay (select_delay);
|
||||
|
||||
mode = "-is";
|
||||
break;
|
||||
|
||||
case SHOOT_WINDOW:
|
||||
if (shootvals->select_delay > 0)
|
||||
screenshot_delay (shootvals->select_delay);
|
||||
if (select_delay > 0)
|
||||
screenshot_wait_delay (select_delay);
|
||||
|
||||
if (shootvals->decorate)
|
||||
if (decorate)
|
||||
mode = "-iwo";
|
||||
else
|
||||
mode = "-iw";
|
||||
if (shootvals->show_cursor)
|
||||
if (show_cursor)
|
||||
cursor = "-C";
|
||||
break;
|
||||
|
||||
case SHOOT_ROOT:
|
||||
mode = " ";
|
||||
if (shootvals->show_cursor)
|
||||
if (show_cursor)
|
||||
cursor = "-C";
|
||||
break;
|
||||
|
||||
|
@ -118,7 +121,7 @@ screenshot_osx_shoot (ScreenshotValues *shootvals,
|
|||
break;
|
||||
}
|
||||
|
||||
delay = g_strdup_printf ("-T %i", shootvals->screenshot_delay);
|
||||
delay = g_strdup_printf ("-T %i", screenshot_delay);
|
||||
|
||||
tmpfile = gimp_temp_file ("png");
|
||||
quoted = g_shell_quote (g_file_peek_path (tmpfile));
|
||||
|
|
|
@ -25,10 +25,13 @@ gboolean screenshot_osx_available (void);
|
|||
|
||||
ScreenshotCapabilities screenshot_osx_get_capabilities (void);
|
||||
|
||||
GimpPDBStatusType screenshot_osx_shoot (ScreenshotValues *shootvals,
|
||||
GdkScreen *screen,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
GimpPDBStatusType screenshot_osx_shoot (ShootType shoot_type,
|
||||
guint select_delay,
|
||||
guint screenshot_delay,
|
||||
gboolean decorate,
|
||||
gboolean show_cursor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
|
||||
#endif /* PLATFORM_OSX */
|
||||
|
||||
|
|
|
@ -164,33 +164,35 @@ screenshot_win32_get_capabilities (void)
|
|||
}
|
||||
|
||||
GimpPDBStatusType
|
||||
screenshot_win32_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **_image,
|
||||
GError **error)
|
||||
screenshot_win32_shoot (ShootType shoot_type,
|
||||
guint screenshot_delay,
|
||||
gboolean show_cursor,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **_image,
|
||||
GError **error)
|
||||
{
|
||||
GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR;
|
||||
|
||||
/* leave "shootvals->monitor" alone until somebody patches the code
|
||||
/* leave "monitor" alone until somebody patches the code
|
||||
* to be able to get a monitor's color profile
|
||||
*/
|
||||
|
||||
image = _image;
|
||||
|
||||
winsnapvals.delay = shootvals->screenshot_delay;
|
||||
capturePointer = shootvals->show_cursor;
|
||||
winsnapvals.delay = screenshot_delay;
|
||||
capturePointer = show_cursor;
|
||||
|
||||
if (shootvals->shoot_type == SHOOT_ROOT)
|
||||
if (shoot_type == SHOOT_ROOT)
|
||||
{
|
||||
doCapture (0);
|
||||
|
||||
status = GIMP_PDB_SUCCESS;
|
||||
}
|
||||
else if (shootvals->shoot_type == SHOOT_WINDOW)
|
||||
else if (shoot_type == SHOOT_WINDOW)
|
||||
{
|
||||
status = 0 == doWindowCapture () ? GIMP_PDB_CANCEL : GIMP_PDB_SUCCESS;
|
||||
}
|
||||
else if (shootvals->shoot_type == SHOOT_REGION)
|
||||
else if (shoot_type == SHOOT_REGION)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
|
|
@ -33,10 +33,12 @@ gboolean screenshot_win32_available (void);
|
|||
|
||||
ScreenshotCapabilities screenshot_win32_get_capabilities (void);
|
||||
|
||||
GimpPDBStatusType screenshot_win32_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
GimpPDBStatusType screenshot_win32_shoot (ShootType shoot_type,
|
||||
guint screenshot_delay,
|
||||
gboolean show_cursor,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "libgimp/stdplugins-intl.h"
|
||||
|
||||
|
||||
static guint32 select_window (ScreenshotValues *shootvals,
|
||||
static guint32 select_window (GimpProcedureConfig *config,
|
||||
GdkMonitor *monitor);
|
||||
static GimpImage * create_image (cairo_surface_t *surface,
|
||||
cairo_region_t *shape,
|
||||
|
@ -58,8 +58,8 @@ static GimpImage * create_image (cairo_surface_t *surface,
|
|||
/* Allow the user to select a window or a region with the mouse */
|
||||
|
||||
static guint32
|
||||
select_window (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor)
|
||||
select_window (GimpProcedureConfig *config,
|
||||
GdkMonitor *monitor)
|
||||
{
|
||||
Display *x_dpy = GDK_DISPLAY_XDISPLAY (gdk_monitor_get_display (monitor));
|
||||
gint x_scr = 0;
|
||||
|
@ -76,7 +76,21 @@ select_window (ScreenshotValues *shootvals,
|
|||
gint mask = ButtonPressMask | ButtonReleaseMask;
|
||||
gboolean cancel = FALSE;
|
||||
|
||||
if (shootvals->shoot_type == SHOOT_REGION)
|
||||
ShootType shoot_type;
|
||||
guint screenshot_delay;
|
||||
gboolean decorate;
|
||||
gint x1 = 0;
|
||||
gint y1 = 0;
|
||||
gint x2 = 0;
|
||||
gint y2 = 0;
|
||||
|
||||
g_object_get (config,
|
||||
"shoot-type", &shoot_type,
|
||||
"screenshot-delay", &screenshot_delay,
|
||||
"include-decoration", &decorate,
|
||||
NULL);
|
||||
|
||||
if (shoot_type == SHOOT_REGION)
|
||||
mask |= PointerMotionMask;
|
||||
|
||||
status = XGrabPointer (x_dpy, x_root, False,
|
||||
|
@ -95,7 +109,7 @@ select_window (ScreenshotValues *shootvals,
|
|||
g_message (_("Error selecting the window"));
|
||||
}
|
||||
|
||||
if (shootvals->shoot_type == SHOOT_REGION)
|
||||
if (shoot_type == SHOOT_REGION)
|
||||
{
|
||||
XGCValues gc_values;
|
||||
|
||||
|
@ -176,12 +190,12 @@ select_window (ScreenshotValues *shootvals,
|
|||
if (x_win == None)
|
||||
x_win = x_root;
|
||||
#ifdef HAVE_X11_XMU_WINUTIL_H
|
||||
else if (! shootvals->decorate)
|
||||
else if (! decorate)
|
||||
x_win = XmuClientWindow (x_dpy, x_win);
|
||||
#endif
|
||||
|
||||
shootvals->x2 = shootvals->x1 = x_event.xbutton.x_root;
|
||||
shootvals->y2 = shootvals->y1 = x_event.xbutton.y_root;
|
||||
x2 = x1 = x_event.xbutton.x_root;
|
||||
y2 = y1 = x_event.xbutton.y_root;
|
||||
}
|
||||
|
||||
buttons++;
|
||||
|
@ -191,39 +205,39 @@ select_window (ScreenshotValues *shootvals,
|
|||
if (buttons > 0)
|
||||
buttons--;
|
||||
|
||||
if (! buttons && shootvals->shoot_type == SHOOT_REGION)
|
||||
if (! buttons && shoot_type == SHOOT_REGION)
|
||||
{
|
||||
x = MIN (shootvals->x1, shootvals->x2);
|
||||
y = MIN (shootvals->y1, shootvals->y2);
|
||||
w = ABS (shootvals->x2 - shootvals->x1);
|
||||
h = ABS (shootvals->y2 - shootvals->y1);
|
||||
x = MIN (x1, x2);
|
||||
y = MIN (y1, y2);
|
||||
w = ABS (x2 - x1);
|
||||
h = ABS (y2 - y1);
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);
|
||||
|
||||
shootvals->x2 = x_event.xbutton.x_root;
|
||||
shootvals->y2 = x_event.xbutton.y_root;
|
||||
x2 = x_event.xbutton.x_root;
|
||||
y2 = x_event.xbutton.y_root;
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
if (buttons > 0)
|
||||
{
|
||||
x = MIN (shootvals->x1, shootvals->x2);
|
||||
y = MIN (shootvals->y1, shootvals->y2);
|
||||
w = ABS (shootvals->x2 - shootvals->x1);
|
||||
h = ABS (shootvals->y2 - shootvals->y1);
|
||||
x = MIN (x1, x2);
|
||||
y = MIN (y1, y2);
|
||||
w = ABS (x2 - x1);
|
||||
h = ABS (y2 - y1);
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);
|
||||
|
||||
shootvals->x2 = x_event.xmotion.x_root;
|
||||
shootvals->y2 = x_event.xmotion.y_root;
|
||||
x2 = x_event.xmotion.x_root;
|
||||
y2 = x_event.xmotion.y_root;
|
||||
|
||||
x = MIN (shootvals->x1, shootvals->x2);
|
||||
y = MIN (shootvals->y1, shootvals->y2);
|
||||
w = ABS (shootvals->x2 - shootvals->x1);
|
||||
h = ABS (shootvals->y2 - shootvals->y1);
|
||||
x = MIN (x1, x2);
|
||||
y = MIN (y1, y2);
|
||||
w = ABS (x2 - x1);
|
||||
h = ABS (y2 - y1);
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h);
|
||||
|
@ -283,6 +297,8 @@ select_window (ScreenshotValues *shootvals,
|
|||
if (x_gc != NULL)
|
||||
XFreeGC (x_dpy, x_gc);
|
||||
|
||||
g_object_set (config, "x1", x1, "x2", x2, "y1", y1, "y2", y2, NULL);
|
||||
|
||||
return x_win;
|
||||
}
|
||||
|
||||
|
@ -556,10 +572,10 @@ screenshot_x11_get_capabilities (void)
|
|||
}
|
||||
|
||||
GimpPDBStatusType
|
||||
screenshot_x11_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
screenshot_x11_shoot (GimpProcedureConfig *config,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
|
@ -573,33 +589,55 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
|
|||
gchar *name = NULL;
|
||||
gint x, y;
|
||||
|
||||
ShootType shoot_type;
|
||||
guint screenshot_delay;
|
||||
guint select_delay;
|
||||
gboolean show_cursor;
|
||||
guint window_id = 0;
|
||||
|
||||
g_object_get (config,
|
||||
"shoot-type", &shoot_type,
|
||||
"screenshot-delay", &screenshot_delay,
|
||||
"selection-delay", &select_delay,
|
||||
"include-pointer", &show_cursor,
|
||||
NULL);
|
||||
|
||||
/* use default screen if we are running non-interactively */
|
||||
if (monitor == NULL)
|
||||
monitor = gdk_display_get_monitor (gdk_display_get_default (), 0);
|
||||
|
||||
if (shootvals->shoot_type != SHOOT_ROOT && ! shootvals->window_id)
|
||||
if (shoot_type != SHOOT_ROOT)
|
||||
{
|
||||
if (shootvals->select_delay > 0)
|
||||
screenshot_delay (shootvals->select_delay);
|
||||
if (select_delay > 0)
|
||||
screenshot_wait_delay (select_delay);
|
||||
|
||||
shootvals->window_id = select_window (shootvals, monitor);
|
||||
window_id = select_window (config, monitor);
|
||||
|
||||
if (! shootvals->window_id)
|
||||
if (! window_id)
|
||||
return GIMP_PDB_CANCEL;
|
||||
}
|
||||
|
||||
if (shootvals->screenshot_delay > 0)
|
||||
screenshot_delay (shootvals->screenshot_delay);
|
||||
if (screenshot_delay > 0)
|
||||
screenshot_wait_delay (screenshot_delay);
|
||||
|
||||
display = gdk_monitor_get_display (monitor);
|
||||
screen = gdk_display_get_default_screen (display);
|
||||
|
||||
if (shootvals->shoot_type == SHOOT_REGION)
|
||||
if (shoot_type == SHOOT_REGION)
|
||||
{
|
||||
rect.x = MIN (shootvals->x1, shootvals->x2);
|
||||
rect.y = MIN (shootvals->y1, shootvals->y2);
|
||||
rect.width = ABS (shootvals->x2 - shootvals->x1);
|
||||
rect.height = ABS (shootvals->y2 - shootvals->y1);
|
||||
gint x1;
|
||||
gint y1;
|
||||
gint x2;
|
||||
gint y2;
|
||||
|
||||
g_object_get (config,
|
||||
"x1", &x1, "y1", &y1,
|
||||
"x2", &x2, "y2", &y2,
|
||||
NULL);
|
||||
rect.x = MIN (x1, x2);
|
||||
rect.y = MIN (y1, y2);
|
||||
rect.width = ABS (x2 - x1);
|
||||
rect.height = ABS (y2 - y1);
|
||||
|
||||
monitor = gdk_display_get_monitor_at_point (display,
|
||||
rect.x + rect.width / 2,
|
||||
|
@ -607,7 +645,7 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (shootvals->shoot_type == SHOOT_ROOT)
|
||||
if (shoot_type == SHOOT_ROOT)
|
||||
{
|
||||
window = gdk_screen_get_root_window (screen);
|
||||
|
||||
|
@ -615,9 +653,7 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
|
|||
}
|
||||
else
|
||||
{
|
||||
window = gdk_x11_window_foreign_new_for_display (display,
|
||||
shootvals->window_id);
|
||||
|
||||
window = gdk_x11_window_foreign_new_for_display (display, window_id);
|
||||
monitor = gdk_display_get_monitor_at_window (display, window);
|
||||
}
|
||||
|
||||
|
@ -658,11 +694,11 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
|
|||
|
||||
gdk_display_beep (display);
|
||||
|
||||
if (shootvals->shoot_type == SHOOT_WINDOW)
|
||||
if (shoot_type == SHOOT_WINDOW)
|
||||
{
|
||||
name = window_get_title (display, shootvals->window_id);
|
||||
name = window_get_title (display, window_id);
|
||||
|
||||
shape = window_get_shape (monitor, shootvals->window_id);
|
||||
shape = window_get_shape (monitor, window_id);
|
||||
|
||||
if (shape)
|
||||
cairo_region_translate (shape, x - rect.x, y - rect.y);
|
||||
|
@ -680,8 +716,7 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
|
|||
/* FIXME: Some time might have passed until we get here.
|
||||
* The cursor image should be grabbed together with the screenshot.
|
||||
*/
|
||||
if ((shootvals->shoot_type == SHOOT_ROOT ||
|
||||
shootvals->shoot_type == SHOOT_WINDOW) && shootvals->show_cursor)
|
||||
if ((shoot_type == SHOOT_ROOT || shoot_type == SHOOT_WINDOW) && show_cursor)
|
||||
add_cursor_image (*image, display);
|
||||
|
||||
profile = gimp_monitor_get_color_profile (monitor);
|
||||
|
|
|
@ -25,10 +25,10 @@ gboolean screenshot_x11_available (void);
|
|||
|
||||
ScreenshotCapabilities screenshot_x11_get_capabilities (void);
|
||||
|
||||
GimpPDBStatusType screenshot_x11_shoot (ScreenshotValues *shootvals,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
GimpPDBStatusType screenshot_x11_shoot (GimpProcedureConfig *config,
|
||||
GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
|
||||
#endif /* GDK_WINDOWING_X11 */
|
||||
|
||||
|
|
|
@ -64,16 +64,19 @@ static GimpProcedure * screenshot_create_procedure (GimpPlugIn *plug_
|
|||
const gchar *name);
|
||||
|
||||
static GimpValueArray * screenshot_run (GimpProcedure *procedure,
|
||||
const GimpValueArray *args,
|
||||
GimpProcedureConfig *config,
|
||||
gpointer run_data);
|
||||
|
||||
static GimpPDBStatusType shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error);
|
||||
static GimpPDBStatusType shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GimpProcedureConfig *config,
|
||||
GError **error);
|
||||
|
||||
static gboolean shoot_dialog (GdkMonitor **monitor);
|
||||
static gboolean shoot_quit_timeout (gpointer data);
|
||||
static gboolean shoot_delay_timeout (gpointer data);
|
||||
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)
|
||||
|
@ -82,26 +85,8 @@ GIMP_MAIN (SCREENSHOT_TYPE)
|
|||
DEFINE_STD_SET_I18N
|
||||
|
||||
|
||||
static ScreenshotBackend backend = SCREENSHOT_BACKEND_NONE;
|
||||
static ScreenshotCapabilities capabilities = 0;
|
||||
static GtkWidget *select_delay_grid = NULL;
|
||||
static GtkWidget *shot_delay_grid = NULL;
|
||||
|
||||
static ScreenshotValues shootvals =
|
||||
{
|
||||
SHOOT_WINDOW, /* root window */
|
||||
TRUE, /* include WM decorations */
|
||||
0, /* window ID */
|
||||
0, /* select delay */
|
||||
0, /* screenshot delay */
|
||||
0, /* coords of region dragged out by pointer */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FALSE, /* show cursor */
|
||||
SCREENSHOT_PROFILE_POLICY_MONITOR
|
||||
};
|
||||
|
||||
static ScreenshotBackend backend = SCREENSHOT_BACKEND_NONE;
|
||||
static ScreenshotCapabilities capabilities = 0;
|
||||
|
||||
static void
|
||||
screenshot_class_init (ScreenshotClass *klass)
|
||||
|
@ -126,15 +111,15 @@ screenshot_query_procedures (GimpPlugIn *plug_in)
|
|||
|
||||
static GimpProcedure *
|
||||
screenshot_create_procedure (GimpPlugIn *plug_in,
|
||||
const gchar *name)
|
||||
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);
|
||||
procedure = gimp_procedure_new2 (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");
|
||||
|
@ -176,10 +161,10 @@ screenshot_create_procedure (GimpPlugIn *plug_in,
|
|||
G_PARAM_READWRITE);
|
||||
|
||||
GIMP_PROC_ARG_INT (procedure, "shoot-type",
|
||||
"Shoot type",
|
||||
_("Shoot _area"),
|
||||
"The shoot type { SHOOT-WINDOW (0), SHOOT-ROOT (1), "
|
||||
"SHOOT-REGION (2) }",
|
||||
0, 2, 0,
|
||||
0, 2, SHOOT_WINDOW,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
GIMP_PROC_ARG_INT (procedure, "x1",
|
||||
|
@ -206,6 +191,42 @@ screenshot_create_procedure (GimpPlugIn *plug_in,
|
|||
G_MININT, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
GIMP_PROC_ARG_BOOLEAN (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_PROC_AUX_ARG_BOOLEAN (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_PROC_AUX_ARG_INT (procedure, "selection-delay",
|
||||
"Selection d_elay",
|
||||
"Delay before selection of the window or the region",
|
||||
0, 20, 0,
|
||||
G_PARAM_READWRITE);
|
||||
GIMP_PROC_AUX_ARG_INT (procedure, "screenshot-delay",
|
||||
"Screenshot dela_y",
|
||||
"Delay before snapping the screenshot",
|
||||
0, 20, 0,
|
||||
G_PARAM_READWRITE);
|
||||
GIMP_PROC_AUX_ARG_INT (procedure, "color-profile",
|
||||
_("Color _Profile"),
|
||||
"{ SCREENSHOT_PROFILE_POLICY_MONITOR, (0), "
|
||||
"SCREENSHOT_PROFILE_POLICY_MONITOR, (1) } ",
|
||||
0, 1, SCREENSHOT_PROFILE_POLICY_MONITOR,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
GIMP_PROC_VAL_IMAGE (procedure, "image",
|
||||
"Image",
|
||||
"Output image",
|
||||
|
@ -218,7 +239,7 @@ screenshot_create_procedure (GimpPlugIn *plug_in,
|
|||
|
||||
static GimpValueArray *
|
||||
screenshot_run (GimpProcedure *procedure,
|
||||
const GimpValueArray *args,
|
||||
GimpProcedureConfig *config,
|
||||
gpointer run_data)
|
||||
{
|
||||
GimpValueArray *return_vals;
|
||||
|
@ -228,19 +249,29 @@ screenshot_run (GimpProcedure *procedure,
|
|||
GimpImage *image = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
ShootType shoot_type;
|
||||
ScreenshotProfilePolicy profile_policy;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
run_mode = GIMP_VALUES_GET_ENUM (args, 0);
|
||||
gimp_ui_init (PLUG_IN_BINARY);
|
||||
g_object_get (config,
|
||||
"run-mode", &run_mode,
|
||||
"shoot-type", &shoot_type,
|
||||
NULL);
|
||||
|
||||
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 ();
|
||||
|
||||
/* on OS X, this just means shoot the shadow, default to nope */
|
||||
shootvals.decorate = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -265,24 +296,36 @@ screenshot_run (GimpProcedure *procedure,
|
|||
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:
|
||||
/* Possibly retrieve data from a previous run */
|
||||
gimp_get_data (PLUG_IN_PROC, &shootvals);
|
||||
shootvals.window_id = 0;
|
||||
gimp_ui_init (PLUG_IN_BINARY);
|
||||
|
||||
if ((shootvals.shoot_type == SHOOT_WINDOW &&
|
||||
/* 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)) ||
|
||||
(shootvals.shoot_type == SHOOT_REGION &&
|
||||
(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).
|
||||
*/
|
||||
shootvals.shoot_type = SHOOT_ROOT;
|
||||
g_object_set (config, "shoot-type", SHOOT_ROOT, NULL);
|
||||
}
|
||||
|
||||
/* Get information from the dialog. Freedesktop portal comes with
|
||||
|
@ -290,7 +333,7 @@ screenshot_run (GimpProcedure *procedure,
|
|||
*/
|
||||
if (backend != SCREENSHOT_BACKEND_FREEDESKTOP)
|
||||
{
|
||||
if (! shoot_dialog (&monitor))
|
||||
if (! shoot_dialog (procedure, config, &monitor))
|
||||
status = GIMP_PDB_CANCEL;
|
||||
}
|
||||
else
|
||||
|
@ -304,30 +347,20 @@ screenshot_run (GimpProcedure *procedure,
|
|||
break;
|
||||
|
||||
case GIMP_RUN_NONINTERACTIVE:
|
||||
shootvals.shoot_type = GIMP_VALUES_GET_INT (args, 1);
|
||||
shootvals.window_id = GIMP_VALUES_GET_INT (args, 2);
|
||||
shootvals.select_delay = 0;
|
||||
shootvals.x1 = GIMP_VALUES_GET_INT (args, 3);
|
||||
shootvals.y1 = GIMP_VALUES_GET_INT (args, 4);
|
||||
shootvals.x2 = GIMP_VALUES_GET_INT (args, 5);
|
||||
shootvals.y2 = GIMP_VALUES_GET_INT (args, 6);
|
||||
|
||||
if (! gdk_init_check (NULL, NULL))
|
||||
status = GIMP_PDB_CALLING_ERROR;
|
||||
|
||||
if (! (capabilities & SCREENSHOT_CAN_PICK_NONINTERACTIVELY))
|
||||
if (backend == SCREENSHOT_BACKEND_FREEDESKTOP)
|
||||
{
|
||||
if (shootvals.shoot_type == SHOOT_WINDOW ||
|
||||
shootvals.shoot_type == SHOOT_REGION)
|
||||
{
|
||||
status = GIMP_PDB_CALLING_ERROR;
|
||||
}
|
||||
/* 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:
|
||||
/* Possibly retrieve data from a previous run */
|
||||
gimp_get_data (PLUG_IN_PROC, &shootvals);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -335,9 +368,7 @@ screenshot_run (GimpProcedure *procedure,
|
|||
}
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
status = shoot (monitor, &image, &error);
|
||||
}
|
||||
status = shoot (monitor, &image, config, &error);
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
|
@ -345,7 +376,14 @@ screenshot_run (GimpProcedure *procedure,
|
|||
|
||||
gimp_image_undo_disable (image);
|
||||
|
||||
if (shootvals.profile_policy == SCREENSHOT_PROFILE_POLICY_SRGB)
|
||||
g_object_get (config,
|
||||
"color-profile", &profile_policy,
|
||||
NULL);
|
||||
|
||||
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 ();
|
||||
|
||||
|
@ -374,13 +412,15 @@ screenshot_run (GimpProcedure *procedure,
|
|||
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||
{
|
||||
/* Store variable states for next run */
|
||||
gimp_set_data (PLUG_IN_PROC, &shootvals, sizeof (ScreenshotValues));
|
||||
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 (shootvals.select_delay > 0)
|
||||
if (select_delay > 0)
|
||||
{
|
||||
gdk_display_beep (gdk_monitor_get_display (monitor));
|
||||
/* flush so the beep makes it to the server */
|
||||
|
@ -401,26 +441,45 @@ screenshot_run (GimpProcedure *procedure,
|
|||
/* The main Screenshot function */
|
||||
|
||||
static GimpPDBStatusType
|
||||
shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GError **error)
|
||||
shoot (GdkMonitor *monitor,
|
||||
GimpImage **image,
|
||||
GimpProcedureConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
ShootType shoot_type;
|
||||
gboolean decorate;
|
||||
guint select_delay;
|
||||
guint screenshot_delay;
|
||||
gboolean show_cursor;
|
||||
|
||||
g_object_get (config,
|
||||
"shoot-type", &shoot_type,
|
||||
"screenshot-delay", &screenshot_delay,
|
||||
"selection-delay", &select_delay,
|
||||
"include-decoration", &decorate,
|
||||
"include-pointer", &show_cursor,
|
||||
NULL);
|
||||
|
||||
#ifdef PLATFORM_OSX
|
||||
if (backend == SCREENSHOT_BACKEND_OSX)
|
||||
return screenshot_osx_shoot (&shootvals, monitor, image, error);
|
||||
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 (&shootvals, monitor, image, error);
|
||||
return screenshot_win32_shoot (shoot_type, screenshot_delay, show_cursor,
|
||||
monitor, image, error);
|
||||
#endif
|
||||
|
||||
if (backend == SCREENSHOT_BACKEND_FREEDESKTOP)
|
||||
return screenshot_freedesktop_shoot (&shootvals, monitor, image, error);
|
||||
return screenshot_freedesktop_shoot (monitor, image, error);
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (backend == SCREENSHOT_BACKEND_X11)
|
||||
return screenshot_x11_shoot (&shootvals, monitor, image, error);
|
||||
return screenshot_x11_shoot (config, monitor, image, error);
|
||||
#endif
|
||||
|
||||
return GIMP_PDB_CALLING_ERROR; /* silence compiler */
|
||||
|
@ -429,416 +488,133 @@ shoot (GdkMonitor *monitor,
|
|||
|
||||
/* Screenshot dialog */
|
||||
|
||||
static void
|
||||
shoot_dialog_add_hint (GtkNotebook *notebook,
|
||||
ShootType type,
|
||||
const gchar *hint)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = g_object_new (GTK_TYPE_LABEL,
|
||||
"label", hint,
|
||||
"wrap", TRUE,
|
||||
"justify", GTK_JUSTIFY_LEFT,
|
||||
"xalign", 0.0,
|
||||
"yalign", 0.0,
|
||||
NULL);
|
||||
gimp_label_set_attributes (GTK_LABEL (label),
|
||||
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
|
||||
-1);
|
||||
|
||||
gtk_notebook_insert_page (notebook, label, NULL, type);
|
||||
gtk_widget_show (label);
|
||||
}
|
||||
|
||||
static void
|
||||
shoot_radio_button_toggled (GtkWidget *widget,
|
||||
GtkWidget *notebook)
|
||||
{
|
||||
gimp_radio_button_update (widget, &shootvals.shoot_type);
|
||||
|
||||
if (select_delay_grid)
|
||||
{
|
||||
if (shootvals.shoot_type == SHOOT_ROOT ||
|
||||
(shootvals.shoot_type == SHOOT_WINDOW &&
|
||||
! (capabilities & SCREENSHOT_CAN_PICK_WINDOW)))
|
||||
{
|
||||
gtk_widget_hide (select_delay_grid);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_show (select_delay_grid);
|
||||
}
|
||||
}
|
||||
if (shot_delay_grid)
|
||||
{
|
||||
if (shootvals.shoot_type == SHOOT_WINDOW &&
|
||||
(capabilities & SCREENSHOT_CAN_PICK_WINDOW) &&
|
||||
! (capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT))
|
||||
{
|
||||
gtk_widget_hide (shot_delay_grid);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_show (shot_delay_grid);
|
||||
}
|
||||
}
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), shootvals.shoot_type);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shoot_dialog (GdkMonitor **monitor)
|
||||
shoot_dialog (GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GdkMonitor **monitor)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *notebook1;
|
||||
GtkWidget *notebook2;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
GtkWidget *toggle;
|
||||
GtkWidget *spinner;
|
||||
GtkWidget *grid;
|
||||
GSList *radio_group = NULL;
|
||||
GtkAdjustment *adj;
|
||||
gboolean run;
|
||||
GtkWidget *cursor_toggle = NULL;
|
||||
GtkWidget *dialog;
|
||||
GtkListStore *store;
|
||||
GimpValueArray *values;
|
||||
GValue value = G_VALUE_INIT;
|
||||
gboolean run;
|
||||
|
||||
dialog = gimp_dialog_new (_("Screenshot"), PLUG_IN_ROLE,
|
||||
NULL, 0,
|
||||
gimp_standard_help_func, PLUG_IN_PROC,
|
||||
dialog = gimp_procedure_dialog_new (procedure,
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
_("Screenshot"));
|
||||
gimp_procedure_dialog_set_ok_label (GIMP_PROCEDURE_DIALOG (dialog), _("S_nap"));
|
||||
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("S_nap"), GTK_RESPONSE_OK,
|
||||
store = gimp_int_store_new (_("Take a screenshot of a single window"), SHOOT_WINDOW,
|
||||
_("Take a screenshot of the entire screen"), SHOOT_ROOT,
|
||||
_("Select a region to grab"), SHOOT_REGION,
|
||||
NULL);
|
||||
gimp_procedure_dialog_get_int_combo (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"shoot-type", GIMP_INT_STORE (store));
|
||||
|
||||
NULL);
|
||||
|
||||
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
||||
GTK_RESPONSE_OK,
|
||||
GTK_RESPONSE_CANCEL,
|
||||
-1);
|
||||
|
||||
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
||||
main_vbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (main_vbox);
|
||||
|
||||
|
||||
/* Create delay hints notebooks early */
|
||||
notebook1 = g_object_new (GTK_TYPE_NOTEBOOK,
|
||||
"show-border", FALSE,
|
||||
"show-tabs", FALSE,
|
||||
NULL);
|
||||
notebook2 = g_object_new (GTK_TYPE_NOTEBOOK,
|
||||
"show-border", FALSE,
|
||||
"show-tabs", FALSE,
|
||||
NULL);
|
||||
|
||||
/* Area */
|
||||
frame = gimp_frame_new (_("Area"));
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
/* Single window */
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_WINDOW)
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_POINTER ||
|
||||
capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS)
|
||||
{
|
||||
button = gtk_radio_button_new_with_mnemonic (radio_group,
|
||||
_("Take a screenshot of "
|
||||
"a single _window"));
|
||||
radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_show (button);
|
||||
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);
|
||||
|
||||
g_object_set_data (G_OBJECT (button), "gimp-item-data",
|
||||
GINT_TO_POINTER (SHOOT_WINDOW));
|
||||
gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"contents-frame-title",
|
||||
_("Contents"));
|
||||
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"contents-frame", "contents-frame-title",
|
||||
FALSE, "contents-box");
|
||||
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook1);
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook2);
|
||||
|
||||
/* Window decorations */
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
toggle = gtk_check_button_new_with_mnemonic (_("Include window _decoration"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
|
||||
shootvals.decorate);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, TRUE, 24);
|
||||
gtk_widget_show (toggle);
|
||||
|
||||
g_signal_connect (toggle, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
&shootvals.decorate);
|
||||
|
||||
g_object_bind_property (button, "active",
|
||||
toggle, "sensitive",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
values = gimp_value_array_new (1);
|
||||
g_value_init (&value, G_TYPE_INT);
|
||||
g_value_set_int (&value, SHOOT_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);
|
||||
}
|
||||
/* Mouse pointer */
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_POINTER)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
cursor_toggle = gtk_check_button_new_with_mnemonic (_("Include _mouse pointer"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cursor_toggle),
|
||||
shootvals.show_cursor);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), cursor_toggle, TRUE, TRUE, 24);
|
||||
gtk_widget_show (cursor_toggle);
|
||||
|
||||
g_signal_connect (cursor_toggle, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
&shootvals.show_cursor);
|
||||
|
||||
g_object_bind_property (button, "active",
|
||||
cursor_toggle, "sensitive",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
values = gimp_value_array_new (1);
|
||||
g_value_init (&value, G_TYPE_INT);
|
||||
g_value_set_int (&value, SHOOT_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);
|
||||
}
|
||||
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
shootvals.shoot_type == SHOOT_WINDOW);
|
||||
}
|
||||
|
||||
/* Whole screen */
|
||||
button = gtk_radio_button_new_with_mnemonic (radio_group,
|
||||
_("Take a screenshot of "
|
||||
"the entire _screen"));
|
||||
radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_show (button);
|
||||
|
||||
g_object_set_data (G_OBJECT (button), "gimp-item-data",
|
||||
GINT_TO_POINTER (SHOOT_ROOT));
|
||||
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook1);
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook2);
|
||||
|
||||
/* Mouse pointer */
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_POINTER)
|
||||
if (capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT)
|
||||
{
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
toggle = gtk_check_button_new_with_mnemonic (_("Include _mouse pointer"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
|
||||
shootvals.show_cursor);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, TRUE, 24);
|
||||
gtk_widget_show (toggle);
|
||||
|
||||
g_signal_connect (toggle, "toggled",
|
||||
G_CALLBACK (gimp_toggle_button_update),
|
||||
&shootvals.show_cursor);
|
||||
|
||||
if (cursor_toggle)
|
||||
if (capabilities & SCREENSHOT_CAN_PICK_WINDOW)
|
||||
{
|
||||
g_object_bind_property (cursor_toggle, "active",
|
||||
toggle, "active",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
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_INT);
|
||||
g_value_set_int (&value, SHOOT_ROOT);
|
||||
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);
|
||||
}
|
||||
g_object_bind_property (button, "active",
|
||||
toggle, "sensitive",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
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"));
|
||||
gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"delay-frame", "delay-frame-title",
|
||||
FALSE, "delay-box");
|
||||
}
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
shootvals.shoot_type == SHOOT_ROOT);
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "shoot-type", NULL);
|
||||
|
||||
/* Dragged region */
|
||||
if (capabilities & SCREENSHOT_CAN_SHOOT_REGION)
|
||||
{
|
||||
button = gtk_radio_button_new_with_mnemonic (radio_group,
|
||||
_("Select a _region to grab"));
|
||||
radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
shootvals.shoot_type == SHOOT_REGION);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_show (button);
|
||||
store = gimp_int_store_new (_("Tag image with monitor profile"), SCREENSHOT_PROFILE_POLICY_MONITOR,
|
||||
_("Convert image with sRGB"), SCREENSHOT_PROFILE_POLICY_SRGB,
|
||||
NULL);
|
||||
gimp_procedure_dialog_get_int_combo (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"color-profile", GIMP_INT_STORE (store));
|
||||
|
||||
g_object_set_data (G_OBJECT (button), "gimp-item-data",
|
||||
GINT_TO_POINTER (SHOOT_REGION));
|
||||
if ((capabilities & SCREENSHOT_CAN_SHOOT_POINTER) ||
|
||||
(capabilities & SCREENSHOT_CAN_SHOOT_DECORATIONS))
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "contents-frame", NULL);
|
||||
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook1);
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (shoot_radio_button_toggled),
|
||||
notebook2);
|
||||
}
|
||||
if (capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT)
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "delay-frame", NULL);
|
||||
|
||||
frame = gimp_frame_new (_("Delay"));
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
/* Selection delay */
|
||||
grid = gtk_grid_new ();
|
||||
select_delay_grid = grid;
|
||||
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
|
||||
/* Check if this delay must be hidden from start. */
|
||||
if (shootvals.shoot_type == SHOOT_REGION ||
|
||||
(shootvals.shoot_type == SHOOT_WINDOW &&
|
||||
capabilities & SCREENSHOT_CAN_PICK_WINDOW))
|
||||
{
|
||||
gtk_widget_show (select_delay_grid);
|
||||
}
|
||||
|
||||
label = gtk_label_new (_("Selection delay: "));
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
gtk_widget_show (label);
|
||||
|
||||
adj = gtk_adjustment_new (shootvals.select_delay,
|
||||
0.0, 100.0, 1.0, 5.0, 0.0);
|
||||
spinner = gimp_spin_button_new (adj, 0, 0);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), spinner, 1, 0, 1, 1);
|
||||
gtk_widget_show (spinner);
|
||||
|
||||
g_signal_connect (adj, "value-changed",
|
||||
G_CALLBACK (gimp_int_adjustment_update),
|
||||
&shootvals.select_delay);
|
||||
|
||||
/* translators: this is the unit label of a spinbutton */
|
||||
label = gtk_label_new (_("seconds"));
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_show (label);
|
||||
|
||||
/* Selection delay hints */
|
||||
gtk_grid_attach (GTK_GRID (grid), notebook1, 0, 1, 3, 1);
|
||||
gtk_widget_show (notebook1);
|
||||
|
||||
/* No selection delay for full-screen. */
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook1), SHOOT_ROOT, "");
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook1), SHOOT_REGION,
|
||||
_("After the delay, drag your mouse to select "
|
||||
"the region for the screenshot."));
|
||||
#ifdef G_OS_WIN32
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook1), SHOOT_WINDOW,
|
||||
_("Click in a window to snap it after delay."));
|
||||
#else
|
||||
if (capabilities & SCREENSHOT_CAN_PICK_WINDOW)
|
||||
{
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook1), SHOOT_WINDOW,
|
||||
_("At the end of the delay, click in a window "
|
||||
"to snap it."));
|
||||
}
|
||||
else
|
||||
{
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook1), SHOOT_WINDOW, "");
|
||||
}
|
||||
#endif
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook1), shootvals.shoot_type);
|
||||
|
||||
/* Screenshot delay */
|
||||
grid = gtk_grid_new ();
|
||||
shot_delay_grid = grid;
|
||||
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
|
||||
if (shootvals.shoot_type != SHOOT_WINDOW ||
|
||||
! (capabilities & SCREENSHOT_CAN_PICK_WINDOW) ||
|
||||
(capabilities & SCREENSHOT_CAN_DELAY_WINDOW_SHOT))
|
||||
{
|
||||
gtk_widget_show (grid);
|
||||
}
|
||||
|
||||
label = gtk_label_new_with_mnemonic (_("Screenshot dela_y: "));
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
gtk_widget_show (label);
|
||||
|
||||
adj = gtk_adjustment_new (shootvals.screenshot_delay,
|
||||
0.0, 100.0, 1.0, 5.0, 0.0);
|
||||
spinner = gimp_spin_button_new (adj, 0, 0);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), spinner, 1, 0, 1, 1);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (spinner));
|
||||
gtk_widget_show (spinner);
|
||||
|
||||
g_signal_connect (adj, "value-changed",
|
||||
G_CALLBACK (gimp_int_adjustment_update),
|
||||
&shootvals.screenshot_delay);
|
||||
|
||||
/* translators: this is the unit label of a spinbutton */
|
||||
label = gtk_label_new (_("seconds"));
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_show (label);
|
||||
|
||||
/* Screenshot delay hints */
|
||||
gtk_grid_attach (GTK_GRID (grid), notebook2, 0, 1, 3, 1);
|
||||
gtk_widget_show (notebook2);
|
||||
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook2), SHOOT_ROOT,
|
||||
_("After the delay, the screenshot is taken."));
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook2), SHOOT_REGION,
|
||||
_("Once the region is selected, it will be "
|
||||
"captured after this delay."));
|
||||
if (capabilities & SCREENSHOT_CAN_PICK_WINDOW)
|
||||
{
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook2), SHOOT_WINDOW,
|
||||
_("Once the window is selected, it will be "
|
||||
"captured after this delay."));
|
||||
}
|
||||
else
|
||||
{
|
||||
shoot_dialog_add_hint (GTK_NOTEBOOK (notebook2), SHOOT_WINDOW,
|
||||
_("After the delay, the active window "
|
||||
"will be captured."));
|
||||
}
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook2), shootvals.shoot_type);
|
||||
|
||||
/* Color profile */
|
||||
frame = gimp_int_radio_group_new (TRUE,
|
||||
_("Color Profile"),
|
||||
G_CALLBACK (gimp_radio_button_update),
|
||||
&shootvals.profile_policy, NULL,
|
||||
shootvals.profile_policy,
|
||||
|
||||
_("Tag image with _monitor profile"),
|
||||
SCREENSHOT_PROFILE_POLICY_MONITOR,
|
||||
NULL,
|
||||
|
||||
_("Convert image to sR_GB"),
|
||||
SCREENSHOT_PROFILE_POLICY_SRGB,
|
||||
NULL,
|
||||
|
||||
NULL);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
||||
|
||||
if (run)
|
||||
{
|
||||
/* get the screen on which we are running */
|
||||
*monitor = gimp_widget_get_monitor (dialog);
|
||||
}
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "color-profile", NULL);
|
||||
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
|
@ -880,7 +656,7 @@ shoot_delay_timeout (gpointer data)
|
|||
/* public functions */
|
||||
|
||||
void
|
||||
screenshot_delay (gint seconds)
|
||||
screenshot_wait_delay (gint seconds)
|
||||
{
|
||||
g_timeout_add (1000, shoot_delay_timeout, &seconds);
|
||||
gtk_main ();
|
||||
|
|
|
@ -34,7 +34,7 @@ typedef enum
|
|||
SCREENSHOT_CAN_SHOOT_POINTER = 0x1 << 1,
|
||||
SCREENSHOT_CAN_PICK_NONINTERACTIVELY = 0x1 << 2,
|
||||
SCREENSHOT_CAN_SHOOT_REGION = 0x1 << 3,
|
||||
/* SHOOT_WINDOW mode only: it window selection requires active click. */
|
||||
/* SHOOT_WINDOW mode only: if window selection requires active click. */
|
||||
SCREENSHOT_CAN_PICK_WINDOW = 0x1 << 4,
|
||||
/* SHOOT_WINDOW + SCREENSHOT_CAN_PICK_WINDOW only: if a delay can be
|
||||
* inserted in-between selection click and actual snapshot. */
|
||||
|
@ -55,24 +55,8 @@ typedef enum
|
|||
SHOOT_REGION
|
||||
} ShootType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ShootType shoot_type;
|
||||
gboolean decorate;
|
||||
guint window_id;
|
||||
GdkMonitor *monitor;
|
||||
guint select_delay;
|
||||
guint screenshot_delay;
|
||||
gint x1;
|
||||
gint y1;
|
||||
gint x2;
|
||||
gint y2;
|
||||
gboolean show_cursor;
|
||||
ScreenshotProfilePolicy profile_policy;
|
||||
} ScreenshotValues;
|
||||
|
||||
|
||||
void screenshot_delay (gint seconds);
|
||||
void screenshot_wait_delay (gint seconds);
|
||||
|
||||
|
||||
#endif /* __SCREENSHOT_H__ */
|
||||
|
|
Loading…
Reference in New Issue