Replaced the netscape-dependent web browser plug-in with a user

2003-09-22 Henrik Brix Andersen <brix@gimp.org>

Replaced the netscape-dependent web browser plug-in with a user
configureable plug-in. This fixes bug #119120:

* app/config/gimpguiconfig.[ch]: added gchar *web_browser member

* app/config/gimprc-blurbs.h: added web browser blurb

* etc/gimprc
* docs/gimprc-1.3.5.in: regenerated using gimpconfig-dump

* app/gui/preferences-dialog.c (prefs_dialog_new): added UI for
specifying external web browser

* configure.in
* plug-ins/Makefile.am
* plug-ins/webbrowser/Makefile.am
* plug-ins/webbrowser/README
* plug-ins/webbrowser/web-browser.scm
* plug-ins/webbrowser/webbrowser.c : removed the old netscape-dependent
web browser plug-in

* po-plug-ins/POTFILES.in
* plug-ins/common/plugin-defs.pl
* plug-ins/common/webbrowser.c: added a new web browser plug-in

* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am: regenerated

* app/widgets/gimphelp.c
* app/widgets/widget-enums.[ch]
* plug-ins/helpbrowser/dialog.c
* plug-ins/maze/maze_face.c: changed accordingly + whitespace
clean-up

* po-script-fu/POTFILES.in
* plug-ins/script-fu/scripts/Makefile.am
* plug-ins/script-fu/scripts/web-browser.scm: use the new web
browser plug-in to add menu entries to <Toolbox>/Help/
This commit is contained in:
Henrik Brix Andersen 2003-09-22 20:04:39 +00:00 committed by Henrik Brix Andersen
parent c9ef4b23f7
commit 9b3bc08eb6
28 changed files with 482 additions and 1405 deletions

View file

@ -1,3 +1,44 @@
2003-09-22 Henrik Brix Andersen <brix@gimp.org>
Replaced the netscape-dependent web browser plug-in with a user
configureable plug-in. This fixes bug #119120:
* app/config/gimpguiconfig.[ch]: added gchar *web_browser member
* app/config/gimprc-blurbs.h: added web browser blurb
* etc/gimprc
* docs/gimprc-1.3.5.in: regenerated using gimpconfig-dump
* app/gui/preferences-dialog.c (prefs_dialog_new): added UI for
specifying external web browser
* configure.in
* plug-ins/Makefile.am
* plug-ins/webbrowser/Makefile.am
* plug-ins/webbrowser/README
* plug-ins/webbrowser/web-browser.scm
* plug-ins/webbrowser/webbrowser.c : removed the old netscape-dependent
web browser plug-in
* po-plug-ins/POTFILES.in
* plug-ins/common/plugin-defs.pl
* plug-ins/common/webbrowser.c: added a new web browser plug-in
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am: regenerated
* app/widgets/gimphelp.c
* app/widgets/widget-enums.[ch]
* plug-ins/helpbrowser/dialog.c
* plug-ins/maze/maze_face.c: changed accordingly + whitespace
clean-up
* po-script-fu/POTFILES.in
* plug-ins/script-fu/scripts/Makefile.am
* plug-ins/script-fu/scripts/web-browser.scm: use the new web
browser plug-in to add menu entries to <Toolbox>/Help/
2003-09-22 Sven Neumann <sven@gimp.org> 2003-09-22 Sven Neumann <sven@gimp.org>
* app/gui/menus.c (menus_restore) (menus_save): removed gimprc * app/gui/menus.c (menus_restore) (menus_save): removed gimprc

View file

