made --new the default behaviour and allow gimp-remote to be called

2004-01-20  Sven Neumann  <sven@gimp.org>

	* tools/gimp-remote.c: made --new the default behaviour and allow
	gimp-remote to be called without any image filenames.

	* docs/gimp-remote-1.3.1.in: changed accordingly.

	* data/misc/gimp.applications
	* data/misc/gimp.desktop.in.in: removed --new option from
	gimp-remote calls.
This commit is contained in:
Sven Neumann 2004-01-20 12:07:26 +00:00 committed by Sven Neumann
parent 8096cef139
commit b5bf60ac6a
7 changed files with 145 additions and 139 deletions

View file

@ -1,3 +1,14 @@
2004-01-20 Sven Neumann <sven@gimp.org>
* tools/gimp-remote.c: made --new the default behaviour and allow
gimp-remote to be called without any image filenames.
* docs/gimp-remote-1.3.1.in: changed accordingly.
* data/misc/gimp.applications
* data/misc/gimp.desktop.in.in: removed --new option from
gimp-remote calls.
2004-01-20 Michael Natterer <mitch@gimp.org> 2004-01-20 Michael Natterer <mitch@gimp.org>
* plug-ins/common/mail.c * plug-ins/common/mail.c

View file

@ -1,5 +1,5 @@
gimp-1.3 gimp-1.3
command=gimp-remote-1.3 --new command=gimp-remote-1.3
name=The GIMP (unstable) name=The GIMP (unstable)
can_open_multiple_files=true can_open_multiple_files=true
expects_uris=non-file expects_uris=non-file

View file

@ -1,5 +1,5 @@
gimp-1.3 gimp-1.3
command=gimp-remote-1.3 --new command=gimp-remote-1.3
name=The GIMP (unstable) name=The GIMP (unstable)
can_open_multiple_files=true can_open_multiple_files=true
expects_uris=non-file expects_uris=non-file

View file

@ -2,8 +2,8 @@
Encoding=UTF-8 Encoding=UTF-8
_Name=The GIMP (unstable) _Name=The GIMP (unstable)
_Comment=Create and edit images or photographs _Comment=Create and edit images or photographs
Exec=gimp-remote-1.3 %U
TryExec=gimp-1.3 TryExec=gimp-1.3
Exec=gimp-remote-1.3 --new %U
Icon=@gimpdatadir@/images/wilber-icon.png Icon=@gimpdatadir@/images/wilber-icon.png
Terminal=false Terminal=false
Type=Application Type=Application

View file

@ -1,16 +1,16 @@
.TH GIMP-REMOTE 1 "31 October 2003" "Version @GIMP_VERSION@" "GIMP Manual Pages" .TH GIMP-REMOTE 1 "20 January 2004" "Version @GIMP_VERSION@" "GIMP Manual Pages"
.SH NAME .SH NAME
gimp-remote - tells a running GIMP to open a (local or remote) image file. gimp-remote - tells a running GIMP to open a (local or remote) image file.
.SH SYNOPSIS .SH SYNOPSIS
.B gimp-remote .B gimp-remote
[\-h] [\-\-help] [-v] [\-\-version] [\-\-display \fIdisplay\fP] [\-h] [\-\-help] [-v] [\-\-version] [\-\-display \fIdisplay\fP]
[\-n] [\-\-new] \fIfilename\fP... \fIfilename\fP ...
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
\fIgimp-remote\fP is a small utility that tells a running GIMP to open \fIgimp-remote\fP is a small utility that tells a running GIMP to open
a (local or remote) image file. It does so by searching for a GIMP one or more (local or remote) image files. It does so by searching for
toolbox on the active display. If it can find a GIMP toolbox, a a GIMP toolbox on the active display. If it can find a GIMP toolbox, a
synthetic drop event is created which makes GIMP think the files would synthetic drop event is created which makes GIMP think the files would
have been dropped onto the toolbox. More than one filename or URL can have been dropped onto the toolbox. More than one filename or URL can
be specified on the commandline. be specified on the commandline.
@ -27,19 +27,16 @@ Output the version info.
.TP 8 .TP 8
.B \-\-display \fIdisplay\fP .B \-\-display \fIdisplay\fP
Use the designated X display. Use the designated X display.
.TP 8
.B \-n, \-\-new
If no running GIMP is found, a new instance of GIMP is started.
The files to open are passed to the new GIMP.
.SH EXAMPLES .SH EXAMPLES
.TP .TP
.BI gimp-remote \ http://www.gimp.org/icons/frontpage-small.gif .BI gimp-remote\ http://www.gimp.org/icons/frontpage-small.gif
Loads the image from the GIMP website into a running GIMP. Loads the image from the GIMP website into a running GIMP or starts
a new one.
.TP .TP
.BI gimp-remote\ \-n \ wilber.xcf\ \ wilma.xcf .BI gimp-remote\ wilber.xcf\ wilma.xcf
Loads the local files wilber.xcf and wilma.xcf into a running GIMP. Loads the local files wilber.xcf and wilma.xcf into a running GIMP
If no GIMP is running, a new one is started. or starts a new one.
.SH ENVIRONMENT .SH ENVIRONMENT
.PP .PP

