mirror of https://github.com/GNOME/gimp.git
tools/Makefile.am tools/gimp-remote.[ch] split gimp-remote into common and
2007-10-25 Sven Neumann <sven@gimp.org> * tools/Makefile.am * tools/gimp-remote.[ch] * tools/gimp-remote-x11.c: split gimp-remote into common and X11 specific code. svn path=/trunk/; revision=23947
This commit is contained in:
parent
07533d3dc1
commit
03235e4b23
|
@ -1,3 +1,10 @@
|
|||
2007-10-25 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* tools/Makefile.am
|
||||
* tools/gimp-remote.[ch]
|
||||
* tools/gimp-remote-x11.c: split gimp-remote into common and X11
|
||||
specific code.
|
||||
|
||||
2007-10-25 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* configure.in: made all tests consistently use
|
||||
|
|
|
@ -16,7 +16,10 @@ EXTRA_PROGRAMS = \
|
|||
gimp-remote-2.4 \
|
||||
kernelgen
|
||||
|
||||
gimp_remote_2_4_SOURCES = gimp-remote.c
|
||||
gimp_remote_2_4_SOURCES = \
|
||||
gimp-remote.c \
|
||||
gimp-remote.h \
|
||||
gimp-remote-x11.c
|
||||
|
||||
gimp_remote_2_4_LDADD = \
|
||||
$(GTK_LIBS) \
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimp-remote-x11.c
|
||||
* Copyright (C) 2000-2007 Sven Neumann <sven@gimp.org>
|
||||
* Simon Budig <simon@gimp.org>
|
||||
*
|
||||
* X11 specific routines for gimp-remote.
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <X11/Xmu/WinUtil.h>
|
||||
|
||||
#include "libgimpbase/gimpversion.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gimp-remote.h"
|
||||
|
||||
|
||||
#define GIMP_BINARY "gimp-" GIMP_APP_VERSION
|
||||
|
||||
|
||||
static void
|
||||
source_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
const gchar *uri)
|
||||
{
|
||||
gtk_selection_data_set (selection_data,
|
||||
selection_data->target,
|
||||
8, (const guchar *) uri, strlen (uri));
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toolbox_hidden (gpointer data)
|
||||
{
|
||||
g_printerr ("%s\n%s\n",
|
||||
_("Could not connect to GIMP."),
|
||||
_("Make sure that the Toolbox is visible!"));
|
||||
gtk_main_quit ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
gimp_remote_find_toolbox (GdkDisplay *display,
|
||||
GdkScreen *screen)
|
||||
{
|
||||
GdkWindow *result = NULL;
|
||||
Display *xdisplay;
|
||||
Window root, parent;
|
||||
Window *children;
|
||||
Atom role_atom;
|
||||
Atom string_atom;
|
||||
guint nchildren;
|
||||
gint i;
|
||||
|
||||
GdkWindow *root_window = gdk_screen_get_root_window (screen);
|
||||
|
||||
xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
role_atom = XInternAtom (xdisplay, "WM_WINDOW_ROLE", TRUE);
|
||||
string_atom = XInternAtom (xdisplay, "STRING", TRUE);
|
||||
|
||||
if (role_atom == None || string_atom == None)
|
||||
return NULL;
|
||||
|
||||
if (XQueryTree (xdisplay, GDK_WINDOW_XID (root_window),
|
||||
&root, &parent, &children, &nchildren) == 0)
|
||||
return NULL;
|
||||
|
||||
if (! (children && nchildren))
|
||||
return NULL;
|
||||
|
||||
for (i = nchildren - 1; i >= 0; i--)
|
||||
{
|
||||
Window window;
|
||||
Atom ret_type;
|
||||
gint ret_format;
|
||||
gulong bytes_after;
|
||||
gulong nitems;
|
||||
guchar *data;
|
||||
|
||||
/* The XmuClientWindow() function finds a window at or below the
|
||||
* specified window, that has a WM_STATE property. If such a
|
||||
* window is found, it is returned; otherwise the argument window
|
||||
* is returned.
|
||||
*/
|
||||
|
||||
window = XmuClientWindow (xdisplay, children[i]);
|
||||
|
||||
/* We are searching for the GIMP toolbox: Its WM_WINDOW_ROLE Property
|
||||
* (as set by gtk_window_set_role ()) has the value "gimp-toolbox".
|
||||
* This is pretty reliable, since it ask for a special property,
|
||||
* explicitly set by GIMP. See below... :-)
|
||||
*/
|
||||
|
||||
if (XGetWindowProperty (xdisplay, window,
|
||||
role_atom,
|
||||
0, 32,
|
||||
FALSE,
|
||||
string_atom,
|
||||
&ret_type, &ret_format, &nitems, &bytes_after,
|
||||
&data) == Success && ret_type)
|
||||
{
|
||||
if (nitems > 11 &&
|
||||
strcmp ((const gchar *) data, "gimp-toolbox") == 0)
|
||||
{
|
||||
XFree (data);
|
||||
result = gdk_window_foreign_new_for_display (display, window);
|
||||
break;
|
||||
}
|
||||
|
||||
XFree (data);
|
||||
}
|
||||
}
|
||||
|
||||
XFree (children);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_remote_launch (GdkScreen *screen,
|
||||
const gchar *argv0,
|
||||
const gchar *startup_id,
|
||||
gboolean no_splash,
|
||||
GString *file_list)
|
||||
{
|
||||
gchar *display_name;
|
||||
gchar **argv;
|
||||
gchar *gimp, *path, *name, *pwd;
|
||||
const gchar *spath;
|
||||
gint i;
|
||||
|
||||
if (startup_id)
|
||||
putenv (g_strdup_printf ("DESKTOP_STARTUP_ID=%s", startup_id));
|
||||
|
||||
if (file_list->len > 0)
|
||||
file_list = g_string_prepend (file_list, "\n");
|
||||
|
||||
display_name = gdk_screen_make_display_name (screen);
|
||||
file_list = g_string_prepend (file_list, display_name);
|
||||
file_list = g_string_prepend (file_list, "--display\n");
|
||||
g_free (display_name);
|
||||
|
||||
if (no_splash)
|
||||
file_list = g_string_prepend (file_list, "--no-splash\n");
|
||||
|
||||
file_list = g_string_prepend (file_list, "gimp\n");
|
||||
|
||||
argv = g_strsplit (file_list->str, "\n", 0);
|
||||
|
||||
/* We are searching for the path the gimp-remote executable lives in */
|
||||
|
||||
/*
|
||||
* the "_" environment variable usually gets set by the sh-family of
|
||||
* shells. We have to sanity-check it. If we do not find anything
|
||||
* usable in it try argv[0], then fall back to search the path.
|
||||
*/
|
||||
|
||||
gimp = NULL;
|
||||
spath = NULL;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
spath = g_getenv ("_");
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
spath = argv0;
|
||||
}
|
||||
|
||||
if (spath)
|
||||
{
|
||||
name = g_path_get_basename (spath);
|
||||
|
||||
if (! strncmp (name, "gimp-remote", 11))
|
||||
{
|
||||
path = g_path_get_dirname (spath);
|
||||
|
||||
if (g_path_is_absolute (spath))
|
||||
{
|
||||
gimp = g_build_filename (path, GIMP_BINARY, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pwd = g_get_current_dir ();
|
||||
gimp = g_build_filename (pwd, path, GIMP_BINARY, NULL);
|
||||
g_free (pwd);
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
if (gimp)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We must ensure that gimp is started with a different PID.
|
||||
Otherwise it could happen that (when it opens it's display) it sends
|
||||
the same auth token again (because that one is uniquified with PID
|
||||
and time()), which the server would deny. */
|
||||
switch (fork ())
|
||||
{
|
||||
case -1:
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
case 0: /* child */
|
||||
execv (gimp, argv);
|
||||
execvp (GIMP_BINARY, argv);
|
||||
|
||||
/* if execv and execvp return, there was an error */
|
||||
g_printerr (_("Couldn't start '%s': %s"),
|
||||
GIMP_BINARY, g_strerror (errno));
|
||||
g_printerr ("\n");
|
||||
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_remote_drop_files (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
GString *file_list)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GdkDragProtocol protocol;
|
||||
GtkWidget *source;
|
||||
GdkAtom sel_type;
|
||||
GdkAtom sel_id;
|
||||
GList *targetlist;
|
||||
guint timeout;
|
||||
|
||||
gdk_drag_get_protocol_for_display (display,
|
||||
GDK_WINDOW_XID (window),
|
||||
&protocol);
|
||||
if (protocol != GDK_DRAG_PROTO_XDND)
|
||||
{
|
||||
g_printerr ("GIMP Window doesnt use Xdnd-Protocol - huh?\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* 5 seconds.
|
||||
*/
|
||||
|
||||
timeout = g_timeout_add (5000, 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, 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);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_remote_print_id (GdkWindow *window)
|
||||
{
|
||||
g_print ("0x%lx\n", GDK_WINDOW_XID (window));
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimp-remote.c
|
||||
* Copyright (C) 2000-2004 Sven Neumann <sven@gimp.org>
|
||||
* 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.
|
||||
|
@ -26,44 +26,25 @@
|
|||
*
|
||||
* 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. We do this *only*, because we are in a
|
||||
* feature freeze for GIMP 1.2 and adding a completely new communication
|
||||
* infrastructure for remote controlling GIMP is definitely a new
|
||||
* feature...
|
||||
* created application.
|
||||
* Simon
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <X11/Xmu/WinUtil.h>
|
||||
|
||||
#include "libgimpbase/gimpversion.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
|
||||
#define GIMP_BINARY "gimp-" GIMP_APP_VERSION
|
||||
#include "gimp-remote.h"
|
||||
|
||||
|
||||
static void start_new_gimp (GdkScreen *screen,
|
||||
const gchar *argv0,
|
||||
const gchar *startup_id,
|
||||
GString *file_list) G_GNUC_NORETURN;
|
||||
|
||||
static void show_version (void) G_GNUC_NORETURN;
|
||||
static void show_version (void) G_GNUC_NORETURN;
|
||||
|
||||
|
||||
static gboolean existing = FALSE;
|
||||
|
@ -88,11 +69,13 @@ static const GOptionEntry main_entries[] =
|
|||
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,
|
||||
|
@ -106,217 +89,6 @@ static const GOptionEntry main_entries[] =
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
static GdkWindow *
|
||||
gimp_remote_find_window (GdkDisplay *display,
|
||||
GdkScreen *screen)
|
||||
{
|
||||
GdkWindow *result = NULL;
|
||||
Display *xdisplay;
|
||||
Window root, parent;
|
||||
Window *children;
|
||||
Atom role_atom;
|
||||
Atom string_atom;
|
||||
guint nchildren;
|
||||
gint i;
|
||||
|
||||
GdkWindow *root_window = gdk_screen_get_root_window (screen);
|
||||
|
||||
xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
role_atom = XInternAtom (xdisplay, "WM_WINDOW_ROLE", TRUE);
|
||||
string_atom = XInternAtom (xdisplay, "STRING", TRUE);
|
||||
|
||||
if (role_atom == None || string_atom == None)
|
||||
return NULL;
|
||||
|
||||
if (XQueryTree (xdisplay, GDK_WINDOW_XID (root_window),
|
||||
&root, &parent, &children, &nchildren) == 0)
|
||||
return NULL;
|
||||
|
||||
if (! (children && nchildren))
|
||||
return NULL;
|
||||
|
||||
for (i = nchildren - 1; i >= 0; i--)
|
||||
{
|
||||
Window window;
|
||||
Atom ret_type;
|
||||
gint ret_format;
|
||||
gulong bytes_after;
|
||||
gulong nitems;
|
||||
guchar *data;
|
||||
|
||||
/* The XmuClientWindow() function finds a window at or below the
|
||||
* specified window, that has a WM_STATE property. If such a
|
||||
* window is found, it is returned; otherwise the argument window
|
||||
* is returned.
|
||||
*/
|
||||
|
||||
window = XmuClientWindow (xdisplay, children[i]);
|
||||
|
||||
/* We are searching for the GIMP toolbox: Its WM_WINDOW_ROLE Property
|
||||
* (as set by gtk_window_set_role ()) has the value "gimp-toolbox".
|
||||
* This is pretty reliable, since it ask for a special property,
|
||||
* explicitly set by GIMP. See below... :-)
|
||||
*/
|
||||
|
||||
if (XGetWindowProperty (xdisplay, window,
|
||||
role_atom,
|
||||
0, 32,
|
||||
FALSE,
|
||||
string_atom,
|
||||
&ret_type, &ret_format, &nitems, &bytes_after,
|
||||
&data) == Success && ret_type)
|
||||
{
|
||||
if (nitems > 11 &&
|
||||
strcmp ((const gchar *) data, "gimp-toolbox") == 0)
|
||||
{
|
||||
XFree (data);
|
||||
result = gdk_window_foreign_new_for_display (display, window);
|
||||
break;
|
||||
}
|
||||
|
||||
XFree (data);
|
||||
}
|
||||
}
|
||||
|
||||
XFree (children);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
source_selection_get (GtkWidget *widget,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
const gchar *uri)
|
||||
{
|
||||
gtk_selection_data_set (selection_data,
|
||||
selection_data->target,
|
||||
8, (const guchar *) uri, strlen (uri));
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toolbox_hidden (gpointer data)
|
||||
{
|
||||
g_printerr ("%s\n%s\n",
|
||||
_("Could not connect to GIMP."),
|
||||
_("Make sure that the Toolbox is visible!"));
|
||||
gtk_main_quit ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_new_gimp (GdkScreen *screen,
|
||||
const gchar *argv0,
|
||||
const gchar *startup_id,
|
||||
GString *file_list)
|
||||
{
|
||||
gchar *display_name;
|
||||
gchar **argv;
|
||||
gchar *gimp, *path, *name, *pwd;
|
||||
const gchar *spath;
|
||||
gint i;
|
||||
|
||||
if (startup_id)
|
||||
putenv (g_strdup_printf ("DESKTOP_STARTUP_ID=%s", startup_id));
|
||||
|
||||
if (file_list->len > 0)
|
||||
file_list = g_string_prepend (file_list, "\n");
|
||||
|
||||
display_name = gdk_screen_make_display_name (screen);
|
||||
file_list = g_string_prepend (file_list, display_name);
|
||||
file_list = g_string_prepend (file_list, "--display\n");
|
||||
g_free (display_name);
|
||||
|
||||
if (no_splash)
|
||||
file_list = g_string_prepend (file_list, "--no-splash\n");
|
||||
|
||||
file_list = g_string_prepend (file_list, "gimp\n");
|
||||
|
||||
argv = g_strsplit (file_list->str, "\n", 0);
|
||||
|
||||
/* We are searching for the path the gimp-remote executable lives in */
|
||||
|
||||
/*
|
||||
* the "_" environment variable usually gets set by the sh-family of
|
||||
* shells. We have to sanity-check it. If we do not find anything
|
||||
* usable in it try argv[0], then fall back to search the path.
|
||||
*/
|
||||
|
||||
gimp = NULL;
|
||||
spath = NULL;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
spath = g_getenv ("_");
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
spath = argv0;
|
||||
}
|
||||
|
||||
if (spath)
|
||||
{
|
||||
name = g_path_get_basename (spath);
|
||||
|
||||
if (!strncmp (name, "gimp-remote", 11))
|
||||
{
|
||||
path = g_path_get_dirname (spath);
|
||||
|
||||
if (g_path_is_absolute (spath))
|
||||
{
|
||||
gimp = g_build_filename (path, GIMP_BINARY, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pwd = g_get_current_dir ();
|
||||
gimp = g_build_filename (pwd, path, GIMP_BINARY, NULL);
|
||||
g_free (pwd);
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
if (gimp)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We must ensure that gimp is started with a different PID.
|
||||
Otherwise it could happen that (when it opens it's display) it sends
|
||||
the same auth token again (because that one is uniquified with PID
|
||||
and time()), which the server would deny. */
|
||||
switch (fork ())
|
||||
{
|
||||
case -1:
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
case 0: /* child */
|
||||
execv (gimp, argv);
|
||||
execvp (GIMP_BINARY, argv);
|
||||
|
||||
/* if execv and execvp return, there was an error */
|
||||
g_printerr (_("Couldn't start '%s': %s"),
|
||||
GIMP_BINARY, g_strerror (errno));
|
||||
g_printerr ("\n");
|
||||
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
show_version (void)
|
||||
{
|
||||
|
@ -381,7 +153,7 @@ main (gint argc,
|
|||
GError *error = NULL;
|
||||
GdkDisplay *display;
|
||||
GdkScreen *screen;
|
||||
GdkWindow *gimp_window;
|
||||
GdkWindow *toolbox;
|
||||
const gchar *startup_id;
|
||||
gchar *desktop_startup_id = NULL;
|
||||
GString *file_list = g_string_new (NULL);
|
||||
|
@ -459,85 +231,30 @@ main (gint argc,
|
|||
/* if called without any filenames, always start a new GIMP */
|
||||
if (file_list->len == 0 && !query && !print_xid && !existing)
|
||||
{
|
||||
start_new_gimp (screen, argv[0], desktop_startup_id, file_list);
|
||||
gimp_remote_launch (screen,
|
||||
argv[0], desktop_startup_id, no_splash,
|
||||
file_list);
|
||||
}
|
||||
|
||||
gimp_window = gimp_remote_find_window (display, screen);
|
||||
toolbox = gimp_remote_find_toolbox (display, screen);
|
||||
|
||||
if (! query && ! print_xid)
|
||||
{
|
||||
if (gimp_window)
|
||||
if (toolbox)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
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
|
||||
* 5 seconds.
|
||||
*/
|
||||
|
||||
timeout = g_timeout_add (5000, 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);
|
||||
if (! gimp_remote_drop_files (display, toolbox, file_list))
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else if (! existing)
|
||||
{
|
||||
start_new_gimp (screen, argv[0], desktop_startup_id, file_list);
|
||||
gimp_remote_launch (screen,
|
||||
argv[0], desktop_startup_id, no_splash,
|
||||
file_list);
|
||||
}
|
||||
}
|
||||
else if (print_xid)
|
||||
else if (print_xid && toolbox)
|
||||
{
|
||||
if (gimp_window)
|
||||
{
|
||||
g_print ("0x%lx\n", GDK_WINDOW_XID (gimp_window));
|
||||
}
|
||||
gimp_remote_print_id (toolbox);
|
||||
}
|
||||
|
||||
gdk_notify_startup_complete ();
|
||||
|
@ -547,5 +264,5 @@ main (gint argc,
|
|||
g_string_free (file_list, TRUE);
|
||||
g_free (desktop_startup_id);
|
||||
|
||||
return (gimp_window ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
return (toolbox ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimp-remote.h
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_REMOTE_H__
|
||||
#define __GIMP_REMOTE_H__
|
||||
|
||||
|
||||
GdkWindow * gimp_remote_find_toolbox (GdkDisplay *display,
|
||||
GdkScreen *screen);
|
||||
void gimp_remote_launch (GdkScreen *screen,
|
||||
const gchar *argv0,
|
||||
const gchar *startup_id,
|
||||
gboolean no_splash,
|
||||
GString *file_list) G_GNUC_NORETURN;
|
||||
gboolean gimp_remote_drop_files (GdkDisplay *display,
|
||||
GdkWindow *window,
|
||||
GString *file_list);
|
||||
void gimp_remote_print_id (GdkWindow *window);
|
||||
|
||||
|
||||
#endif /* __GIMP_REMOTE_H__ */
|
Loading…
Reference in New Issue