@ -49,7 +49,13 @@ static void gimp_gui_config_get_property (GObject *object,
GParamSpec *pspec); GParamSpec *pspec);
#define DEFAULT_THEME "Default" #define DEFAULT_THEME "Default"
#ifdef G_OS_WIN32
#define DEFAULT_WEB_BROWSER "\"C:\Program Files\Internet Explorer\iexplore.exe\" \"%s\""
#else
#define DEFAULT_WEB_BROWSER "mozilla \"%s\""
#endif
enum enum
{ {
@ -73,13 +79,14 @@ enum
PROP_THEME_PATH, PROP_THEME_PATH,
PROP_THEME, PROP_THEME,
PROP_USE_HELP, PROP_USE_HELP,
PROP_HELP_BROWSER PROP_HELP_BROWSER,
PROP_WEB_BROWSER
}; };
static GObjectClass *parent_class = NULL; static GObjectClass *parent_class = NULL;
GType GType
gimp_gui_config_get_type (void) gimp_gui_config_get_type (void)
{ {
static GType config_type = 0; static GType config_type = 0;
@ -99,8 +106,8 @@ gimp_gui_config_get_type (void)
NULL /* instance_init */ NULL /* instance_init */
}; };
config_type = g_type_register_static (GIMP_TYPE_DISPLAY_CONFIG, config_type = g_type_register_static (GIMP_TYPE_DISPLAY_CONFIG,
"GimpGuiConfig", "GimpGuiConfig",
&config_info, 0); &config_info, 0);
} }
@ -207,6 +214,11 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
GIMP_TYPE_HELP_BROWSER_TYPE, GIMP_TYPE_HELP_BROWSER_TYPE,
GIMP_HELP_BROWSER_GIMP, GIMP_HELP_BROWSER_GIMP,
0); 0);
GIMP_CONFIG_INSTALL_PROP_PATH (object_class, PROP_WEB_BROWSER,
"web-browser", WEB_BROWSER_BLURB,
GIMP_PARAM_PATH_FILE,
DEFAULT_WEB_BROWSER,
0);
} }
static void static void
@ -215,9 +227,10 @@ gimp_gui_config_finalize (GObject *object)
GimpGuiConfig *gui_config; GimpGuiConfig *gui_config;
gui_config = GIMP_GUI_CONFIG (object); gui_config = GIMP_GUI_CONFIG (object);
g_free (gui_config->theme_path); g_free (gui_config->theme_path);
g_free (gui_config->theme); g_free (gui_config->theme);
g_free (gui_config->web_browser);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -245,7 +258,7 @@ gimp_gui_config_set_property (GObject *object,
break; break;
case PROP_INFO_WINDOW_PER_DISPLAY: case PROP_INFO_WINDOW_PER_DISPLAY:
gui_config->info_window_per_display = g_value_get_boolean (value); gui_config->info_window_per_display = g_value_get_boolean (value);
break; break;
case PROP_TRUST_DIRTY_FLAG: case PROP_TRUST_DIRTY_FLAG:
gui_config->trust_dirty_flag = g_value_get_boolean (value); gui_config->trust_dirty_flag = g_value_get_boolean (value);
break; break;
@ -296,6 +309,10 @@ gimp_gui_config_set_property (GObject *object,
case PROP_HELP_BROWSER: case PROP_HELP_BROWSER:
gui_config->help_browser = g_value_get_enum (value); gui_config->help_browser = g_value_get_enum (value);
break; break;
case PROP_WEB_BROWSER:
g_free (gui_config->web_browser);
gui_config->web_browser = g_value_dup_string (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -375,6 +392,9 @@ gimp_gui_config_get_property (GObject *object,
case PROP_HELP_BROWSER: case PROP_HELP_BROWSER:
g_value_set_enum (value, gui_config->help_browser); g_value_set_enum (value, gui_config->help_browser);
break; break;
case PROP_WEB_BROWSER:
g_value_set_string (value, gui_config->web_browser);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

View file

@ -60,6 +60,7 @@ struct _GimpGuiConfig
gchar *theme; gchar *theme;
gboolean use_help; gboolean use_help;
GimpHelpBrowserType help_browser; GimpHelpBrowserType help_browser;
gchar *web_browser;
gint last_tip; /* saved in sessionrc */ gint last_tip; /* saved in sessionrc */
}; };

View file

@ -358,5 +358,12 @@ N_("Sets an upper limit to the memory that is used per image to keep " \
#define USE_HELP_BLURB \ #define USE_HELP_BLURB \
N_("When enabled, pressing F1 will open the help browser.") N_("When enabled, pressing F1 will open the help browser.")
#define WEB_BROWSER_BLURB \
N_("Sets the external web browser to be used. This can be an absolute " \
"path or the name of an executable to search for in the user's PATH. " \
"If the command contains '%s' it will be replaced with the URL, else " \
"the URL will be appended to the command with a space separating the " \
"two.")
#endif /* __GIMP_RC_BLURBS_H__ */ #endif /* __GIMP_RC_BLURBS_H__ */

View file

@ -1854,7 +1854,20 @@ prefs_dialog_new (Gimp *gimp,
prefs_enum_option_menu_add (config, "thumbnail-size", 0, 0, prefs_enum_option_menu_add (config, "thumbnail-size", 0, 0,
_("Size of Thumbnail Files:"), _("Size of Thumbnail Files:"),
GTK_TABLE (table), 1); GTK_TABLE (table), 1);
/* External Browser */
vbox2 = prefs_frame_new (_("Web Browser"), GTK_CONTAINER (vbox), FALSE);
table = prefs_table_new (1, GTK_CONTAINER (vbox2), FALSE);
fileselection = gimp_prop_file_entry_new (config, "web-browser",
_("Select Web Browser"),
FALSE, FALSE);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Web Browser to Use:"), 1.0, 0.5,
fileselection, 1, TRUE);
/* Rescan Font List */
vbox2 = prefs_frame_new (_("Fonts"), GTK_CONTAINER (vbox), FALSE); vbox2 = prefs_frame_new (_("Fonts"), GTK_CONTAINER (vbox), FALSE);
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 2);

View file

@ -1854,7 +1854,20 @@ prefs_dialog_new (Gimp *gimp,
prefs_enum_option_menu_add (config, "thumbnail-size", 0, 0, prefs_enum_option_menu_add (config, "thumbnail-size", 0, 0,
_("Size of Thumbnail Files:"), _("Size of Thumbnail Files:"),
GTK_TABLE (table), 1); GTK_TABLE (table), 1);
/* External Browser */
vbox2 = prefs_frame_new (_("Web Browser"), GTK_CONTAINER (vbox), FALSE);
table = prefs_table_new (1, GTK_CONTAINER (vbox2), FALSE);
fileselection = gimp_prop_file_entry_new (config, "web-browser",
_("Select Web Browser"),
FALSE, FALSE);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Web Browser to Use:"), 1.0, 0.5,
fileselection, 1, TRUE);
/* Rescan Font List */
vbox2 = prefs_frame_new (_("Fonts"), GTK_CONTAINER (vbox), FALSE); vbox2 = prefs_frame_new (_("Fonts"), GTK_CONTAINER (vbox), FALSE);
hbox = gtk_hbox_new (FALSE, 2); hbox = gtk_hbox_new (FALSE, 2);

View file

@ -66,15 +66,15 @@ struct _GimpIdleHelp
/* local function prototypes */ /* local function prototypes */
static gint gimp_idle_help (gpointer data); static gint gimp_idle_help (gpointer data);
static gboolean gimp_help_internal (Gimp *gimp, static gboolean gimp_help_internal (Gimp *gimp,
const gchar *help_domain, const gchar *help_domain,
const gchar *help_locale, const gchar *help_locale,
const gchar *help_id); const gchar *help_id);
static void gimp_help_netscape (Gimp *gimp, static void gimp_help_webbrowser (Gimp *gimp,
const gchar *help_domain, const gchar *help_domain,
const gchar *help_locale, const gchar *help_locale,
const gchar *help_id); const gchar *help_id);
/* public functions */ /* public functions */
@ -142,11 +142,11 @@ gimp_idle_help (gpointer data)
idle_help->help_id)) idle_help->help_id))
break; break;
case GIMP_HELP_BROWSER_NETSCAPE: case GIMP_HELP_BROWSER_WEBBROWSER:
gimp_help_netscape (idle_help->gimp, gimp_help_webbrowser (idle_help->gimp,
idle_help->help_domain, idle_help->help_domain,
idle_help->help_locale, idle_help->help_locale,
idle_help->help_id); idle_help->help_id);
break; break;
default: default:
@ -163,16 +163,16 @@ gimp_idle_help (gpointer data)
static void static void
gimp_help_internal_not_found_callback (GtkWidget *widget, gimp_help_internal_not_found_callback (GtkWidget *widget,
gboolean use_netscape, gboolean use_webbrowser,
gpointer data) gpointer data)
{ {
Gimp *gimp = GIMP (data); Gimp *gimp = GIMP (data);
if (use_netscape) if (use_webbrowser)
g_object_set (gimp->config, g_object_set (gimp->config,
"help-browser", GIMP_HELP_BROWSER_NETSCAPE, "help-browser", GIMP_HELP_BROWSER_WEBBROWSER,
NULL); NULL);
gtk_main_quit (); gtk_main_quit ();
} }
@ -211,7 +211,7 @@ gimp_help_internal (Gimp *gimp,
_("Could not find the GIMP Help Browser procedure.\n" _("Could not find the GIMP Help Browser procedure.\n"
"It probably was not compiled because\n" "It probably was not compiled because\n"
"you don't have GtkXmHTML installed."), "you don't have GtkXmHTML installed."),
_("Use Netscape instead"), _("Use web browser instead"),
GTK_STOCK_CANCEL, GTK_STOCK_CANCEL,
NULL, NULL, NULL, NULL,
gimp_help_internal_not_found_callback, gimp_help_internal_not_found_callback,
@ -222,7 +222,7 @@ gimp_help_internal (Gimp *gimp,
busy = FALSE; busy = FALSE;
return (GIMP_GUI_CONFIG (gimp->config)->help_browser return (GIMP_GUI_CONFIG (gimp->config)->help_browser
!= GIMP_HELP_BROWSER_NETSCAPE); != GIMP_HELP_BROWSER_WEBBROWSER);
} }
n_domains = plug_ins_help_domains (gimp, &help_domains, &help_uris); n_domains = plug_ins_help_domains (gimp, &help_domains, &help_uris);
@ -253,7 +253,7 @@ gimp_help_internal (Gimp *gimp,
gimp_query_boolean_box (_("Could not start GIMP Help Browser"), gimp_query_boolean_box (_("Could not start GIMP Help Browser"),
NULL, NULL, FALSE, NULL, NULL, FALSE,
_("Could not start the GIMP Help Browser."), _("Could not start the GIMP Help Browser."),
_("Use Netscape instead"), _("Use web browser instead"),
GTK_STOCK_CANCEL, GTK_STOCK_CANCEL,
NULL, NULL, NULL, NULL,
gimp_help_internal_not_found_callback, gimp_help_internal_not_found_callback,
@ -264,7 +264,7 @@ gimp_help_internal (Gimp *gimp,
busy = FALSE; busy = FALSE;
return (GIMP_GUI_CONFIG (gimp->config)->help_browser return (GIMP_GUI_CONFIG (gimp->config)->help_browser
!= GIMP_HELP_BROWSER_NETSCAPE); != GIMP_HELP_BROWSER_WEBBROWSER);
} }
else else
{ {
@ -289,10 +289,10 @@ gimp_help_internal (Gimp *gimp,
} }
static void static void
gimp_help_netscape (Gimp *gimp, gimp_help_webbrowser (Gimp *gimp,
const gchar *help_domain, const gchar *help_domain,
const gchar *help_locale, const gchar *help_locale,
const gchar *help_id) const gchar *help_id)
{ {
Argument *return_vals; Argument *return_vals;
gint nreturn_vals; gint nreturn_vals;
@ -322,9 +322,7 @@ gimp_help_netscape (Gimp *gimp,
procedural_db_run_proc (gimp, procedural_db_run_proc (gimp,
"plug_in_web_browser", "plug_in_web_browser",
&nreturn_vals, &nreturn_vals,
GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
GIMP_PDB_STRING, url, GIMP_PDB_STRING, url,
GIMP_PDB_INT32, FALSE,
GIMP_PDB_END); GIMP_PDB_END);
procedural_db_destroy_args (return_vals, nreturn_vals); procedural_db_destroy_args (return_vals, nreturn_vals);

View file

@ -31,7 +31,7 @@ gimp_aspect_type_get_type (void)
static const GEnumValue gimp_help_browser_type_enum_values[] = static const GEnumValue gimp_help_browser_type_enum_values[] =
{ {
{ GIMP_HELP_BROWSER_GIMP, N_("Internal"), "gimp" }, { GIMP_HELP_BROWSER_GIMP, N_("Internal"), "gimp" },
{ GIMP_HELP_BROWSER_NETSCAPE, N_("Netscape"), "netscape" }, { GIMP_HELP_BROWSER_WEBBROWSER, N_("Web Browser"), "webbrowser" },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };

View file

@ -20,7 +20,7 @@
#define __WIDGETS_ENUMS_H__ #define __WIDGETS_ENUMS_H__
/* /*
* these enums that are registered with the type system * these enums that are registered with the type system
*/ */
@ -42,8 +42,8 @@ GType gimp_help_browser_type_get_type (void) G_GNUC_CONST;
typedef enum typedef enum
{ {
GIMP_HELP_BROWSER_GIMP, /*< desc="Internal" >*/ GIMP_HELP_BROWSER_GIMP, /*< desc="Internal" >*/
GIMP_HELP_BROWSER_NETSCAPE /*< desc="Netscape" >*/ GIMP_HELP_BROWSER_WEBBROWSER /*< desc="Web Browser" >*/
} GimpHelpBrowserType; } GimpHelpBrowserType;

View file

@ -683,14 +683,14 @@ if test "$gdk_target" = x11; then
GIMP_REMOTE='gimp-remote-1.3'; GIMP_REMOTE='gimp-remote-1.3';
have_libxmu=yes have_libxmu=yes
LIBXMU="$X_LIBS $X_PRE_LIBS -lX11 -lXmu -lXt", LIBXMU="$X_LIBS $X_PRE_LIBS -lX11 -lXmu -lXt",
[AC_MSG_WARN(*** webbrowser plug-in and gimp-remote will not be built (XMU header file not found) ***)])], [AC_MSG_WARN(*** gimp-remote will not be built (XMU header file not found) ***)])],
[AC_CHECK_LIB(Xmu, XmuUpdateMapHints, [AC_CHECK_LIB(Xmu, XmuUpdateMapHints,
[AC_CHECK_HEADER(X11/Xmu/WinUtil.h, [AC_CHECK_HEADER(X11/Xmu/WinUtil.h,
GIMP_REMOTE='gimp-remote-1.3'; GIMP_REMOTE='gimp-remote-1.3';
have_libxmu=yes have_libxmu=yes
LIBXMU="$X_LIBS $X_PRE_LIBS -lX11 -lXmu -lXt", LIBXMU="$X_LIBS $X_PRE_LIBS -lX11 -lXmu -lXt",
[AC_MSG_WARN(*** webbrowser plug-in and gimp-remote will not be built (XMU header file not found) ***)])], [AC_MSG_WARN(*** gimp-remote will not be built (XMU header file not found) ***)])],
AC_MSG_WARN(*** webbrowser plug-in and gimp-remote will not be built (XMU library not found) ***), -lXt)], -lXt) AC_MSG_WARN(*** gimp-remote will not be built (XMU library not found) ***), -lXt)], -lXt)
CFLAGS="$gimp_save_CFLAGS" CFLAGS="$gimp_save_CFLAGS"
LDFLAGS="$gimp_save_LDFLAGS" LDFLAGS="$gimp_save_LDFLAGS"
fi fi
@ -703,10 +703,6 @@ AC_SUBST(LIBXMU)
AC_SUBST(LIBSCREENSHOT) AC_SUBST(LIBSCREENSHOT)
AC_SUBST(GIMP_REMOTE) AC_SUBST(GIMP_REMOTE)
## webbrowser has ifdefs for Win32
AM_CONDITIONAL(BUILD_WEBBROWSER,
test x"$have_libxmu" = xyes || test x"$os_win32" = xyes)
################### ###################
# Check for libtiff # Check for libtiff
@ -1322,7 +1318,6 @@ plug-ins/libgck/gck/Makefile
plug-ins/dbbrowser/Makefile plug-ins/dbbrowser/Makefile
plug-ins/script-fu/Makefile plug-ins/script-fu/Makefile
plug-ins/script-fu/scripts/Makefile plug-ins/script-fu/scripts/Makefile
plug-ins/webbrowser/Makefile
plug-ins/xjt/Makefile plug-ins/xjt/Makefile
plug-ins/FractalExplorer/Makefile plug-ins/FractalExplorer/Makefile
plug-ins/FractalExplorer/fractalexplorer-examples/Makefile plug-ins/FractalExplorer/fractalexplorer-examples/Makefile

View file

@ -672,7 +672,15 @@ and no.
(help-browser gimp) (help-browser gimp)
Sets the browser used by the help system. Possible values are gimp and Sets the browser used by the help system. Possible values are gimp and
netscape. webbrowser.
.TP
(web-browser "mozilla \"%s\"")
Sets the external web browser to be used. This can be an absolute path or the
name of an executable to search for in the user's PATH. If the command
contains '%s' it will be replaced with the URL, else the URL will be appended
to the command with a space separating the two. This is a single filename.
.TP .TP
(fractalexplorer-path "${gimp_dir}/fractalexplorer:${gimp_data_dir}/fractalexplorer") (fractalexplorer-path "${gimp_dir}/fractalexplorer:${gimp_data_dir}/fractalexplorer")

View file

@ -672,7 +672,15 @@ and no.
(help-browser gimp) (help-browser gimp)
Sets the browser used by the help system. Possible values are gimp and Sets the browser used by the help system. Possible values are gimp and
netscape. webbrowser.
.TP
(web-browser "mozilla \"%s\"")
Sets the external web browser to be used. This can be an absolute path or the
name of an executable to search for in the user's PATH. If the command
contains '%s' it will be replaced with the URL, else the URL will be appended
to the command with a space separating the two. This is a single filename.
.TP .TP
(fractalexplorer-path "${gimp_dir}/fractalexplorer:${gimp_data_dir}/fractalexplorer") (fractalexplorer-path "${gimp_dir}/fractalexplorer:${gimp_data_dir}/fractalexplorer")

View file

@ -524,10 +524,18 @@
# (use-help yes) # (use-help yes)
# Sets the browser used by the help system. Possible values are gimp and # Sets the browser used by the help system. Possible values are gimp and
# netscape. # webbrowser.
# #
# (help-browser gimp) # (help-browser gimp)
# Sets the external web browser to be used. This can be an absolute path or
# the name of an executable to search for in the user's PATH. If the command
# contains '%s' it will be replaced with the URL, else the URL will be
# appended to the command with a space separating the two. This is a single
# filename.
#
# (web-browser "mozilla \"%s\"")
# Where to search for fractals used by the Fractal Explorer plug-in. This is # Where to search for fractals used by the Fractal Explorer plug-in. This is
# a colon-separated list of folders to search. # a colon-separated list of folders to search.
# #

View file

@ -15,10 +15,6 @@ if BUILD_HELPBROWSER
helpbrowser = helpbrowser helpbrowser = helpbrowser
endif endif
if BUILD_WEBBROWSER
webbrowser = webbrowser
endif
if BUILD_XJT if BUILD_XJT
xjt = xjt xjt = xjt
endif endif
@ -57,7 +53,6 @@ SUBDIRS = \
rcm \ rcm \
sgi \ sgi \
sel2path \ sel2path \
$(webbrowser) \
$(win32dirs) \ $(win32dirs) \
$(xjt) \ $(xjt) \
common common

View file

@ -127,6 +127,7 @@ vinvert
vpropagate vpropagate
warp warp
waves waves
webbrowser
whirlpinch whirlpinch
winclipboard winclipboard
wind wind

View file

@ -146,6 +146,7 @@ libexec_PROGRAMS = \
vpropagate \ vpropagate \
warp \ warp \
waves \ waves \
webbrowser \
whirlpinch \ whirlpinch \
$(WINCLIPBOARD) \ $(WINCLIPBOARD) \
wind \ wind \
@ -1660,6 +1661,16 @@ waves_LDADD = \
@GTK_LIBS@ \ @GTK_LIBS@ \
@INTLLIBS@ @INTLLIBS@
webbrowser_SOURCES = \
webbrowser.c
webbrowser_LDADD = \
$(top_builddir)/libgimp/libgimp-$(LT_RELEASE).la \
$(top_builddir)/libgimpcolor/libgimpcolor-$(LT_RELEASE).la \
$(top_builddir)/libgimpbase/libgimpbase-$(LT_RELEASE).la \
@GLIB_LIBS@ \
@INTLLIBS@
whirlpinch_SOURCES = \ whirlpinch_SOURCES = \
whirlpinch.c whirlpinch.c

View file

@ -124,6 +124,7 @@
'vpropagate' => { libdep => 'gtk', ui => 1 }, 'vpropagate' => { libdep => 'gtk', ui => 1 },
'warp' => { libdep => 'gtk', ui => 1 }, 'warp' => { libdep => 'gtk', ui => 1 },
'waves' => { libdep => 'gtk', ui => 1 }, 'waves' => { libdep => 'gtk', ui => 1 },
'webbrowser' => { libdep => 'glib' },
'whirlpinch' => { libdep => 'gtk', ui => 1 }, 'whirlpinch' => { libdep => 'gtk', ui => 1 },
'winclipboard' => { libdep => 'glib', ui => 1, optional => 1 }, 'winclipboard' => { libdep => 'glib', ui => 1, optional => 1 },
'wind' => { libdep => 'gtk', ui => 1 }, 'wind' => { libdep => 'gtk', ui => 1 },

View file

@ -0,0 +1,186 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Web Browser Plug-in
* Copyright (C) 2003 Henrik Brix Andersen <brix@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"
#include <string.h> /* strlen, strstr */
#include <glib.h>
#include <libgimp/gimp.h>
#include "libgimp/stdplugins-intl.h"
#define PLUG_IN_NAME "plug_in_web_browser"
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gboolean browser_open_url (const gchar *url);
static gchar* strreplace (const gchar *string,
const gchar *delimiter,
const gchar *replacement);
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run /* run_proc */
};
MAIN ()
static void
query (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_STRING, "url", "URL to open" }
};
gimp_install_procedure (PLUG_IN_NAME,
"Open an URL in the user specified web browser",
"Opens the given URL in the user specified web browser.",
"Henrik Brix Andersen <brix@gimp.org>",
"2003",
"2003/09/16",
NULL, NULL,
GIMP_PLUGIN,
G_N_ELEMENTS (args), 0,
args, NULL);
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpRunMode run_mode;
GimpPDBStatusType status;
run_mode = param[0].data.d_int32;
status = GIMP_PDB_SUCCESS;
INIT_I18N ();
if (nparams == 1 &&
param[0].data.d_string != NULL &&
strlen (param[0].data.d_string))
{
if (! browser_open_url (param[0].data.d_string))
status = GIMP_PDB_EXECUTION_ERROR;
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
*nreturn_vals = 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
}
static gboolean
browser_open_url (const gchar *url)
{
GError *error = NULL;
gchar *browser;
gchar *cmd;
gchar **argv;
gboolean retval;
g_return_val_if_fail (url != NULL, FALSE);
browser = gimp_gimprc_query ("web-browser");
if (browser == NULL || ! strlen (browser))
{
g_message (_("Web browser not specified.\n"
"Please specify a web browser using the Preferences Dialog."));
g_free (browser);
return FALSE;
}
/* replace %s with URL */
if (strstr (browser, "%s"))
cmd = strreplace (browser, "%s", url);
else
cmd = g_strconcat (browser, " ", url, NULL);
/* parse the cmd line */
if (! g_shell_parse_argv (cmd, NULL, &argv, &error))
{
g_message (_("Could not parse specified web browser command:\n%s"),
error->message);
g_error_free (error);
return FALSE;
}
retval = g_spawn_async (NULL, argv, NULL,
G_SPAWN_SEARCH_PATH,
NULL, NULL,
NULL, &error);
if (! retval)
{
g_message (_("Could not execute specified web browser:\n%s"),
error->message);
g_error_free (error);
}
g_free (browser);
g_free (cmd);
g_strfreev (argv);
return retval;
}
static gchar*
strreplace (const gchar *string,
const gchar *delimiter,
const gchar *replacement)
{
gchar *ret;
gchar **tmp;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (delimiter != NULL, NULL);
g_return_val_if_fail (replacement != NULL, NULL);
tmp = g_strsplit (string, delimiter, 0);
ret = g_strjoinv (replacement, tmp);
g_strfreev (tmp);
return ret;
}