View file

@ -1,16 +1,16 @@
.TH GIMP-REMOTE 1 "31 October 2003" "Version @GIMP_VERSION@" "GIMP Manual Pages" .TH GIMP-REMOTE 1 "20 January 2004" "Version @GIMP_VERSION@" "GIMP Manual Pages"
.SH NAME .SH NAME
gimp-remote - tells a running GIMP to open a (local or remote) image file. gimp-remote - tells a running GIMP to open a (local or remote) image file.
.SH SYNOPSIS .SH SYNOPSIS
.B gimp-remote .B gimp-remote
[\-h] [\-\-help] [-v] [\-\-version] [\-\-display \fIdisplay\fP] [\-h] [\-\-help] [-v] [\-\-version] [\-\-display \fIdisplay\fP]
[\-n] [\-\-new] \fIfilename\fP... \fIfilename\fP ...
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
\fIgimp-remote\fP is a small utility that tells a running GIMP to open \fIgimp-remote\fP is a small utility that tells a running GIMP to open
a (local or remote) image file. It does so by searching for a GIMP one or more (local or remote) image files. It does so by searching for
toolbox on the active display. If it can find a GIMP toolbox, a a GIMP toolbox on the active display. If it can find a GIMP toolbox, a
synthetic drop event is created which makes GIMP think the files would synthetic drop event is created which makes GIMP think the files would
have been dropped onto the toolbox. More than one filename or URL can have been dropped onto the toolbox. More than one filename or URL can
be specified on the commandline. be specified on the commandline.
@ -27,19 +27,16 @@ Output the version info.
.TP 8 .TP 8
.B \-\-display \fIdisplay\fP .B \-\-display \fIdisplay\fP
Use the designated X display. Use the designated X display.
.TP 8
.B \-n, \-\-new
If no running GIMP is found, a new instance of GIMP is started.
The files to open are passed to the new GIMP.
.SH EXAMPLES .SH EXAMPLES
.TP .TP
.BI gimp-remote \ http://www.gimp.org/icons/frontpage-small.gif .BI gimp-remote\ http://www.gimp.org/icons/frontpage-small.gif
Loads the image from the GIMP website into a running GIMP. Loads the image from the GIMP website into a running GIMP or starts
a new one.
.TP .TP
.BI gimp-remote\ \-n \ wilber.xcf\ \ wilma.xcf .BI gimp-remote\ wilber.xcf\ wilma.xcf
Loads the local files wilber.xcf and wilma.xcf into a running GIMP. Loads the local files wilber.xcf and wilma.xcf into a running GIMP
If no GIMP is running, a new one is started. or starts a new one.
.SH ENVIRONMENT .SH ENVIRONMENT
.PP .PP

View file

