INSTALL check for D-Bus GLib bindings.

2007-01-19  Sven Neumann  <sven@gimp.org>

	* INSTALL
	* configure.in: check for D-Bus GLib bindings.

	* app/Makefile.am
	* app/main.c: check if an interactive GIMP instance proposes
	itself on the D-Bus and delegate to it. Allow this behaviour to be
	overridden by using the --new-instance command-line option.

	* app/widgets/Makefile.am
	* app/widgets/gimpdbusservice.[ch]
	* app/widgets/dbus-service.xml: added an object that offers a
	D-Bus service.

	* app/gui/Makefile.am
	* app/gui/gui.c: connect to the D-Bus and export the GimpDBusService.


svn path=/trunk/; revision=21737
This commit is contained in:
Sven Neumann 2007-01-19 14:50:13 +00:00 committed by Sven Neumann
parent 20b331da7f
commit bfd1dd5f07
11 changed files with 430 additions and 32 deletions

View File

@ -1,3 +1,21 @@
2007-01-19 Sven Neumann <sven@gimp.org>
* INSTALL
* configure.in: check for D-Bus GLib bindings.
* app/Makefile.am
* app/main.c: check if an interactive GIMP instance proposes
itself on the D-Bus and delegate to it. Allow this behaviour to be
overridden by using the --new-instance command-line option.
* app/widgets/Makefile.am
* app/widgets/gimpdbusservice.[ch]
* app/widgets/dbus-service.xml: added an object that offers a
D-Bus service.
* app/gui/Makefile.am
* app/gui/gui.c: connect to the D-Bus and export the GimpDBusService.
2007-01-19 Sven Neumann <sven@gimp.org>
* app/file/file-utils.[ch]: let the filename -> uri functions take

19
INSTALL
View File

@ -29,7 +29,7 @@ header files installed.
from http://www.freedesktop.org/software/pkgconfig/.
2. You need to have installed GTK+ version 2.8.17 or newer. GIMP
needs an even more recent version of GLib (>= 2.10.2). It also
needs an even more recent version of GLib (>= 2.12.3). It also
wants Pango (>= 1.12.2). Sources for these can be grabbed from
ftp://ftp.gtk.org/.
@ -42,27 +42,30 @@ header files installed.
Older versions are known to have bugs that seriously affect
stability of GIMP.
4. We use libart2. Grab the module libart_lgpl out of GNOME CVS or
4. We use libart2. Grab the module libart_lgpl out of GNOME SVN or
fetch the tarball from
ftp://ftp.gnome.org/pub/gnome/sources/libart_lgpl/
5. You may want to install other third party libraries or programs
5. We use dbus-glib if available. Grab it from
http://dbus.freedesktop.org/releases/dbus-glib/
6. You may want to install other third party libraries or programs
that are needed for some of the available plugins. We recommend
to check that the following libraries are installed: libpng,
libjpeg, libpoppler, libtiff, gtkhtml-2, libmng, librsvg, libwmf.
6. The Python extension requires Python development headers to be
7. The Python extension requires Python development headers to be
present. You will also need PyGTK and the respective development
headers.
7. Configure GIMP by running the `configure' script. You may want
8. Configure GIMP by running the `configure' script. You may want
to pass some options to it, see below.
8. Build GIMP by running `make'. The use of GNU make is recommended.
9. Build GIMP by running `make'. The use of GNU make is recommended.
If you need to tweak the build to make it work with other flavours
of make, we'd appreciate if you'd send us a patch with the changes.
9. Install GIMP by running `make install'. In order to avoid clashes
10. Install GIMP by running `make install'. In order to avoid clashes
with other versions of GIMP, we install a binary called gimp-2.3.
By default there's also a link created so that you can type 'gimp'
to start gimp-2.3.
@ -164,7 +167,7 @@ These are:
--enable-gtk-doc. This option controls whether the libgimp API
references will be created using gtk-doc. The HTML pages are
included in a standard tarball, so you will only need this if you
are building from CVS.
are building from SVN.
--with-html-dir=PATH. This option allows to specify where the
libgimp API reference should be installed. You might want to modify

View File

