mirror of https://github.com/GNOME/gimp.git
268 lines
6.5 KiB
C
268 lines
6.5 KiB
C
/* GIMP - The GNU Image Manipulation Program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* gimp-remote.c
|
|
* Copyright (C) 2000-2007 Sven Neumann <sven@gimp.org>
|
|
* Simon Budig <simon@gimp.org>
|
|
*
|
|
* Tells a running gimp to open files by creating a synthetic drop-event.
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* Disclaimer:
|
|
*
|
|
* It is a really bad idea to use Drag'n'Drop for inter-client
|
|
* communication. Dont even think about doing this in your own newly
|
|
* created application.
|
|
* Simon
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <locale.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "libgimpbase/gimpversion.h"
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
#include "gimp-remote.h"
|
|
|
|
|
|
static void show_version (void) G_GNUC_NORETURN;
|
|
|
|
|
|
static gboolean existing = FALSE;
|
|
static gboolean query = FALSE;
|
|
static gboolean no_splash = FALSE;
|
|
static gboolean print_xid = FALSE;
|
|
static const gchar **filenames = NULL;
|
|
|
|
static const GOptionEntry main_entries[] =
|
|
{
|
|
{ "version", 'v', G_OPTION_FLAG_NO_ARG,
|
|
G_OPTION_ARG_CALLBACK, (GOptionArgFunc) show_version,
|
|
N_("Show version information and exit"), NULL
|
|
},
|
|
{
|
|
"existing", 'e', 0,
|
|
G_OPTION_ARG_NONE, &existing,
|
|
N_("Use a running GIMP only, never start a new one"), NULL
|
|
},
|
|
{
|
|
"query", 'q', 0,
|
|
G_OPTION_ARG_NONE, &query,
|
|
N_("Only check if GIMP is running, then quit"), NULL
|
|
},
|
|
#ifdef GDK_WINDOWING_X11
|
|
{
|
|
"print-xid", 'p', 0,
|
|
G_OPTION_ARG_NONE, &print_xid,
|
|
N_("Print X window ID of GIMP toolbox window, then quit"), NULL
|
|
},
|
|
#endif
|
|
{
|
|
"no-splash", 's', 0,
|
|
G_OPTION_ARG_NONE, &no_splash,
|
|
N_("Start GIMP without showing the startup window"), NULL
|
|
},
|
|
{
|
|
G_OPTION_REMAINING, 0, 0,
|
|
G_OPTION_ARG_FILENAME_ARRAY, &filenames,
|
|
NULL, NULL
|
|
},
|
|
{ NULL }
|
|
};
|
|
|
|
static void
|
|
show_version (void)
|
|
{
|
|
g_print (_("%s version %s"), "gimp-remote", GIMP_VERSION);
|
|
g_print ("\n");
|
|
|
|
exit (EXIT_SUCCESS);
|
|
}
|
|
|
|
static void
|
|
init_i18n (void)
|
|
{
|
|
setlocale (LC_ALL, "");
|
|
|
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
|
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
|
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
#endif
|
|
|
|
textdomain (GETTEXT_PACKAGE);
|
|
}
|
|
|
|
/* Check name for a valid URI scheme as described in RFC 2396.
|
|
* URI scheme:suffix with scheme = [alpha][alphanum|digit|+|-|.]*
|
|
* Note that a null suffix will be considered as an invalid URI.
|
|
* return 1 if valid scheme found, else 0
|
|
*/
|
|
static gboolean
|
|
is_valid_uri (const gchar *name)
|
|
{
|
|
const gchar *c = name;
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
/* first character must be alpha */
|
|
if (! g_ascii_isalpha (*c))
|
|
return FALSE;
|
|
|
|
c++;
|
|
while (*c != '\0' && *c != ':')
|
|
{
|
|
if (! g_ascii_isalnum (*c) && *c != '+' && *c != '-' && *c != '.')
|
|
return FALSE;
|
|
c++;
|
|
}
|
|
|
|
if (*c == ':')
|
|
{
|
|
c++;
|
|
if (*c != '\0')
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
gint
|
|
main (gint argc,
|
|
gchar **argv)
|
|
{
|
|
GOptionContext *context;
|
|
GError *error = NULL;
|
|
GdkDisplay *display;
|
|
GdkScreen *screen;
|
|
GdkWindow *toolbox;
|
|
const gchar *startup_id;
|
|
gchar *desktop_startup_id = NULL;
|
|
GString *file_list = g_string_new (NULL);
|
|
|
|
init_i18n ();
|
|
|
|
/* we save the startup_id before calling gtk_init()
|
|
because GTK+ will unset it */
|
|
|
|
startup_id = g_getenv ("DESKTOP_STARTUP_ID");
|
|
if (startup_id && *startup_id)
|
|
desktop_startup_id = g_strdup (startup_id);
|
|
|
|
/* parse the command-line options */
|
|
context = g_option_context_new ("[FILE|URI...]");
|
|
g_option_context_add_main_entries (context, main_entries, NULL);
|
|
g_option_context_add_group (context, gtk_get_option_group (TRUE));
|
|
|
|
if (! g_option_context_parse (context, &argc, &argv, &error))
|
|
{
|
|
g_printerr ("%s\n", error->message);
|
|
g_error_free (error);
|
|
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
gtk_init (&argc, &argv);
|
|
|
|
if (filenames)
|
|
{
|
|
gchar *cwd = g_get_current_dir ();
|
|
gint i;
|
|
|
|
for (i = 0; filenames[i]; i++)
|
|
{
|
|
const gchar *name = filenames[i];
|
|
gchar *uri;
|
|
|
|
/* If not already a valid URI */
|
|
if (! is_valid_uri (name))
|
|
{
|
|
if (g_path_is_absolute (name))
|
|
{
|
|
uri = g_filename_to_uri (name, NULL, NULL);
|
|
}
|
|
else
|
|
{
|
|
gchar *abs = g_build_filename (cwd, name, NULL);
|
|
|
|
uri = g_filename_to_uri (abs, NULL, NULL);
|
|
g_free (abs);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uri = g_strdup (name);
|
|
}
|
|
|
|
if (uri)
|
|
{
|
|
if (file_list->len > 0)
|
|
file_list = g_string_append_c (file_list, '\n');
|
|
|
|
file_list = g_string_append (file_list, uri);
|
|
g_free (uri);
|
|
}
|
|
}
|
|
|
|
g_free (cwd);
|
|
}
|
|
|
|
display = gdk_display_get_default ();
|
|
screen = gdk_screen_get_default ();
|
|
|
|
/* if called without any filenames, always start a new GIMP */
|
|
if (file_list->len == 0 && !query && !print_xid && !existing)
|
|
{
|
|
gimp_remote_launch (screen,
|
|
argv[0], desktop_startup_id, no_splash,
|
|
file_list);
|
|
}
|
|
|
|
toolbox = gimp_remote_find_toolbox (display, screen);
|
|
|
|
if (! query && ! print_xid)
|
|
{
|
|
if (toolbox)
|
|
{
|
|
if (! gimp_remote_drop_files (display, toolbox, file_list))
|
|
return EXIT_FAILURE;
|
|
}
|
|
else if (! existing)
|
|
{
|
|
gimp_remote_launch (screen,
|
|
argv[0], desktop_startup_id, no_splash,
|
|
file_list);
|
|
}
|
|
}
|
|
else if (print_xid && toolbox)
|
|
{
|
|
gimp_remote_print_id (toolbox);
|
|
}
|
|
|
|
gdk_notify_startup_complete ();
|
|
|
|
g_option_context_free (context);
|
|
|
|
g_string_free (file_list, TRUE);
|
|
g_free (desktop_startup_id);
|
|
|
|
return (toolbox ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
}
|