View file

@ -619,12 +619,10 @@ load_remote_page (const gchar *ref)
GimpParam *return_vals; GimpParam *return_vals;
gint nreturn_vals; gint nreturn_vals;
/* try to call netscape through the web_browser interface */ /* try to call the user specified web browser */
return_vals = gimp_run_procedure ("plug_in_web_browser", return_vals = gimp_run_procedure ("plug_in_web_browser",
&nreturn_vals, &nreturn_vals,
GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
GIMP_PDB_STRING, ref, GIMP_PDB_STRING, ref,
GIMP_PDB_INT32, FALSE,
GIMP_PDB_END); GIMP_PDB_END);
gimp_destroy_params (return_vals, nreturn_vals); gimp_destroy_params (return_vals, nreturn_vals);
} }

View file

@ -1,8 +1,8 @@
/* -*- mode: C; c-file-style: "gnu"; c-basic-offset: 2; -*- */ /* -*- mode: C; c-file-style: "gnu"; c-basic-offset: 2; -*- */
/* $Id$ /* $Id$
* User interface for plug-in-maze. * User interface for plug-in-maze.
* *
* Implemented as a GIMP 0.99 Plugin by * Implemented as a GIMP 0.99 Plugin by
* Kevin Turner <acapnotic@users.sourceforge.net> * Kevin Turner <acapnotic@users.sourceforge.net>
* http://gimp-plug-ins.sourceforge.net/maze/ * http://gimp-plug-ins.sourceforge.net/maze/
*/ */
@ -43,7 +43,7 @@
#define ENTRY_WIDTH 75 #define ENTRY_WIDTH 75
/* entscale stuff begin */ /* entscale stuff begin */
/* FIXME: Entry-Scale stuff is probably in libgimpui by now. /* FIXME: Entry-Scale stuff is probably in libgimpui by now.
Should use that instead.*/ Should use that instead.*/
/* Indeed! By using the gimp_scale_entry you could get along without the /* Indeed! By using the gimp_scale_entry you could get along without the
EntscaleIntData structure, since it has accessors to all objects (Sven) */ EntscaleIntData structure, since it has accessors to all objects (Sven) */
@ -68,7 +68,7 @@ typedef struct
/* one buffer fits all */ /* one buffer fits all */
#define BUFSIZE 128 #define BUFSIZE 128
gchar buffer[BUFSIZE]; gchar buffer[BUFSIZE];
@ -124,7 +124,7 @@ static void maze_entry_callback (GtkWidget *widget,
signal_handler_block_by_name? signal_handler_block_by_name?
That would make life so much nicer. That would make life so much nicer.
You could pass the handler_id around and use You could pass the handler_id around and use
gtk_signal_handler_block (). (Sven) gtk_signal_handler_block (). (Sven)
*/ */
@ -133,17 +133,17 @@ static void div_entry_callback (GtkWidget *entry, GtkWidget *friend);
static void height_width_callback (gint width, GtkWidget **div_entry); static void height_width_callback (gint width, GtkWidget **div_entry);
static GtkWidget* divbox_new (guint *max, static GtkWidget* divbox_new (guint *max,
GtkWidget *friend, GtkWidget *friend,
GtkWidget **div_entry); GtkWidget **div_entry);
#if 0 #if 0
static void div_buttonl_callback (GtkObject *object); static void div_buttonl_callback (GtkObject *object);
static void div_buttonr_callback (GtkObject *object); static void div_buttonr_callback (GtkObject *object);
#endif #endif
/* entscale stuff begin */ /* entscale stuff begin */
static GtkWidget* entscale_int_new ( GtkWidget *table, gint x, gint y, static GtkWidget* entscale_int_new ( GtkWidget *table, gint x, gint y,
gchar *caption, gint *intvar, gchar *caption, gint *intvar,
gint min, gint max, gboolean constraint, gint min, gint max, gboolean constraint,
EntscaleIntCallbackFunc callback, EntscaleIntCallbackFunc callback,
gpointer data ); gpointer data );
@ -165,7 +165,7 @@ static gint maze_run = FALSE;
static GtkWidget *msg_label; static GtkWidget *msg_label;
gint gint
maze_dialog (void) maze_dialog (void)
{ {
GtkWidget *dlg; GtkWidget *dlg;
GtkWidget *frame; GtkWidget *frame;
@ -182,7 +182,7 @@ maze_dialog (void)
gimp_ui_init ("maze", FALSE); gimp_ui_init ("maze", FALSE);
dlg = gimp_dialog_new (MAZE_TITLE, "maze", dlg = gimp_dialog_new (MAZE_TITLE, "maze",
gimp_standard_help_func, "filters/maze.html", gimp_standard_help_func, "filters/maze.html",
GTK_WIN_POS_MOUSE, GTK_WIN_POS_MOUSE,
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE,
@ -206,21 +206,21 @@ maze_dialog (void)
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_set_border_width (GTK_CONTAINER(frame), 6); gtk_container_set_border_width (GTK_CONTAINER(frame), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), frame, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), frame, TRUE, TRUE, 0);
#ifdef SHOW_PRNG_PRIVATES #ifdef SHOW_PRNG_PRIVATES
table = gtk_table_new (8, 3, FALSE); table = gtk_table_new (8, 3, FALSE);
#else #else
table = gtk_table_new (6, 3, FALSE); table = gtk_table_new (6, 3, FALSE);
#endif #endif
gtk_table_set_col_spacings (GTK_TABLE (table), 4); gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_container_set_border_width (GTK_CONTAINER (table), 4); gtk_container_set_border_width (GTK_CONTAINER (table), 4);
gtk_container_add (GTK_CONTAINER (frame), table); gtk_container_add (GTK_CONTAINER (frame), table);
/* entscale == Entry and Scale pair function found in pixelize.c */ /* entscale == Entry and Scale pair function found in pixelize.c */
width_entry = entscale_int_new (table, 0, trow, _("Width (Pixels):"), width_entry = entscale_int_new (table, 0, trow, _("Width (Pixels):"),
&mvals.width, &mvals.width,
1, sel_w/4, TRUE, 1, sel_w/4, TRUE,
(EntscaleIntCallbackFunc) height_width_callback, (EntscaleIntCallbackFunc) height_width_callback,
&div_x_entry); &div_x_entry);
trow++; trow++;
@ -229,15 +229,15 @@ maze_dialog (void)
div_x_hbox = divbox_new (&sel_w, width_entry, &div_x_entry); div_x_hbox = divbox_new (&sel_w, width_entry, &div_x_entry);
g_snprintf (buffer, BUFSIZE, "%d", (sel_w / mvals.width)); g_snprintf (buffer, BUFSIZE, "%d", (sel_w / mvals.width));
gtk_entry_set_text (GTK_ENTRY (div_x_entry), buffer); gtk_entry_set_text (GTK_ENTRY (div_x_entry), buffer);
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
_("Pieces:"), 1.0, 0.5, _("Pieces:"), 1.0, 0.5,
div_x_hbox, 1, FALSE); div_x_hbox, 1, FALSE);
gtk_table_set_row_spacing (GTK_TABLE (table), trow, 8); gtk_table_set_row_spacing (GTK_TABLE (table), trow, 8);
trow++; trow++;
height_entry = entscale_int_new (table, 0, trow, _("Height (Pixels):"), height_entry = entscale_int_new (table, 0, trow, _("Height (Pixels):"),
&mvals.height, &mvals.height,
1, sel_h/4, TRUE, 1, sel_h/4, TRUE,
(EntscaleIntCallbackFunc) height_width_callback, (EntscaleIntCallbackFunc) height_width_callback,
&div_y_entry); &div_y_entry);
trow++; trow++;
@ -245,7 +245,7 @@ maze_dialog (void)
div_y_hbox = divbox_new (&sel_h, height_entry, &div_y_entry); div_y_hbox = divbox_new (&sel_h, height_entry, &div_y_entry);
g_snprintf (buffer, BUFSIZE, "%d", (sel_h / mvals.height)); g_snprintf (buffer, BUFSIZE, "%d", (sel_h / mvals.height));
gtk_entry_set_text (GTK_ENTRY (div_y_entry), buffer); gtk_entry_set_text (GTK_ENTRY (div_y_entry), buffer);
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
_("Pieces:"), 1.0, 0.5, _("Pieces:"), 1.0, 0.5,
div_y_hbox, 1, FALSE); div_y_hbox, 1, FALSE);
gtk_table_set_row_spacing (GTK_TABLE (table), trow, 8); gtk_table_set_row_spacing (GTK_TABLE (table), trow, 8);
@ -257,7 +257,7 @@ maze_dialog (void)
gtk_widget_set_size_request (entry, ENTRY_WIDTH, -1); gtk_widget_set_size_request (entry, ENTRY_WIDTH, -1);
g_snprintf (buffer, BUFSIZE, "%d", mvals.multiple); g_snprintf (buffer, BUFSIZE, "%d", mvals.multiple);
gtk_entry_set_text (GTK_ENTRY (entry), buffer ); gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
_("Multiple (57):"), 1.0, 0.5, _("Multiple (57):"), 1.0, 0.5,
entry, 1, FALSE); entry, 1, FALSE);
trow++; trow++;
@ -270,7 +270,7 @@ maze_dialog (void)
gtk_widget_set_size_request (entry, ENTRY_WIDTH, -1); gtk_widget_set_size_request (entry, ENTRY_WIDTH, -1);
g_snprintf (buffer, BUFSIZE, "%d", mvals.offset); g_snprintf (buffer, BUFSIZE, "%d", mvals.offset);
gtk_entry_set_text (GTK_ENTRY (entry), buffer ); gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
_("Offset (1):"), 1.0, 0.5, _("Offset (1):"), 1.0, 0.5,
entry, 1, FALSE); entry, 1, FALSE);
trow++; trow++;
@ -282,17 +282,17 @@ maze_dialog (void)
/* Tileable checkbox */ /* Tileable checkbox */
tilecheck = gtk_check_button_new_with_label (_("Tileable")); tilecheck = gtk_check_button_new_with_label (_("Tileable"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tilecheck), mvals.tile); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tilecheck), mvals.tile);
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
NULL, 1.0, 0.5, NULL, 1.0, 0.5,
tilecheck, 1, FALSE); tilecheck, 1, FALSE);
trow++; trow++;
g_signal_connect (tilecheck, "clicked", g_signal_connect (tilecheck, "clicked",
G_CALLBACK (gimp_toggle_button_update), G_CALLBACK (gimp_toggle_button_update),
&mvals.tile); &mvals.tile);
/* Seed input box */ /* Seed input box */
seed_hbox = gimp_random_seed_new (&mvals.seed); seed_hbox = gimp_random_seed_new (&mvals.seed);
gimp_table_attach_aligned (GTK_TABLE (table), 0, trow, gimp_table_attach_aligned (GTK_TABLE (table), 0, trow,
_("Seed:"), 1.0, 0.5, _("Seed:"), 1.0, 0.5,
seed_hbox, 1, TRUE); seed_hbox, 1, TRUE);
trow++; trow++;
@ -300,18 +300,18 @@ maze_dialog (void)
/* Algorithm Choice */ /* Algorithm Choice */
frame = gimp_radio_group_new (TRUE, _("Style"), frame = gimp_radio_group_new (TRUE, _("Style"),
_("Depth First"), _("Depth First"),
gimp_radio_button_update, gimp_radio_button_update,
&mvals.algorithm, &mvals.algorithm,
(gpointer) DEPTH_FIRST, (gpointer) DEPTH_FIRST,
NULL, NULL,
(mvals.algorithm == DEPTH_FIRST), (mvals.algorithm == DEPTH_FIRST),
_("Prim's Algorithm"), _("Prim's Algorithm"),
gimp_radio_button_update, gimp_radio_button_update,
&mvals.algorithm, &mvals.algorithm,
(gpointer) PRIMS_ALGORITHM, (gpointer) PRIMS_ALGORITHM,
NULL, NULL,
(mvals.algorithm == PRIMS_ALGORITHM), (mvals.algorithm == PRIMS_ALGORITHM),
NULL); NULL);
@ -325,7 +325,7 @@ maze_dialog (void)
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_set_border_width (GTK_CONTAINER(frame), 6); gtk_container_set_border_width (GTK_CONTAINER(frame), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), frame, FALSE, FALSE, 0);
message = g_strdup_printf (_("Selection is %dx%d"), sel_w, sel_h); message = g_strdup_printf (_("Selection is %dx%d"), sel_w, sel_h);
msg_label = gtk_label_new (message); msg_label = gtk_label_new (message);
g_free (message); g_free (message);
@ -358,7 +358,7 @@ divbox_new (guint *max,
hbox = gtk_hbox_new (FALSE, 0); hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (align), hbox); gtk_container_add (GTK_CONTAINER (align), hbox);
#if DIVBOX_LOOKS_LIKE_SPINBUTTON #if DIVBOX_LOOKS_LIKE_SPINBUTTON
arrowl = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); arrowl = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
arrowr = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT); arrowr = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
#else #else
@ -368,7 +368,7 @@ divbox_new (guint *max,
buttonl = gtk_button_new (); buttonl = gtk_button_new ();
buttonr = gtk_button_new (); buttonr = gtk_button_new ();
g_object_set_data (G_OBJECT (buttonl), "direction", GINT_TO_POINTER (LESS)); g_object_set_data (G_OBJECT (buttonl), "direction", GINT_TO_POINTER (LESS));
g_object_set_data (G_OBJECT (buttonr), "direction", GINT_TO_POINTER (MORE)); g_object_set_data (G_OBJECT (buttonr), "direction", GINT_TO_POINTER (MORE));
@ -398,15 +398,15 @@ divbox_new (guint *max,
gtk_box_pack_start (GTK_BOX (hbox), buttonl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), buttonl, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), *div_entry, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (hbox), *div_entry, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (hbox), buttonr, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), buttonr, FALSE, FALSE, 0);
#endif #endif
gtk_widget_show_all (hbox); gtk_widget_show_all (hbox);
g_signal_connect (buttonl, "clicked", g_signal_connect (buttonl, "clicked",
G_CALLBACK (div_button_callback), G_CALLBACK (div_button_callback),
*div_entry); *div_entry);
g_signal_connect (buttonr, "clicked", g_signal_connect (buttonr, "clicked",
G_CALLBACK (div_button_callback), G_CALLBACK (div_button_callback),
*div_entry); *div_entry);
g_signal_connect (*div_entry, "changed", g_signal_connect (*div_entry, "changed",
G_CALLBACK (div_entry_callback), G_CALLBACK (div_entry_callback),
@ -443,21 +443,21 @@ div_button_callback (GtkWidget *button,
if (divs <= 3) if (divs <= 3)
{ {
divs = mvals.tile ? divs = mvals.tile ?
max - (ISODD(max) ? 1 : 0) : max - (ISODD(max) ? 1 : 0) :
max - (ISODD(max) ? 0 : 1); max - (ISODD(max) ? 0 : 1);
} }
else if (divs > max) else if (divs > max)
{ {
divs = mvals.tile ? 6 : 5; divs = mvals.tile ? 6 : 5;
} }
/* Makes sure we're appropriately even or odd, adjusting in the /* Makes sure we're appropriately even or odd, adjusting in the
proper direction. */ proper direction. */
divs += direction * (mvals.tile ? (ISODD(divs) ? 1 : 0) : divs += direction * (mvals.tile ? (ISODD(divs) ? 1 : 0) :
(ISODD(divs) ? 0 : 1)); (ISODD(divs) ? 0 : 1));
if (mvals.tile) if (mvals.tile)
{ {
if (direction > 0) if (direction > 0)
@ -503,8 +503,8 @@ div_button_callback (GtkWidget *button,
if (divs <= 3) if (divs <= 3)
{ {
divs = mvals.tile ? divs = mvals.tile ?
max - (ISODD(max) ? 1 : 0) : max - (ISODD(max) ? 1 : 0) :
max - (ISODD(max) ? 0 : 1); max - (ISODD(max) ? 0 : 1);
} }
else if (divs > max) else if (divs > max)
@ -530,7 +530,7 @@ div_entry_callback (GtkWidget *entry,
if (divs < 4) /* If this is under 4 (e.g. 0), something's weird. */ if (divs < 4) /* If this is under 4 (e.g. 0), something's weird. */
return; /* But it'll probably be ok, so just return and ignore. */ return; /* But it'll probably be ok, so just return and ignore. */
max = *((guint*) g_object_get_data (G_OBJECT (entry), "max")); max = *((guint*) g_object_get_data (G_OBJECT (entry), "max"));
/* I say "width" here, but it could be height.*/ /* I say "width" here, but it could be height.*/
@ -591,31 +591,29 @@ maze_help (GtkWidget *widget,
gchar *message; gchar *message;
if (gimp_procedural_db_proc_info ("plug_in_web_browser", if (gimp_procedural_db_proc_info ("plug_in_web_browser",
&proc_blurb, &proc_blurb,
&proc_help, &proc_help,
&proc_author, &proc_author,
&proc_copyright, &proc_copyright,
&proc_date, &proc_date,
&proc_type, &proc_type,
&nparams, &nreturn_vals, &nparams, &nreturn_vals,
&params, &return_vals)) &params, &return_vals))
{ {
/* open URL for help */ /* open URL for help */
message = g_strdup_printf (_("Opening %s"), MAZE_URL); message = g_strdup_printf (_("Opening %s"), MAZE_URL);
maze_msg (message); maze_msg (message);
g_free (message); g_free (message);
gimp_run_procedure ("plug_in_web_browser", &baz, gimp_run_procedure ("plug_in_web_browser", &baz,
GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
GIMP_PDB_STRING, MAZE_URL, GIMP_PDB_STRING, MAZE_URL,
GIMP_PDB_INT32, HELP_OPENS_NEW_WINDOW,
GIMP_PDB_END); GIMP_PDB_END);
} }
else else
{ {
message = g_strdup_printf (_("See %s"), MAZE_URL); message = g_strdup_printf (_("See %s"), MAZE_URL);
maze_msg (message); maze_msg (message);
g_free (message); g_free (message);
} }
} }
static void static void
@ -634,7 +632,7 @@ maze_ok_callback (GtkWidget *widget,
} }
#ifdef SHOW_PRNG_PRIVATES #ifdef SHOW_PRNG_PRIVATES
static void static void
maze_entry_callback (GtkWidget *widget, maze_entry_callback (GtkWidget *widget,
gpointer data) gpointer data)
{ {
@ -647,7 +645,7 @@ maze_entry_callback (GtkWidget *widget,
#endif #endif
/* ==================================================================== */ /* ==================================================================== */
/* As found in pixelize.c, /* As found in pixelize.c,
* hacked to return a pointer to the entry widget. */ * hacked to return a pointer to the entry widget. */
/* /*
@ -673,13 +671,13 @@ maze_entry_callback (GtkWidget *widget,
* call_data: data for callback func * call_data: data for callback func
*/ */
static GtkWidget* static GtkWidget*
entscale_int_new (GtkWidget *table, entscale_int_new (GtkWidget *table,
gint x, gint x,
gint y, gint y,
gchar *caption, gchar *caption,
gint *intvar, gint *intvar,
gint min, gint min,
gint max, gint max,
gboolean constraint, gboolean constraint,
EntscaleIntCallbackFunc callback, EntscaleIntCallbackFunc callback,
gpointer call_data) gpointer call_data)
@ -710,7 +708,7 @@ entscale_int_new (GtkWidget *table,
else else
constraint_val = ( *intvar < min ? min : *intvar > max ? max : *intvar ); constraint_val = ( *intvar < min ? min : *intvar > max ? max : *intvar );
userdata->adjustment = adjustment = userdata->adjustment = adjustment =
gtk_adjustment_new (constraint_val, min, max, 1.0, 1.0, 0.0); gtk_adjustment_new (constraint_val, min, max, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment)); scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
gtk_widget_set_size_request (scale, ENTSCALE_INT_SCALE_WIDTH, -1); gtk_widget_set_size_request (scale, ENTSCALE_INT_SCALE_WIDTH, -1);
@ -755,7 +753,7 @@ entscale_int_new (GtkWidget *table,
gtk_widget_show (hbox); gtk_widget_show (hbox);
return entry; return entry;
} }
/* when destroyed, userdata is destroyed too */ /* when destroyed, userdata is destroyed too */
@ -786,7 +784,7 @@ entscale_int_scale_update (GtkAdjustment *adjustment,
entry = GTK_ENTRY (userdata->entry); entry = GTK_ENTRY (userdata->entry);
g_snprintf (buffer, BUFSIZE, "%d", (int) new_val); g_snprintf (buffer, BUFSIZE, "%d", (int) new_val);
/* avoid infinite loop (scale, entry, scale, entry ...) */ /* avoid infinite loop (scale, entry, scale, entry ...) */
g_signal_handlers_block_by_func (entry, g_signal_handlers_block_by_func (entry,
entscale_int_entry_update, entscale_int_entry_update,
@ -837,7 +835,7 @@ entscale_int_entry_update (GtkWidget *widget,
g_signal_handlers_unblock_by_func (adjustment, g_signal_handlers_unblock_by_func (adjustment,
entscale_int_scale_update, entscale_int_scale_update,
data); data);
if (userdata->callback) if (userdata->callback)
(*userdata->callback) (*intvar, userdata->call_data); (*userdata->callback) (*intvar, userdata->call_data);
} }

View file

@ -100,6 +100,7 @@ scriptdata_DATA = \
unsharp-mask.scm \ unsharp-mask.scm \
waves-anim.scm \ waves-anim.scm \
weave.scm \ weave.scm \
web-browser.scm \
xach-effect.scm \ xach-effect.scm \
\ \
test-sphere.scm test-sphere.scm

View file

@ -0,0 +1,53 @@
; The GIMP -- an image manipulation program
; Copyright (C) 1995 Spencer Kimball and Peter Mattis
;
; gimp-online.scm
; Copyright (C) 2003 Henrik Brix Andersen <brix@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.
(define (gimp-online-main-web-site)
(plug-in-web-browser "http://www.gimp.org"))
(define (gimp-online-developer-web-site)
(plug-in-web-browser "http://developer.gimp.org"))
(define (gimp-online-plug-in-web-site)
(plug-in-web-browser "http://registry.gimp.org"))
(script-fu-register "gimp-online-main-web-site"
_"<Toolbox>/Help/The GIMP Online/_Main Web Site"
"Link to http://www.gimp.org"
"Henrik Brix Andersen <brix@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org>"
"2003"
"")
(script-fu-register "gimp-online-developer-web-site"
_"<Toolbox>/Help/The GIMP Online/_Developer Web Site"
"Link to http://www.gimp.org"
"Henrik Brix Andersen <brix@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org>"
"2003"
"")
(script-fu-register "gimp-online-plug-in-web-site"
_"<Toolbox>/Help/The GIMP Online/Plug-in _Registry"
"Link to http://www.gimp.org"
"Henrik Brix Andersen <brix@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org>"
"2003"
"")

View file

@ -1,34 +0,0 @@
## Process this file with automake to produce Makefile.in
if OS_WIN32
mwindows = -mwindows
endif
AM_LDFLAGS = $(mwindows)
scriptdatadir = $(gimpdatadir)/scripts
scriptdata_DATA = web-browser.scm
libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = webbrowser
webbrowser_SOURCES = webbrowser.c
EXTRA_DIST = $(scriptdata_DATA)
INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui-$(LT_RELEASE).la \
$(top_builddir)/libgimpwidgets/libgimpwidgets-$(LT_RELEASE).la \
$(top_builddir)/libgimp/libgimp-$(LT_RELEASE).la \
$(top_builddir)/libgimpcolor/libgimpcolor-$(LT_RELEASE).la \
$(top_builddir)/libgimpbase/libgimpbase-$(LT_RELEASE).la \
$(GTK_LIBS) \
$(LIBXMU) \
$(INTLLIBS)

View file

@ -1,129 +0,0 @@
Web Browser GIMP Extension v0.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
by Misha Dynin <misha@xcf.berkeley.edu>
Introduction
~~~~~~~~~~~~
Web Browser GIMP extension is not an HTML browser (at least, not yet ;-);
it's just an interface to an external web browser that allows GIMP, using
a PDB call, to instruct a browser to open a URL.
Currently, it works with Netscape, version 1.1 or above, using a protocol
described in detail on http://home.netscape.com/newsref/std/x-remote.html.
If Netscape is not running already, the extension starts it, with a URL
as a command-line argument.
Possible uses of this extension:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Providing a set of bookmarks, accessible from the GIMP.
This is implemented -- web-browser.scm, included in a distribution,
builds a menu of frequently accessed GIMP websites. It's cool.
* Implementing GIMP online help.
This is the most promising use of the extension. GIMP plugins and
main application can provide "Help" and "About" buttons, which,
when pressed, cause a corresponding page to be opened in Netscape.
This is doable now; the only problem is to design a standard way
to do that. It would be great to be able to access the documentation
either from the web site or, if installed, from local disk.
(add gimp-path to .gimprc; use as prefix in gimp-help() function?)
I request input of experienced GIMP developers on this.
* Providing a preview in a web browser.
Large percentage of the graphics designed in GIMP ends up on the WWW.
With this extension, you can write a script that automatically
launches a web browser and displays the image as it will be viewed.
Imagine: have a set of scripts defining page style, change one attribute,
and have GIMP not only recompute all the images, but also automagically
open the redesigned page design in a browser window!
How to use the extension:
~~~~~~~~~~~~~~~~~~~~~~~~
* Interactively:
select Xtns -> Web Browser -> Open URL, type in the URL, press Ok;
* Non-interactively:
use procedure extension-web-browser (url, new-window), which takes
as the first argument a URL of a page to open, and second argument
is a boolean which specifies whether you want the browser to open
a new window with a document (new-window == TRUE) or use current
window (new-window == FALSE). If the browser is not already running,
new-window value is ignored.
I didn't provide a more detailed API on purpose -- making it more
detailed would make it more Netscape-specific, and I want to be able
to add support for other browsers. If someone has a convincing argument
for adding more functions (i.e. to check whether browser is running, etc.),
email me.
Status:
~~~~~~
Netscape support is stable. I haven't tested it on many platforms,
but I don't expect any problems. What other browsers, if any, do we
need to support?
Included "web-browser.scm" has links to the most popular (IMHO)
GIMP pages. I hope that the extension will get incorporated into
the main source tree, and I will not have to maintain the bookmarks
list.
Need help system design based on the web browser extension.
If some GIMP guru (petm? spencer?) tells me what's the right way to do it,
I can implement the help system.
I didn't write a proof-of-concept implementation of the preview
script mainly because I am lazy. If someone writes such a script --
please email it to me.
Building Web Browser Extension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiling it should be fairly easy. I've included Makefile diff's (for
the Makefile in plug-ins directory). webbrowser requires libXmu;
it should be linked with -lXmu.
Enclosed script, web-browser.scm, creates a bookmarks menu in
Xnts/Web Browser/*. Note that there is a bug in script-fu
(at least as of version 0.99.15) which prevents it from handling
scripts with zero arguments. Enclosed patch to
plug-ins/script-fu/script-fu-scripts.c fixes that bug. Without
this patch, web-browser.scm won't work.
Where To Find This Extension
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The extension can be downloaded from
ftp://ftp.xcf.berkeley.edu/pub/misha/webbrowser.tar.gz
For the up-to-date information about this extension, check out
http://www.xcf.berkeley.edu/~misha/gimp/
Author
~~~~~~
This extension is written by Misha Dynin <misha@xcf.berkeley.edu>.
I used the code from GUMP plugin, by Adrian Likins <aklikins@eos.ncsu.edu>.
Netscape interface code copyright:
* Copyright © 1996 Netscape Communications Corporation, all rights reserved.
* Created: Jamie Zawinski <jwz@netscape.com>, 24-Dec-94.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation. No representations are made about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.

View file

@ -1,154 +0,0 @@
; web-browser.scm -- install bookmarks
; Copyright (c) 1997 Misha Dynin <misha@xcf.berkeley.edu>
; Note: script-fu must be able to handle zero argument procedures to
; process this file!
;
; For more information see webbrowser.readme or
; http://www.xcf.berkeley.edu/~misha/gimp/
;
; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
(set! web-browser-new-window 0)
(define (script-fu-bookmark url)
(plug-in-web-browser 1 url web-browser-new-window))
(define (bookmark-register proc menu help)
(script-fu-register proc menu help
"Misha Dynin <misha@xcf.berkeley.edu>"
"Misha Dynin"
"1997"
""))
(define (script-fu-bookmark-1)
(script-fu-bookmark "http://www.gimp.org/the_gimp.html"))
(bookmark-register "script-fu-bookmark-1"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/The GIMP"
"Link to http://www.gimp.org/the_gimp.html")
(define (script-fu-bookmark-2)
(script-fu-bookmark "http://www.gimp.org/docs.html"))
(bookmark-register "script-fu-bookmark-2"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/Documenation"
"Link to http://www.gimp.org/docs.html")
(define (script-fu-bookmark-3)
(script-fu-bookmark "http://www.gimp.org/mailing_list.html"))
(bookmark-register "script-fu-bookmark-3"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/Mailing Lists"
"Link to http://www.gimp.org/mailing_list.html")
(define (script-fu-bookmark-4)
(script-fu-bookmark "http://www.gimp.org/data.html"))
(bookmark-register "script-fu-bookmark-4"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/Resources"
"Link to http://www.gimp.org/data.html")
(define (script-fu-bookmark-5)
(script-fu-bookmark "http://www.gimp.org/download.html"))
(bookmark-register "script-fu-bookmark-5"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/Download"
"Link to http://www.gimp.org/download.html")
(define (script-fu-bookmark-6)
(script-fu-bookmark "http://www.gimp.org/art.html"))
(bookmark-register "script-fu-bookmark-6"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/GIMP Art"
"Link to http://www.gimp.org/art.html")
(define (script-fu-bookmark-7)
(script-fu-bookmark "http://www.gimp.org/links.html"))
(bookmark-register "script-fu-bookmark-7"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/Links"
"Link to http://www.gimp.org/links.html")
(define (script-fu-bookmark-8)
(script-fu-bookmark "http://www.gtk.org/"))
(bookmark-register "script-fu-bookmark-8"
_"<Toolbox>/Xtns/Web Browser/GIMP.ORG/GTK"
"Link to http://www.gtk.org/")
(define (script-fu-bookmark-10)
(script-fu-bookmark "http://news.gimp.org/"))
(bookmark-register "script-fu-bookmark-10"
_"<Toolbox>/Xtns/Web Browser/GIMP News"
"Link to http://news.gimp.org/")
(define (script-fu-bookmark-11)
(script-fu-bookmark "http://registry.gimp.org/"))
(bookmark-register "script-fu-bookmark-11"
_"<Toolbox>/Xtns/Web Browser/Plug-In Registry"
"Link to http://registry.gimp.org/")
(define (script-fu-bookmark-12)
(script-fu-bookmark "http://www.rru.com/~meo/gimp/faq-user.html"))
(bookmark-register "script-fu-bookmark-12"
_"<Toolbox>/Xtns/Web Browser/User FAQ"
"Link to http://www.rru.com/~meo/gimp/faq-user.html")
(define (script-fu-bookmark-13)
(script-fu-bookmark "http://www.rru.com/~meo/gimp/faq-dev.html"))
(bookmark-register "script-fu-bookmark-13"
_"<Toolbox>/Xtns/Web Browser/Developer FAQ"
"Link to http://www.rru.com/~meo/gimp/faq-dev.html")
(define (script-fu-bookmark-14)
(script-fu-bookmark "http://manual.gimp.org/"))
(bookmark-register "script-fu-bookmark-14"
_"<Toolbox>/Xtns/Web Browser/GIMP Manual"
"Link to http://manual.gimp.org/")
(define (script-fu-bookmark-15)
(script-fu-bookmark "http://abattoir.cc.ndsu.nodak.edu/~nem/gimp/tuts/"))
(bookmark-register "script-fu-bookmark-15"
_"<Toolbox>/Xtns/Web Browser/GIMP Tutorials"
"Link to http://abattoir.cc.ndsu.nodak.edu/~nem/gimp/tuts/")
(define (script-fu-bookmark-16)
(script-fu-bookmark "http://bugzilla.gnome.org/"))
(bookmark-register "script-fu-bookmark-16"
_"<Toolbox>/Xtns/Web Browser/GIMP Bugs"
"Link to http://bugzilla.gnome.org/")
(define (script-fu-bookmark-17)
(script-fu-bookmark "http://gimp-savvy.com/"))
(bookmark-register "script-fu-bookmark-17"
_"<Toolbox>/Xtns/Web Browser/Gimp-Savvy.com"
"Link to http://gimp-savvy.com/")
(define (script-fu-bookmark-18)
(script-fu-bookmark "http://gimp-savvy.com/BOOK/"))
(bookmark-register "script-fu-bookmark-18"
_"<Toolbox>/Xtns/Web Browser/Grokking the GIMP"
"Link to http://gimp-savvy.com/BOOK/")

View file

@ -1,963 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
* Copyright (C) 1997 Misha Dynin
*
* 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.
*/
/*
Web Browser v0.3 -- opens a URL in Netscape
by Misha Dynin <misha@xcf.berkeley.edu>
For more information, see webbrowser.readme, as well as
http://www.xcf.berkeley.edu/~misha/gimp/
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifdef __EMX__
#include <process.h>
#endif
#include <gtk/gtk.h>
#ifdef G_OS_WIN32
#define STRICT
#include <windows.h>
#include <shellapi.h>
#else
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xmu/WinUtil.h> /* for XmuClientWindow() */
#endif
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
/* Browser program name -- start in case it's not already running */
#define BROWSER_PROGNAME "netscape"
/* Open a new window with request? */
#define OPEN_URL_NEW_WINDOW 1
#define OPEN_URL_CURRENT_WINDOW 0
#define URL_BUF_SIZE 255
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gint open_url_dialog (void);
static void ok_callback (GtkWidget *widget,
gpointer data);
static void about_callback (GtkWidget *widget,
gpointer data);
static void new_window_callback (GtkWidget *widget,
gpointer data);
static void url_callback (GtkWidget *widget,
gpointer data);
#ifndef G_OS_WIN32
static gint mozilla_remote (const gchar *command);
#endif
static gint open_url (const gchar *url,
gboolean new_window);
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
typedef struct
{
gchar url[URL_BUF_SIZE];
gint new_window;
} u_info;
static u_info url_info =
{
"http://www.gimp.org/", /* Default URL */
OPEN_URL_NEW_WINDOW, /* Change to ...CURRENT_WINDOW if
* you prefer that as the default
*/
};
static gboolean run_flag = FALSE;
MAIN ()
static void
query (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
{ GIMP_PDB_STRING, "url", "URL of a document to open" },
{ GIMP_PDB_INT32, "new_window", "Create a new window or use existing one?" },
};
gimp_install_procedure ("plug_in_web_browser",
"open URL in Netscape",
"You need to have Netscape installed",
"Misha Dynin <misha@xcf.berkeley.edu>",
"Misha Dynin, Jamie Zawinski, Spencer Kimball & Peter Mattis",
"1997",
N_("<Toolbox>/Xtns/Web Browser/Open URL..."),
NULL,
GIMP_PLUGIN,
G_N_ELEMENTS (args), 0,
args, NULL);
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
INIT_I18N ();
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
*nreturn_vals = 1;
*return_vals = values;
if (strcmp (name, "plug_in_web_browser") == 0)
{
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
/* Possibly retrieve data */
gimp_get_data ("plug_in_web_browser", &url_info);
if (!open_url_dialog ())
return;
break;
case GIMP_RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 3)
{
status = GIMP_PDB_CALLING_ERROR;
}
else
{
strncpy (url_info.url, param[1].data.d_string, URL_BUF_SIZE);
url_info.new_window = param[2].data.d_int32;
}
break;
case GIMP_RUN_WITH_LAST_VALS:
gimp_get_data ("plug_in_web_browser", &url_info);
break;
default:
break;
}
if (status == GIMP_PDB_SUCCESS)
{
if (!open_url (url_info.url, url_info.new_window))
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data ("plug_in_web_browser", &url_info, sizeof (u_info));
values[0].data.d_status = GIMP_PDB_SUCCESS;
}
else
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
}
else
g_assert_not_reached ();
}
static gint
start_browser (const gchar *prog,
const gchar *url)
{
#ifdef G_OS_WIN32
ShellExecute (HWND_DESKTOP, "open", url, NULL, "C:\\", SW_SHOWNORMAL);
#else
#ifndef __EMX__
pid_t cpid;
if ((cpid = fork()) == 0)
{
execlp (prog, prog, url, NULL);
exit (1);
}
return (cpid > 0);
#else
return (spawnlp (P_NOWAIT, prog, prog, url, NULL) != -1);
#endif
#endif /* !G_OS_WIN32 */
}
static gint
open_url (const gchar *url,
gboolean new_window)
{
gchar buf[512];
while (g_ascii_isspace (*url))
++url;
#ifndef G_OS_WIN32
sprintf (buf, "openURL(%s%s)", url, new_window ? ",new-window" : "");
if (mozilla_remote (buf))
return (TRUE);
#endif
return (start_browser (BROWSER_PROGNAME, url));
}
static gint
open_url_dialog (void)
{
GtkWidget *dlg;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *entry;
GtkWidget *table;
GSList *group;
gchar buffer[256];
gimp_ui_init ("webbrowser", FALSE);
dlg = gimp_dialog_new (_("Open URL"), "webbbrowser",
gimp_standard_help_func, "filters/webbrowser.html",
GTK_WIN_POS_MOUSE,
FALSE, TRUE, FALSE,
_("About"), about_callback,
NULL, NULL, NULL, FALSE, FALSE,
GTK_STOCK_CANCEL, gtk_widget_destroy,
NULL, 1, NULL, FALSE, TRUE,
GTK_STOCK_OK, ok_callback,
NULL, NULL, NULL, TRUE, FALSE,
NULL);
g_signal_connect (dlg, "destroy",
G_CALLBACK (gtk_main_quit),
NULL);
/* table */
table = gtk_table_new (2, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_container_set_border_width (GTK_CONTAINER (table), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
/* URL */
entry = gtk_entry_new ();
gtk_widget_set_size_request (entry, 200, -1);
g_snprintf (buffer, sizeof (buffer), "%s", url_info.url);
gtk_entry_set_text (GTK_ENTRY (entry), buffer);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("URL:"), 1.0, 0.5,
entry, 1, FALSE);
g_signal_connect (entry, "changed",
G_CALLBACK (url_callback),
&url_info.url);
gtk_widget_show (entry);
/* Window */
hbox = gtk_hbox_new (FALSE, 4);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Window:"), 1.0, 0.5,
hbox, 1, FALSE);
button = gtk_radio_button_new_with_label (NULL, _("New"));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
if (url_info.new_window == OPEN_URL_NEW_WINDOW)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "toggled",
G_CALLBACK (new_window_callback),
(gpointer) OPEN_URL_NEW_WINDOW);
button = gtk_radio_button_new_with_label (group, _("Current"));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
if (url_info.new_window == OPEN_URL_CURRENT_WINDOW)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect (button, "toggled",
G_CALLBACK (new_window_callback),
(gpointer) OPEN_URL_CURRENT_WINDOW);
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return run_flag;
}
static void
ok_callback (GtkWidget *widget,
gpointer data)
{
run_flag = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void
about_callback (GtkWidget *widget,
gpointer data)
{
open_url ("http://www.xcf.berkeley.edu/~misha/gimp/", OPEN_URL_NEW_WINDOW);
}
static void
new_window_callback (GtkWidget *widget,
gpointer data)
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
url_info.new_window = GPOINTER_TO_INT (data);
}
}
static void
url_callback (GtkWidget *widget,
gpointer data)
{
strncpy (url_info.url, gtk_entry_get_text (GTK_ENTRY (widget)), URL_BUF_SIZE);
}
#ifndef G_OS_WIN32
/* -*- Mode:C; tab-width: 8 -*-
* remote.c --- remote control of Netscape Navigator for Unix.
* version 1.1.3, for Netscape Navigator 1.1 and newer.
*
* Copyright © 1996 Netscape Communications Corporation, all rights reserved.
* Created: Jamie Zawinski <jwz@netscape.com>, 24-Dec-94.
*
* To compile:
*
* cc -o netscape-remote remote.c -DSTANDALONE -lXmu -lX11
*
* To use:
*
* netscape-remote -help
*
* Documentation for the protocol which this code implements may be found at:
*
* http://home.netscape.com/newsref/std/x-remote.html
*
* Bugs and commentary to x_cbug@netscape.com.
*/
/* vroot.h is a header file which lets a client get along with `virtual root'
window managers like swm, tvtwm, olvwm, etc. If you don't have this header
file, you can find it at "http://home.netscape.com/newsref/std/vroot.h".
If you don't care about supporting virtual root window managers, you can
comment this line out.
*/
/* #include "vroot.h" */
/* Begin vroot.h */
/*****************************************************************************/
/** Copyright 1991 by Andreas Stolcke **/
/** Copyright 1990 by Solbourne Computer Inc. **/
/** Longmont, Colorado **/
/** **/
/** All Rights Reserved **/
/** **/
/** Permission to use, copy, modify, and distribute this software and **/
/** its documentation for any purpose and without fee is hereby **/
/** granted, provided that the above copyright notice appear in all **/
/** copies and that the name of Solbourne not be used in advertising **/
/** in publicity pertaining to distribution of the software without **/
/** specific, written prior permission. **/
/** **/
/** ANDREAS STOLCKE AND SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES **/
/** WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **/
/** MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ANDREAS STOLCKE **/
/** OR SOLBOURNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL **/
/** DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
/** OR PERFORMANCE OF THIS SOFTWARE. **/
/*****************************************************************************/
/*
* vroot.h -- Virtual Root Window handling header file
*
* This header file redefines the X11 macros RootWindow and DefaultRootWindow,
* making them look for a virtual root window as provided by certain `virtual'
* window managers like swm and tvtwm. If none is found, the ordinary root
* window is returned, thus retaining backward compatibility with standard
* window managers.
* The function implementing the virtual root lookup remembers the result of
* its last invocation to avoid overhead in the case of repeated calls
* on the same display and screen arguments.
* The lookup code itself is taken from Tom LaStrange's ssetroot program.
*
* Most simple root window changing X programs can be converted to using
* virtual roots by just including
*
* #include <X11/vroot.h>
*
* after all the X11 header files. It has been tested on such popular
* X clients as xphoon, xfroot, xloadimage, and xaqua.
* It also works with the core clients xprop, xwininfo, xwd, and editres
* (and is necessary to get those clients working under tvtwm).
* It does NOT work with xsetroot; get the xsetroot replacement included in
* the tvtwm distribution instead.
*
* Andreas Stolcke <stolcke@ICSI.Berkeley.EDU>, 9/7/90
* - replaced all NULL's with properly cast 0's, 5/6/91
* - free children list (suggested by Mark Martin <mmm@cetia.fr>), 5/16/91
* - include X11/Xlib.h and support RootWindowOfScreen, too 9/17/91
*/
#ifndef _VROOT_H_
#define _VROOT_H_
static Window
VirtualRootWindowOfScreen(screen)
Screen *screen;
{
static Screen *save_screen = (Screen *)0;
static Window root = (Window)0;
if (screen != save_screen) {
Display *dpy = DisplayOfScreen(screen);
Atom __SWM_VROOT = None;
int i;
Window rootReturn, parentReturn, *children;
unsigned int numChildren;
root = RootWindowOfScreen(screen);
/* go look for a virtual root */
__SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
if (XQueryTree(dpy, root, &rootReturn, &parentReturn,
&children, &numChildren)) {
for (i = 0; i < numChildren; i++) {
Atom actual_type;
int actual_format;
unsigned long nitems, bytesafter;
Window *newRoot = (Window *)0;
if (XGetWindowProperty(dpy, children[i],
__SWM_VROOT, 0, 1, False, XA_WINDOW,
&actual_type, &actual_format,
&nitems, &bytesafter,
(unsigned char **) &newRoot) == Success
&& newRoot) {
root = *newRoot;
break;
}
}
if (children)
XFree((char *)children);
}
save_screen = screen;
}
return root;
}
#undef RootWindowOfScreen
#define RootWindowOfScreen(s) VirtualRootWindowOfScreen(s)
#undef RootWindow
#define RootWindow(dpy,screen) VirtualRootWindowOfScreen(ScreenOfDisplay(dpy,screen))
#undef DefaultRootWindow
#define DefaultRootWindow(dpy) VirtualRootWindowOfScreen(DefaultScreenOfDisplay(dpy))
#endif /* _VROOT_H_ */
/* End vroot.h */
#ifdef DIAGNOSTIC
#ifdef STANDALONE
static const char *progname = 0;
static const char *expected_mozilla_version = "1.1";
#else /* !STANDALONE */
extern const char *progname;
extern const char *expected_mozilla_version;
#endif /* !STANDALONE */
#endif /* DIAGNOSTIC */
#define MOZILLA_VERSION_PROP "_MOZILLA_VERSION"
#define MOZILLA_LOCK_PROP "_MOZILLA_LOCK"
#define MOZILLA_COMMAND_PROP "_MOZILLA_COMMAND"
#define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE"
static Atom XA_MOZILLA_VERSION = 0;
static Atom XA_MOZILLA_LOCK = 0;
static Atom XA_MOZILLA_COMMAND = 0;
static Atom XA_MOZILLA_RESPONSE = 0;
static void
mozilla_remote_init_atoms (Display *dpy)
{
if (! XA_MOZILLA_VERSION)
XA_MOZILLA_VERSION = XInternAtom (dpy, MOZILLA_VERSION_PROP, False);
if (! XA_MOZILLA_LOCK)
XA_MOZILLA_LOCK = XInternAtom (dpy, MOZILLA_LOCK_PROP, False);
if (! XA_MOZILLA_COMMAND)
XA_MOZILLA_COMMAND = XInternAtom (dpy, MOZILLA_COMMAND_PROP, False);
if (! XA_MOZILLA_RESPONSE)
XA_MOZILLA_RESPONSE = XInternAtom (dpy, MOZILLA_RESPONSE_PROP, False);
}
static Window
mozilla_remote_find_window (Display *dpy)
{
int i;
Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
Window root2, parent, *kids;
unsigned int nkids;
Window result = 0;
if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: XQueryTree failed on display %s\n", progname,
DisplayString (dpy));
#endif
return (0);
}
/* root != root2 is possible with virtual root WMs. */
if (! (kids && nkids))
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: root window has no children on display %s\n",
progname, DisplayString (dpy));
#endif
return (0);
}
for (i = nkids-1; i >= 0; i--)
{
Atom type;
int format;
unsigned long nitems, bytesafter;
unsigned char *version = 0;
Window w = XmuClientWindow (dpy, kids[i]);
int status = XGetWindowProperty (dpy, w, XA_MOZILLA_VERSION,
0, (65536 / sizeof (long)),
False, XA_STRING,
&type, &format, &nitems, &bytesafter,
&version);
if (! version)
continue;
XFree (version);
if (status == Success && type != None)
{
result = w;
break;
}
}
return result;
}
static char *lock_data = 0;
static int
mozilla_remote_obtain_lock (Display *dpy, Window window)
{
Bool locked = False;
Bool waited = False;
if (! lock_data)
{
lock_data = (char *) malloc (255);
sprintf (lock_data, "pid%d@", getpid ());
if (gethostname (lock_data + strlen (lock_data), 100))
{
return (-1);
}
}
do
{
int result;
Atom actual_type;
int actual_format;
unsigned long nitems, bytes_after;
unsigned char *data = 0;
XGrabServer (dpy); /* ################################# DANGER! */
result = XGetWindowProperty (dpy, window, XA_MOZILLA_LOCK,
0, (65536 / sizeof (long)),
False, /* don't delete */
XA_STRING,
&actual_type, &actual_format,
&nitems, &bytes_after,
&data);
if (result != Success || actual_type == None)
{
/* It's not now locked - lock it. */
#ifdef DEBUG_PROPS
fprintf (stderr, "%s: (writing " MOZILLA_LOCK_PROP
" \"%s\" to 0x%x)\n",
progname, lock_data, (unsigned int) window);
#endif
XChangeProperty (dpy, window, XA_MOZILLA_LOCK, XA_STRING, 8,
PropModeReplace, (unsigned char *) lock_data,
strlen (lock_data));
locked = True;
}
XUngrabServer (dpy); /* ################################# danger over */
XSync (dpy, False);
if (! locked)
{
/* We tried to grab the lock this time, and failed because someone
else is holding it already. So, wait for a PropertyDelete event
to come in, and try again. */
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: window 0x%x is locked by %s; waiting...\n",
progname, (unsigned int) window, data);
#endif
waited = True;
while (1)
{
XEvent event;
XNextEvent (dpy, &event);
if (event.xany.type == DestroyNotify &&
event.xdestroywindow.window == window)
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: window 0x%x unexpectedly destroyed.\n",
progname, (unsigned int) window);
#endif
return (6);
}
else if (event.xany.type == PropertyNotify &&
event.xproperty.state == PropertyDelete &&
event.xproperty.window == window &&
event.xproperty.atom == XA_MOZILLA_LOCK)
{
/* Ok! Someone deleted their lock, so now we can try
again. */
#ifdef DEBUG_PROPS
fprintf (stderr, "%s: (0x%x unlocked, trying again...)\n",
progname, (unsigned int) window);
#endif
break;
}
}
}
if (data)
XFree (data);
}
while (! locked);
#ifdef DIAGNOSTIC
if (waited)
fprintf (stderr, "%s: obtained lock.\n", progname);
#endif
return (0);
}
static void
mozilla_remote_free_lock (Display *dpy, Window window)
{
int result;
Atom actual_type;
int actual_format;
unsigned long nitems, bytes_after;
unsigned char *data = 0;
#ifdef DEBUG_PROPS
fprintf (stderr, "%s: (deleting " MOZILLA_LOCK_PROP
" \"%s\" from 0x%x)\n",
progname, lock_data, (unsigned int) window);
#endif
result = XGetWindowProperty (dpy, window, XA_MOZILLA_LOCK,
0, (65536 / sizeof (long)),
True, /* atomic delete after */
XA_STRING,
&actual_type, &actual_format,
&nitems, &bytes_after,
&data);
if (result != Success)
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: unable to read and delete " MOZILLA_LOCK_PROP
" property\n",
progname);
#endif
return;
}
else if (!data || !*data)
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: invalid data on " MOZILLA_LOCK_PROP
" of window 0x%x.\n",
progname, (unsigned int) window);
#endif
return;
}
else if (strcmp ((char *) data, lock_data))
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: " MOZILLA_LOCK_PROP
" was stolen! Expected \"%s\", saw \"%s\"!\n",
progname, lock_data, data);
#endif
return;
}
if (data)
XFree (data);
}
static int
mozilla_remote_command (Display *dpy, Window window, const char *command)
{
int result = 0;
Bool done = False;
#ifdef DEBUG_PROPS
fprintf (stderr, "%s: (writing " MOZILLA_COMMAND_PROP " \"%s\" to 0x%x)\n",
progname, command, (unsigned int) window);
#endif
XChangeProperty (dpy, window, XA_MOZILLA_COMMAND, XA_STRING, 8,
PropModeReplace, (unsigned char *) command,
strlen (command));
while (!done)
{
XEvent event;
XNextEvent (dpy, &event);
if (event.xany.type == DestroyNotify &&
event.xdestroywindow.window == window)
{
/* Print to warn user...*/
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: window 0x%x was destroyed.\n",
progname, (unsigned int) window);
#endif
result = 6;
goto DONE;
}
else if (event.xany.type == PropertyNotify &&
event.xproperty.state == PropertyNewValue &&
event.xproperty.window == window &&
event.xproperty.atom == XA_MOZILLA_RESPONSE)
{
Atom actual_type;
int actual_format;
unsigned long nitems, bytes_after;
unsigned char *data = 0;
result = XGetWindowProperty (dpy, window, XA_MOZILLA_RESPONSE,
0, (65536 / sizeof (long)),
True, /* atomic delete after */
XA_STRING,
&actual_type, &actual_format,
&nitems, &bytes_after,
&data);
#ifdef DEBUG_PROPS
if (result == Success && data && *data)
{
fprintf (stderr, "%s: (server sent " MOZILLA_RESPONSE_PROP
" \"%s\" to 0x%x.)\n",
progname, data, (unsigned int) window);
}
#endif
if (result != Success)
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: failed reading " MOZILLA_RESPONSE_PROP
" from window 0x%0x.\n",
progname, (unsigned int) window);
#endif
result = 6;
done = True;
}
else if (!data || strlen((char *) data) < 5)
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: invalid data on " MOZILLA_RESPONSE_PROP
" property of window 0x%0x.\n",
progname, (unsigned int) window);
#endif
result = 6;
done = True;
}
else if (*data == '1') /* positive preliminary reply */
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: %s\n", progname, data + 4);
#endif
/* keep going */
done = False;
}
#if 1
else if (!strncmp ((char *)data, "200", 3)) /* positive completion */
{
result = 0;
done = True;
}
#endif
else if (*data == '2') /* positive completion */
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: %s\n", progname, data + 4);
#endif
result = 0;
done = True;
}
else if (*data == '3') /* positive intermediate reply */
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: internal error: "
"server wants more information? (%s)\n",
progname, data);
#endif
result = 3;
done = True;
}
else if (*data == '4' || /* transient negative completion */
*data == '5') /* permanent negative completion */
{
#ifdef DIAGNOSTIC
fprintf (stderr, "%s: %s\n", progname, data + 4);
#endif
result = (*data - '0');
done = True;
}
else
{
#ifdef DIAGNOSTIC
fprintf (stderr,
"%s: unrecognised " MOZILLA_RESPONSE_PROP
" from window 0x%x: %s\n",
progname, (unsigned int) window, data);
#endif
result = 6;
done = True;
}
if (data)
XFree (data);
}
#ifdef DEBUG_PROPS
else if (event.xany.type == PropertyNotify &&
event.xproperty.window == window &&
event.xproperty.state == PropertyDelete &&
event.xproperty.atom == XA_MOZILLA_COMMAND)
{
fprintf (stderr, "%s: (server 0x%x has accepted "
MOZILLA_COMMAND_PROP ".)\n",
progname, (unsigned int) window);
}
#endif /* DEBUG_PROPS */
}
DONE:
return result;
}
static int
mozilla_remote (const gchar *command)
{
int status = 0;
Display *dpy;
Window window;
if (!(dpy = XOpenDisplay (NULL)))
return (0);
mozilla_remote_init_atoms (dpy);
if (!(window = mozilla_remote_find_window (dpy)))
return (0);
XSelectInput (dpy, window, (PropertyChangeMask|StructureNotifyMask));
if (mozilla_remote_obtain_lock (dpy, window))
return (0);
status = mozilla_remote_command (dpy, window, command);
/* When status = 6, it means the window has been destroyed */
/* It is invalid to free the lock when window is destroyed. */
if ( status != 6 )
mozilla_remote_free_lock (dpy, window);
return (!status);
}
#endif /* !G_OS_WIN32 */

View file

@ -135,6 +135,7 @@ plug-ins/common/vinvert.c
plug-ins/common/vpropagate.c plug-ins/common/vpropagate.c
plug-ins/common/warp.c plug-ins/common/warp.c
plug-ins/common/waves.c plug-ins/common/waves.c
plug-ins/common/webbrowser.c
plug-ins/common/whirlpinch.c plug-ins/common/whirlpinch.c
plug-ins/common/winclipboard.c plug-ins/common/winclipboard.c
plug-ins/common/wind.c plug-ins/common/wind.c

View file

@ -99,5 +99,5 @@ plug-ins/script-fu/scripts/truchet.scm
plug-ins/script-fu/scripts/unsharp-mask.scm plug-ins/script-fu/scripts/unsharp-mask.scm
plug-ins/script-fu/scripts/waves-anim.scm plug-ins/script-fu/scripts/waves-anim.scm
plug-ins/script-fu/scripts/weave.scm plug-ins/script-fu/scripts/weave.scm
plug-ins/script-fu/scripts/web-browser.scm
plug-ins/script-fu/scripts/xach-effect.scm plug-ins/script-fu/scripts/xach-effect.scm
plug-ins/webbrowser/web-browser.scm