@ -89,6 +89,7 @@ INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(PANGOFT2_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
-I$(includedir)
gimp_2_3_LDFLAGS = $(mwindows) $(munix) -u $(SYMPREFIX)xcf_init -u $(SYMPREFIX)internal_procs_init
@ -127,6 +128,7 @@ gimp_2_3_LDADD = \
$(PANGOFT2_LIBS) \
$(FONTCONFIG_LIBS) \
$(FREETYPE_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTHREAD_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \

View File

@ -10,6 +10,7 @@ INCLUDES = \
-I$(top_builddir)/app \
-I$(top_srcdir)/app \
$(GTK_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = libappgui.a

View File

@ -22,6 +22,11 @@
#include <gtk/gtk.h>
#if HAVE_DBUS_GLIB
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#endif
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "libgimpwidgets/gimpwidgets-private.h"
@ -51,6 +56,7 @@
#include "widgets/gimpclipboard.h"
#include "widgets/gimpcolorselectorpalette.h"
#include "widgets/gimpcontrollers.h"
#include "widgets/gimpdbusservice.h"
#include "widgets/gimpdevices.h"
#include "widgets/gimpdevicestatus.h"
#include "widgets/gimpdialogfactory.h"
@ -126,11 +132,18 @@ static void gui_display_changed (GimpContext *context,
Gimp *gimp);
static void gui_display_remove (GimpContainer *displays);
static void gui_dbus_service_init (Gimp *gimp);
static void gui_dbus_service_exit (void);
/* private variables */
static Gimp *the_gui_gimp = NULL;
static GimpUIManager *image_ui_manager = NULL;
static Gimp *the_gui_gimp = NULL;
static GimpUIManager *image_ui_manager = NULL;
#if HAVE_DBUS_GLIB
static DBusGConnection *dbus_connection = NULL;
#endif
/* public functions */
@ -262,18 +275,19 @@ gui_sanity_check (void)
GTK_REQUIRED_MICRO);
if (mismatch)
return g_strdup_printf
("%s\n\n"
"GIMP requires GTK+ version %d.%d.%d or later.\n"
"Installed GTK+ version is %d.%d.%d.\n\n"
"Somehow you or your software packager managed\n"
"to install GIMP with an older GTK+ version.\n\n"
"Please upgrade to GTK+ version %d.%d.%d or later.",
mismatch,
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO,
gtk_major_version, gtk_minor_version, gtk_micro_version,
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO);
{
return g_strdup_printf
("%s\n\n"
"GIMP requires GTK+ version %d.%d.%d or later.\n"
"Installed GTK+ version is %d.%d.%d.\n\n"
"Somehow you or your software packager managed\n"
"to install GIMP with an older GTK+ version.\n\n"
"Please upgrade to GTK+ version %d.%d.%d or later.",
mismatch,
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO,
gtk_major_version, gtk_minor_version, gtk_micro_version,
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO);
}
#undef GTK_REQUIRED_MAJOR
#undef GTK_REQUIRED_MINOR
#undef GTK_REQUIRED_MICRO
@ -465,6 +479,8 @@ gui_restore_after_callback (Gimp *gimp,
session_restore (gimp);
dialogs_show_toolbox ();
gui_dbus_service_init (gimp);
}
static gboolean
@ -487,6 +503,10 @@ gui_exit_callback (Gimp *gimp,
gimp->message_handler = GIMP_CONSOLE;
#if HAVE_DBUS_GLIB
gui_dbus_service_exit ();
#endif
if (gui_config->save_session_info)
session_save (gimp, FALSE);
@ -682,3 +702,43 @@ gui_display_remove (GimpContainer *displays)
if (gimp_container_is_empty (displays))
dialogs_show_toolbox ();
}
static void
gui_dbus_service_init (Gimp *gimp)
{
#if HAVE_DBUS_GLIB
GError *error = NULL;
g_return_if_fail (dbus_connection == NULL);
dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (dbus_connection)
{
GObject *service = gimp_dbus_service_new (gimp);
dbus_bus_request_name (dbus_g_connection_get_connection (dbus_connection),
GIMP_DBUS_SERVICE_NAME, 0, NULL);
dbus_g_connection_register_g_object (dbus_connection,
GIMP_DBUS_SERVICE_PATH, service);
}
else
{
g_printerr ("%s\n", error->message);
g_error_free (error);
}
#endif
}
static void
gui_dbus_service_exit (void)
{
#if HAVE_DBUS_GLIB
if (dbus_connection)
{
dbus_g_connection_unref (dbus_connection);
dbus_connection = NULL;
}
#endif
}

View File

@ -37,6 +37,10 @@
#include <glib-object.h>
#if HAVE_DBUS_GLIB
#include <dbus/dbus-glib.h>
#endif
#include "libgimpbase/gimpbase.h"
#include "core/core-types.h"
@ -47,6 +51,8 @@
#include "core/gimp.h"
#include "widgets/gimpdbusservice.h"
#include "about.h"
#include "app_procs.h"
#include "errors.h"
@ -100,6 +106,7 @@ static gboolean no_data = FALSE;
static gboolean no_fonts = FALSE;
static gboolean no_splash = FALSE;
static gboolean be_verbose = FALSE;
static gboolean new_instance = FALSE;
#if defined (USE_SYSV_SHM) || defined (USE_POSIX_SHM) || defined (G_OS_WIN32)
static gboolean use_shm = TRUE;
#else
@ -134,6 +141,11 @@ static const GOptionEntry main_entries[] =
G_OPTION_ARG_NONE, &be_verbose,
N_("Be more verbose"), NULL
},
{
"new-instance", 'n', 0,
G_OPTION_ARG_NONE, &new_instance,
N_("Start a new GIMP instance"), NULL
},
{
"no-interface", 'i', 0,
G_OPTION_ARG_NONE, &no_interface,
@ -314,6 +326,70 @@ main (int argc,
app_exit (EXIT_FAILURE);
}
if (no_interface)
new_instance = TRUE;
#ifndef GIMP_CONSOLE_COMPILATION
#if HAVE_DBUS_GLIB
if (! new_instance)
{
DBusGConnection *connection;
connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
if (connection)
{
DBusGProxy *proxy;
gboolean success;
const gchar **arg = filenames;
/* Work around a bug in dbus-glib:
* It doesn't accept NULL as an empty string array.
*/
if (! filenames)
arg = g_new0 (const gchar *, 1);
proxy = dbus_g_proxy_new_for_name (connection,
GIMP_DBUS_SERVICE_NAME,
GIMP_DBUS_SERVICE_PATH,
GIMP_DBUS_SERVICE_INTERFACE);
success = dbus_g_proxy_call (proxy, "Open", &error,
G_TYPE_STRV, arg,
G_TYPE_INVALID, G_TYPE_INVALID);
if (! filenames)
g_free (arg);
g_object_unref (proxy);
dbus_g_connection_unref (connection);
if (success)
{
if (be_verbose)
g_print ("Found another GIMP instance, using that.\n");
return EXIT_SUCCESS;
}
if (error->domain == DBUS_GERROR &&
error->code == DBUS_GERROR_REMOTE_EXCEPTION)
{
g_printerr ("Caught remote method exception %s: %s",
dbus_g_error_get_name (error),
error->message);
}
else if (! (error->domain == DBUS_GERROR &&
error->code == DBUS_GERROR_SERVICE_UNKNOWN))
{
g_printerr ("Error: %s\n", error->message);
}
g_clear_error (&error);
}
}
#endif
#endif
abort_message = sanity_check ();
if (abort_message)
app_abort (no_interface, abort_message);

View File

@ -11,6 +11,7 @@ INCLUDES = \
-I$(top_srcdir)/app \
$(GTK_CFLAGS) \
$(PANGOFT2_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = libappwidgets.a
@ -106,6 +107,8 @@ libappwidgets_a_sources = \
gimpdataeditor.h \
gimpdatafactoryview.c \
gimpdatafactoryview.h \
gimpdbusservice.c \
gimpdbusservice.h \
gimpdeviceinfo.c \
gimpdeviceinfo.h \
gimpdevices.c \
@ -312,20 +315,30 @@ libappwidgets_a_sources = \
gtkvwrapbox.c \
gtkvwrapbox.h
libappwidgets_a_built_sources = widgets-enums.c
libappwidgets_a_built_sources = gimpdbusservice-glue.h widgets-enums.c
libappwidgets_a_SOURCES = \
$(libappwidgets_a_built_sources) $(libappwidgets_a_sources)
EXTRA_DIST = makefile.msc
EXTRA_DIST = \
dbus-service.xml \
makefile.msc
#
# rules to generate built sources
#
# setup autogeneration dependencies
gen_sources = xgen-wec
gen_sources = xgen-wec gimpdbusservice-glue.h
CLEANFILES = $(gen_sources)
$(srcdir)/gimpdbusservice.c: gimpdbusservice-glue.h
gimpdbusservice-glue.h: $(srcdir)/dbus-service.xml
$(DBUS_BINDING_TOOL) --mode=glib-server --prefix=gimp $< > $(@F)
$(srcdir)/widgets-enums.c: $(srcdir)/widgets-enums.h $(GIMP_MKENUMS)
$(GIMP_MKENUMS) \
--fhead "#include \"config.h\"\n#include <gtk/gtk.h>\n#include \"libgimpbase/gimpbase.h\"\n#include \"widgets-enums.h\"\n#include \"gimp-intl.h\"" \

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/org/gimp/GIMP">
<interface name="org.gimp.GIMP">
<annotation name="org.freedesktop.DBus.GLib.CSymbol"
value="gimp_dbus_service" />
<method name="Open">
<arg type="as" name="uri" direction="in" />
</method>
</interface>
</node>

View File

@ -0,0 +1,117 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpDBusService
* Copyright (C) 2007 Sven Neumann <sven@gimp.org>
*
* 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"
#if HAVE_DBUS_GLIB
#include <dbus/dbus-glib.h>
#include "core/core-types.h"
#include "core/gimp.h"
#include "file/file-open.h"
#include "file/file-utils.h"
#include "gimpdbusservice.h"
#include "gimpdbusservice-glue.h"
#include "gimpuimanager.c"
static void gimp_dbus_service_class_init (GimpDBusServiceClass *klass);
static void gimp_dbus_service_init (GimpDBusService *service);
G_DEFINE_TYPE (GimpDBusService, gimp_dbus_service, G_TYPE_OBJECT)
static void
gimp_dbus_service_class_init (GimpDBusServiceClass *klass)
{
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_gimp_object_info);
}
static void
gimp_dbus_service_init (GimpDBusService *service)
{
}
GObject *
gimp_dbus_service_new (Gimp *gimp)
{
GimpDBusService *service;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
service = g_object_new (GIMP_TYPE_DBUS_SERVICE, NULL);
service->gimp = gimp;
return G_OBJECT (service);
}
gboolean
gimp_dbus_service_open (GimpDBusService *service,
const gchar **uris,
GError **error)
{
gint i;
g_return_val_if_fail (GIMP_IS_DBUS_SERVICE (service), FALSE);
for (i = 0; uris[i]; i++)
{
GimpImage *image;
gchar *uri;
GimpPDBStatusType status;
/* the method is documented to take URIs but we also accept filenames */
uri = file_utils_any_to_uri (service->gimp, uris[i], error);
if (! uri)
return FALSE;
image = file_open_with_display (service->gimp,
gimp_get_user_context (service->gimp),
NULL,
uris[i],
&status, error);
g_free (uri);
if (! image && status != GIMP_PDB_CANCEL)
return FALSE;
}
/* if no URI is passed, raise the toolbox */
if (i == 0)
{
const GList *managers = gimp_ui_managers_from_name ("<Image>");
if (managers)
gimp_ui_manager_activate_action (managers->data,
"dialogs", "dialogs-toolbox");
}
return TRUE;
}
#endif /* HAVE_DBUS_GLIB */

View File

@ -0,0 +1,66 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpDBusService
* Copyright (C) 2007 Sven Neumann <sven@gimp.org>
*
* 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_DBUS_SERVICE_H__
#define __GIMP_DBUS_SERVICE_H__
G_BEGIN_DECLS
#define GIMP_DBUS_SERVICE_NAME "org.gimp.GIMP"
#define GIMP_DBUS_SERVICE_PATH "/org/gimp/GIMP"
#define GIMP_DBUS_SERVICE_INTERFACE "org.gimp.GIMP"
#define GIMP_TYPE_DBUS_SERVICE (gimp_dbus_service_get_type ())
#define GIMP_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DBUS_SERVICE, GimpDBusService))
#define GIMP_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DBUS_SERVICE, GimpDBusServiceClass))
#define GIMP_IS_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DBUS_SERVICE))
#define GIMP_IS_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DBUS_SERVICE))
#define GIMP_DBUS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DBUS_SERVICE, GimpDBusServiceClass))
typedef struct _GimpDBusService GimpDBusService;
typedef struct _GimpDBusServiceClass GimpDBusServiceClass;
struct _GimpDBusService
{
GObject parent_instance;
Gimp *gimp;
};
struct _GimpDBusServiceClass
{
GObjectClass parent_class;
};
GType gimp_dbus_service_get_type (void) G_GNUC_CONST;
GObject * gimp_dbus_service_new (Gimp *gimp);
gboolean gimp_dbus_service_open (GimpDBusService *service,
const gchar **uris,
GError **error);
G_END_DECLS
#endif /* __GIMP_DBUS_SERVICE_H__ */

View File

@ -56,6 +56,7 @@ m4_define([gnome_vfs_required_version], [2.10.0])
m4_define([gnomeui_required_version], [2.10.0])
m4_define([gnome_keyring_required_version], [0.4.5])
m4_define([libcurl_required_version], [7.15.1])
m4_define([dbus_glib_required_version], [0.71])
AC_INIT([GIMP], [gimp_version],
@ -903,9 +904,9 @@ if test "$gdk_target" = x11; then
dnl doc-shooter is X11 specific
DOC_SHOOTER=doc-shooter
dnl Test for Xmu
enable_gimp_remote=yes
if test -z "$LIBXMU"; then
dnl Test for Xmu
enable_gimp_remote=yes
if test -z "$LIBXMU"; then
gimp_save_CFLAGS="$CFLAGS"
gimp_save_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS $GTK_CFLAGS"
@ -921,7 +922,9 @@ if test "$gdk_target" = x11; then
CFLAGS="$gimp_save_CFLAGS"
LDFLAGS="$gimp_save_LDFLAGS"
LIBSCREENSHOT="$LIBXMU"
fi
fi
else
enable_gimp_remote="no (building for $gdk_target)"
fi
AC_SUBST(LIBXMU)
@ -1248,9 +1251,9 @@ if test "x$have_poppler" = xyes; then
fi
###################################################################
# Check for gnome-vfs (and optionally libgnomeui and gnome-keyring)
###################################################################
###############################################################################
# Check for gnome-vfs and libcurl (and optionally libgnomeui and gnome-keyring)
###############################################################################
uri_plugin=no
gnome_vfs_modules="gnome-vfs-2.0 >= gnome_vfs_required_version"
@ -1300,6 +1303,29 @@ if test "x$have_gnome_keyring" = xyes; then
fi
###############################
# Check for D-Bus glib bindings
###############################
have_dbus_glib=no
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= dbus_glib_required_version,
have_dbus_glib=yes)
if test "x$have_dbus_glib" = xyes; then
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
if test x$DBUS_BINDING_TOOL = xno; then
AC_MSG_WARN(Could not find dbus-binding-tool in your PATH)
have_dbus_glib="no (dbus-binding-tool not found)"
fi
fi
if test "x$have_dbus_glib" = xyes; then
AC_DEFINE(HAVE_DBUS_GLIB, 1,
[Define to 1 if D-Bus GLib bindings are available])
GIMP_COMMAND='gimp-gimp_app_version'
fi
###################
# Check for libwmf2
###################
@ -1898,6 +1924,9 @@ Extra Binaries:
gimp-console: $enable_gimp_console
gimp-remote: $enable_gimp_remote
Optional Features:
D-Bus service: $have_dbus_glib
Optional Plug-Ins:
Ascii Art: $have_libaa
Help Browser: $have_gtkhtml2