@ -2,14 +2,11 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis * Copyright (C) 1995 Spencer Kimball and Peter Mattis
* *
* gimp-remote.c * gimp-remote.c
* Copyright (C) 2000-2003 Sven Neumann <sven@gimp.org> * Copyright (C) 2000-2004 Sven Neumann <sven@gimp.org>
* Simon Budig <simon@gimp.org> * Simon Budig <simon@gimp.org>
* *
* Tells a running gimp to open files by creating a synthetic drop-event. * Tells a running gimp to open files by creating a synthetic drop-event.
* *
* compile with
* gcc -o gimp-remote `pkg-config --cflags --libs gtk+-2.0` -lXmu gimp-remote.c
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -38,7 +35,6 @@
* Simon * Simon
*/ */
#include "config.h" #include "config.h"
#include <errno.h> #include <errno.h>
@ -54,7 +50,7 @@
#include "libgimpbase/gimpversion.h" #include "libgimpbase/gimpversion.h"
static gboolean start_new = FALSE; #define GIMP_BINARY "gimp-1.3"
static GdkWindow * static GdkWindow *
@ -137,10 +133,8 @@ source_selection_get (GtkWidget *widget,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint info, guint info,
guint time, guint time,
gpointer data) const gchar *uri)
{ {
gchar *uri = (gchar *) data;
gtk_selection_data_set (selection_data, gtk_selection_data_set (selection_data,
selection_data->target, selection_data->target,
8, uri, strlen (uri)); 8, uri, strlen (uri));
@ -165,7 +159,6 @@ usage (const gchar *name)
"Usage: %s [options] [FILE|URI]...\n\n", name); "Usage: %s [options] [FILE|URI]...\n\n", name);
g_print ("Valid options are:\n" g_print ("Valid options are:\n"
" --display <display> Use the designated X display.\n" " --display <display> Use the designated X display.\n"
" -n --new Start gimp if no active gimp window was found.\n"
" -h --help Output this help.\n" " -h --help Output this help.\n"
" -v --version Output version info.\n" " -v --version Output version info.\n"
"\n"); "\n");
@ -182,9 +175,12 @@ start_new_gimp (gchar *argv0,
gchar *gimp, *path, *name, *pwd; gchar *gimp, *path, *name, *pwd;
const gchar *spath; const gchar *spath;
file_list = g_string_prepend (file_list, "gimp\n"); if (file_list->len > 0)
file_list = g_string_prepend (file_list, "\n");
file_list = g_string_prepend (file_list, "gimp");
argv = g_strsplit (file_list->str, "\n", 0); argv = g_strsplit (file_list->str, "\n", 0);
g_string_free (file_list, TRUE);
/* We are searching for the path the gimp-remote executable lives in */ /* We are searching for the path the gimp-remote executable lives in */
@ -194,15 +190,19 @@ start_new_gimp (gchar *argv0,
* usable in it try argv[0], then fall back to search the path. * usable in it try argv[0], then fall back to search the path.
*/ */
gimp = NULL; gimp = NULL;
spath = NULL; spath = NULL;
for (i=0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (i == 0) if (i == 0)
spath = g_getenv ("_"); {
spath = g_getenv ("_");
}
else if (i == 1) else if (i == 1)
spath = argv0; {
spath = argv0;
}
if (spath) if (spath)
{ {
@ -210,22 +210,20 @@ start_new_gimp (gchar *argv0,
if (!strncmp (name, "gimp-remote", 11)) if (!strncmp (name, "gimp-remote", 11))
{ {
path = g_path_get_dirname (spath);
if (g_path_is_absolute (spath)) if (g_path_is_absolute (spath))
{ {
path = g_path_get_dirname (spath); gimp = g_build_filename (path, GIMP_BINARY, NULL);
gimp = g_strconcat (path, G_DIR_SEPARATOR_S,
"gimp-1.3", NULL);
g_free (path);
} }
else else
{ {
pwd = g_get_current_dir (); pwd = g_get_current_dir ();
path = g_path_get_dirname (spath); gimp = g_build_filename (pwd, path, GIMP_BINARY, NULL);
gimp = g_strconcat (pwd, G_DIR_SEPARATOR_S, path,
G_DIR_SEPARATOR_S, "gimp-1.3", NULL);
g_free (path);
g_free (pwd); g_free (pwd);
} }
g_free (path);
} }
g_free (name); g_free (name);
@ -235,19 +233,13 @@ start_new_gimp (gchar *argv0,
break; break;
} }
for (i = 1; argv[i]; i++)
{
if (g_ascii_strncasecmp ("file:", argv[i], 5) == 0)
argv[i] += 5;
}
execv (gimp, argv); execv (gimp, argv);
execvp ("gimp-1.3", argv); execvp (GIMP_BINARY, argv);
/* if execv and execvp return, there was an arror */ /* if execv and execvp return, there was an arror */
g_printerr ("Couldn't start gimp-1.3 for the following reason: %s\n", g_printerr ("Couldn't start %s for the following reason: %s\n",
g_strerror (errno)); GIMP_BINARY, g_strerror (errno));
exit (-1); exit (EXIT_FAILURE);
} }
static void static void
@ -258,7 +250,7 @@ parse_option (const gchar *progname,
strcmp (arg, "--version") == 0) strcmp (arg, "--version") == 0)
{ {
g_print ("gimp-remote version %s\n", GIMP_VERSION); g_print ("gimp-remote version %s\n", GIMP_VERSION);
exit (0); exit (EXIT_SUCCESS);
} }
else if (strcmp (arg, "-h") == 0 || else if (strcmp (arg, "-h") == 0 ||
strcmp (arg, "-?") == 0 || strcmp (arg, "-?") == 0 ||
@ -266,18 +258,20 @@ parse_option (const gchar *progname,
strcmp (arg, "--usage") == 0) strcmp (arg, "--usage") == 0)
{ {
usage (progname); usage (progname);
exit (0); exit (EXIT_SUCCESS);
} }
else if (strcmp (arg, "-n") == 0 || else if (strcmp (arg, "-n") == 0 ||
strcmp (arg, "--new") == 0) strcmp (arg, "--new") == 0)
{ {
start_new = TRUE; /* accepted for backward compatibility; this is now the default */
} }
else else
{ {
g_print ("Unknown option %s\n", arg); g_printerr ("Unknown option %s\n", arg);
g_print ("Try gimp-remote --help to get detailed usage instructions.\n"); g_printerr ("Try %s --help to get detailed usage instructions.\n",
exit (0); progname);
exit (EXIT_FAILURE);
} }
} }
@ -285,28 +279,19 @@ gint
main (gint argc, main (gint argc,
gchar **argv) gchar **argv)
{ {
GtkWidget *source;
GdkDisplay *display; GdkDisplay *display;
GdkWindow *gimp_window; GdkWindow *gimp_window;
GString *file_list = g_string_new (NULL);
GdkDragContext *context; gchar *cwd = g_get_current_dir ();
GdkDragProtocol protocol; gint i;
GdkAtom sel_type;
GdkAtom sel_id;
GList *targetlist;
guint timeout;
gboolean options = TRUE;
GString *file_list = g_string_new (NULL);
gchar *cwd = g_get_current_dir ();
gchar *file_uri = "";
guint i;
gtk_init (&argc, &argv); gtk_init (&argc, &argv);
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
gchar *file_uri = NULL;
gboolean options = TRUE;
if (strlen (argv[i]) == 0) if (strlen (argv[i]) == 0)
continue; continue;
@ -332,9 +317,17 @@ main (gint argc,
g_ascii_strncasecmp ("https:", argv[i], 6)) g_ascii_strncasecmp ("https:", argv[i], 6))
{ {
if (g_path_is_absolute (argv[i])) if (g_path_is_absolute (argv[i]))
file_uri = g_strconcat ("file:", argv[i], NULL); {
file_uri = g_filename_to_uri (argv[i], NULL, NULL);
}
else else
file_uri = g_strconcat ("file:", cwd, "/", argv[i], NULL); {
gchar *abs = g_build_filename (cwd, argv[i], NULL);
file_uri = g_strconcat (abs, NULL, NULL);
g_free (abs);
}
} }
else else
{ {
@ -348,74 +341,82 @@ main (gint argc,
g_free (file_uri); g_free (file_uri);
} }
if (file_list->len == 0)
{
usage (argv[0]);
return EXIT_SUCCESS;
}
/* locate Gimp window */ /* locate Gimp window */
display = gdk_display_get_default (); display = gdk_display_get_default ();
gimp_window = gimp_remote_find_window (display, gdk_screen_get_default ()); gimp_window = gimp_remote_find_window (display, gdk_screen_get_default ());
if (!gimp_window) if (! gimp_window)
{ {
if (start_new) start_new_gimp (argv[0], file_list);
start_new_gimp (argv[0], file_list);
g_printerr ("No gimp window found on display %s\n", gdk_get_display ()); g_printerr ("No gimp window found on display %s\n", gdk_get_display ());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
gdk_drag_get_protocol_for_display (display, GDK_WINDOW_XID (gimp_window), if (file_list->len > 0)
&protocol);
if (protocol != GDK_DRAG_PROTO_XDND)
{ {
g_printerr ("Gimp Window doesnt use Xdnd-Protocol - huh?\n"); GdkDragContext *context;
return EXIT_FAILURE; GdkDragProtocol protocol;
GtkWidget *source;
GdkAtom sel_type;
GdkAtom sel_id;
GList *targetlist;
guint timeout;
gdk_drag_get_protocol_for_display (display,
GDK_WINDOW_XID (gimp_window),
&protocol);
if (protocol != GDK_DRAG_PROTO_XDND)
{
g_printerr ("Gimp Window doesnt use Xdnd-Protocol - huh?\n");
return EXIT_FAILURE;
}
/* Problem: If the Toolbox is hidden via Tab (gtk_widget_hide)
* it does not accept DnD-Operations and gtk_main() will not be
* terminated. If the Toolbox is simply unmapped (by the WM)
* DnD works. But in both cases gdk_window_is_visible() returns
* FALSE. To work around this we add a timeout and abort after
* 1.5 seconds.
*/
timeout = g_timeout_add (1500, toolbox_hidden, NULL);
/* set up an DND-source */
source = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (source, "selection_get",
G_CALLBACK (source_selection_get),
file_list->str);
gtk_widget_realize (source);
/* specify the id and the content-type of the selection used to
* pass the URIs to Gimp.
*/
sel_id = gdk_atom_intern ("XdndSelection", FALSE);
sel_type = gdk_atom_intern ("text/uri-list", FALSE);
targetlist = g_list_prepend (NULL, GUINT_TO_POINTER (sel_type));
/* assign the selection to our DnD-source */
gtk_selection_owner_set (source, sel_id, GDK_CURRENT_TIME);
gtk_selection_add_target (source, sel_id, sel_type, 0);
/* drag_begin/motion/drop */
context = gdk_drag_begin (source->window, targetlist);
gdk_drag_motion (context, gimp_window, protocol, 0, 0,
GDK_ACTION_COPY, GDK_ACTION_COPY, GDK_CURRENT_TIME);
gdk_drag_drop (context, GDK_CURRENT_TIME);
/* finally enter the mainloop to handle the events */
gtk_main ();
g_source_remove (timeout);
} }
/* Problem: If the Toolbox is hidden via Tab (gtk_widget_hide)
* it does not accept DnD-Operations and gtk_main() will not be
* terminated. If the Toolbox is simply unmapped (by the Windowmanager)
* DnD works. But in both cases gdk_window_is_visible () == 0.... :-(
* To work around this add a timeout and abort after 1.5 seconds.
*/
timeout = g_timeout_add (1500, toolbox_hidden, NULL);
/* set up an DND-source */
source = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (source, "selection_get",
G_CALLBACK (source_selection_get), file_list->str);
gtk_widget_realize (source);
/* specify the id and the content-type of the selection used to
* pass the URIs to Gimp.
*/
sel_id = gdk_atom_intern ("XdndSelection", FALSE);
sel_type = gdk_atom_intern ("text/uri-list", FALSE);
targetlist = g_list_prepend (NULL, GUINT_TO_POINTER (sel_type));
/* assign the selection to our DnD-source */
gtk_selection_owner_set (source, sel_id, GDK_CURRENT_TIME);
gtk_selection_add_target (source, sel_id, sel_type, 0);
/* drag_begin/motion/drop */
context = gdk_drag_begin (source->window, targetlist);
gdk_drag_motion (context, gimp_window, protocol, 0, 0,
GDK_ACTION_COPY, GDK_ACTION_COPY, GDK_CURRENT_TIME);
gdk_drag_drop (context, GDK_CURRENT_TIME);
/* finally enter the mainloop to handle the events */
gtk_main ();
g_source_remove (timeout);
g_string_free (file_list, TRUE); g_string_free (file_list, TRUE);
return EXIT_SUCCESS; return EXIT_SUCCESS;