1
/* GIMP - The GNU Image Manipulation Program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
5
* Copyright (C) 2000-2007 Sven Neumann <sven@gimp.org>
6
* Simon Budig <simon@gimp.org>
8
* X11 specific routines for gimp-remote.
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38
#include <X11/Xmu/WinUtil.h>
40
#include "libgimpbase/gimpversion.h"
42
#include <glib/gi18n.h>
44
#include "gimp-remote.h"
47
#define GIMP_BINARY "gimp-" GIMP_APP_VERSION
51
source_selection_get (GtkWidget *widget,
52
GtkSelectionData *selection_data,
57
gtk_selection_data_set (selection_data,
58
selection_data->target,
59
8, (const guchar *) uri, strlen (uri));
64
toolbox_hidden (gpointer data)
66
g_printerr ("%s\n%s\n",
67
_("Could not connect to GIMP."),
68
_("Make sure that the Toolbox is visible!"));
75
gimp_remote_find_toolbox (GdkDisplay *display,
78
GdkWindow *result = NULL;
87
GdkWindow *root_window = gdk_screen_get_root_window (screen);
89
xdisplay = gdk_x11_display_get_xdisplay (display);
91
role_atom = XInternAtom (xdisplay, "WM_WINDOW_ROLE", TRUE);
92
string_atom = XInternAtom (xdisplay, "STRING", TRUE);
94
if (role_atom == None || string_atom == None)
97
if (XQueryTree (xdisplay, GDK_WINDOW_XID (root_window),
98
&root, &parent, &children, &nchildren) == 0)
101
if (! (children && nchildren))
104
for (i = nchildren - 1; i >= 0; i--)
113
/* The XmuClientWindow() function finds a window at or below the
114
* specified window, that has a WM_STATE property. If such a
115
* window is found, it is returned; otherwise the argument window
119
window = XmuClientWindow (xdisplay, children[i]);
121
/* We are searching for the GIMP toolbox: Its WM_WINDOW_ROLE Property
122
* (as set by gtk_window_set_role ()) has the value "gimp-toolbox".
123
* This is pretty reliable, since it ask for a special property,
124
* explicitly set by GIMP. See below... :-)
127
if (XGetWindowProperty (xdisplay, window,
132
&ret_type, &ret_format, &nitems, &bytes_after,
133
&data) == Success && ret_type)
136
strcmp ((const gchar *) data, "gimp-toolbox") == 0)
139
result = gdk_window_foreign_new_for_display (display, window);
153
gimp_remote_launch (GdkScreen *screen,
155
const gchar *startup_id,
161
gchar *gimp, *path, *name, *pwd;
166
g_setenv ("DESKTOP_STARTUP_ID", startup_id, TRUE);
168
if (file_list->len > 0)
169
file_list = g_string_prepend (file_list, "\n");
171
display_name = gdk_screen_make_display_name (screen);
172
file_list = g_string_prepend (file_list, display_name);
173
file_list = g_string_prepend (file_list, "--display\n");
174
g_free (display_name);
177
file_list = g_string_prepend (file_list, "--no-splash\n");
179
file_list = g_string_prepend (file_list, "gimp\n");
181
argv = g_strsplit (file_list->str, "\n", 0);
183
/* We are searching for the path the gimp-remote executable lives in */
186
* the "_" environment variable usually gets set by the sh-family of
187
* shells. We have to sanity-check it. If we do not find anything
188
* usable in it try argv[0], then fall back to search the path.
194
for (i = 0; i < 2; i++)
198
spath = g_getenv ("_");
207
name = g_path_get_basename (spath);
209
if (! strncmp (name, "gimp-remote", 11))
211
path = g_path_get_dirname (spath);
213
if (g_path_is_absolute (spath))
215
gimp = g_build_filename (path, GIMP_BINARY, NULL);
219
pwd = g_get_current_dir ();
220
gimp = g_build_filename (pwd, path, GIMP_BINARY, NULL);
234
/* We must ensure that gimp is started with a different PID.
235
Otherwise it could happen that (when it opens it's display) it sends
236
the same auth token again (because that one is uniquified with PID
237
and time()), which the server would deny. */
245
execvp (GIMP_BINARY, argv);
247
/* if execv and execvp return, there was an error */
248
g_printerr (_("Couldn't start '%s': %s"),
249
GIMP_BINARY, g_strerror (errno));
254
default: /* parent */
262
gimp_remote_drop_files (GdkDisplay *display,
266
GdkDragContext *context;
267
GdkDragProtocol protocol;
274
gdk_drag_get_protocol_for_display (display,
275
GDK_WINDOW_XID (window),
277
if (protocol != GDK_DRAG_PROTO_XDND)
279
g_printerr ("GIMP Window doesnt use Xdnd-Protocol - huh?\n");
283
/* Problem: If the Toolbox is hidden via Tab (gtk_widget_hide)
284
* it does not accept DnD-Operations and gtk_main() will not be
285
* terminated. If the Toolbox is simply unmapped (by the WM)
286
* DnD works. But in both cases gdk_window_is_visible() returns
287
* FALSE. To work around this we add a timeout and abort after
291
timeout = g_timeout_add (5000, toolbox_hidden, NULL);
293
/* set up an DND-source */
294
source = gtk_window_new (GTK_WINDOW_TOPLEVEL);
295
g_signal_connect (source, "selection-get",
296
G_CALLBACK (source_selection_get),
298
gtk_widget_realize (source);
301
/* specify the id and the content-type of the selection used to
302
* pass the URIs to GIMP.
304
sel_id = gdk_atom_intern ("XdndSelection", FALSE);
305
sel_type = gdk_atom_intern ("text/uri-list", FALSE);
306
targetlist = g_list_prepend (NULL, GUINT_TO_POINTER (sel_type));
308
/* assign the selection to our DnD-source */
309
gtk_selection_owner_set (source, sel_id, GDK_CURRENT_TIME);
310
gtk_selection_add_target (source, sel_id, sel_type, 0);
312
/* drag_begin/motion/drop */
313
context = gdk_drag_begin (source->window, targetlist);
315
gdk_drag_motion (context, window, protocol, 0, 0,
316
GDK_ACTION_COPY, GDK_ACTION_COPY, GDK_CURRENT_TIME);
318
gdk_drag_drop (context, GDK_CURRENT_TIME);
320
/* finally enter the mainloop to handle the events */
323
g_source_remove (timeout);
329
gimp_remote_print_id (GdkWindow *window)
331
g_print ("0x%lx\n", GDK_WINDOW_XID (window));