summaryrefslogtreecommitdiff
path: root/src/gimp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gimp')
-rw-r--r--src/gimp/.cvsignore5
-rw-r--r--src/gimp/Makefile.am87
-rw-r--r--src/gimp/gimp_color_window.c581
-rw-r--r--src/gimp/gimp_main_window.c3314
-rw-r--r--src/gimp/print-image-gimp.c343
-rw-r--r--src/gimp/print-intl.h36
-rw-r--r--src/gimp/print.c1319
-rw-r--r--src/gimp/print_gimp.h124
8 files changed, 5809 insertions, 0 deletions
diff --git a/src/gimp/.cvsignore b/src/gimp/.cvsignore
new file mode 100644
index 0000000..dc31214
--- /dev/null
+++ b/src/gimp/.cvsignore
@@ -0,0 +1,5 @@
+.deps
+.libs
+Makefile
+Makefile.in
+print
diff --git a/src/gimp/Makefile.am b/src/gimp/Makefile.am
new file mode 100644
index 0000000..5ec8700
--- /dev/null
+++ b/src/gimp/Makefile.am
@@ -0,0 +1,87 @@
+## $Id: Makefile.am,v 1.18 2001/10/10 23:05:16 rlk Exp $
+## Copyright (C) 2000 Roger Leigh
+##
+## 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, 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.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.4 gnu
+
+@SET_MAKE@
+
+MAINT_CHARSET = latin1
+
+
+## Variables
+
+AM_CFLAGS = $(GNUCFLAGS)
+INCLUDES = @INCLUDES@ $(GIMP_CFLAGS) $(LIBGIMPPRINT_CFLAGS)
+LIBS = @LIBS@ ../../lib/libprintut.la $(INTLLIBS) ../../lib/libprintut.la
+
+libexecdir = $(gimptool_prefix)/plug-ins
+
+
+## Programs
+
+GIMP_BIN = print
+
+libexec_PROGRAMS = @GIMP_BIN@
+
+EXTRA_PROGRAMS = print
+
+print_SOURCES = \
+ print-image-gimp.c \
+ print-intl.h \
+ print.c \
+ gimp_color_window.c \
+ gimp_main_window.c \
+ print_gimp.h
+print_LDADD = $(GIMP_LIBS) $(LIBGIMPPRINT_LIBS) ../../lib/libprintut.la
+print_DEPENDENCIES = $(LIBGIMPPRINT_LIBS)
+
+
+## Rules
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @DESTDIR='$(DESTDIR)'; export DESTDIR;\
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ if test -f .libs/$$p; then \
+ cd .libs; \
+ fi; \
+ echo $(GIMPTOOL) --install-@PLUG_IN_PATH@ $$p; \
+ $(GIMPTOOL) --install-@PLUG_IN_PATH@ $$p; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @DESTDIR='$(DESTDIR)'; export DESTDIR;\
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ echo $(GIMPTOOL) --uninstall-@PLUG_IN_PATH@ "$$p"; \
+ $(GIMPTOOL) --uninstall-@PLUG_IN_PATH@ "$$p"; \
+ echo $(GIMPTOOL) --uninstall-admin-bin "$$p"; \
+ $(GIMPTOOL) --uninstall-admin-bin "$$p"; \
+ done; \
+ exit 0
+
+$(LIBGIMPPRINT_LIBS):
+ cd ../main ; \
+ $(MAKE)
+
+
+## Clean
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/gimp/gimp_color_window.c b/src/gimp/gimp_color_window.c
new file mode 100644
index 0000000..418f4f5
--- /dev/null
+++ b/src/gimp/gimp_color_window.c
@@ -0,0 +1,581 @@
+/*
+ * "$Id: gimp_color_window.c,v 1.19 2001/09/24 17:30:07 mitsch Exp $"
+ *
+ * Main window code for Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
+ * and Michael Natterer (mitch@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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "../../lib/libprintut.h"
+
+#include "print_gimp.h"
+
+#include "print-intl.h"
+#include <string.h>
+
+gint thumbnail_w, thumbnail_h, thumbnail_bpp;
+guchar *thumbnail_data;
+gint adjusted_thumbnail_bpp;
+guchar *adjusted_thumbnail_data;
+
+GtkWidget *gimp_color_adjust_dialog;
+
+static GtkObject *brightness_adjustment;
+static GtkObject *saturation_adjustment;
+static GtkObject *density_adjustment;
+static GtkObject *contrast_adjustment;
+static GtkObject *cyan_adjustment;
+static GtkObject *magenta_adjustment;
+static GtkObject *yellow_adjustment;
+static GtkObject *gamma_adjustment;
+
+GtkWidget *dither_algo_combo = NULL;
+static gint dither_algo_callback_id = -1;
+
+static void gimp_brightness_update (GtkAdjustment *adjustment);
+static void gimp_saturation_update (GtkAdjustment *adjustment);
+static void gimp_density_update (GtkAdjustment *adjustment);
+static void gimp_contrast_update (GtkAdjustment *adjustment);
+static void gimp_cyan_update (GtkAdjustment *adjustment);
+static void gimp_magenta_update (GtkAdjustment *adjustment);
+static void gimp_yellow_update (GtkAdjustment *adjustment);
+static void gimp_gamma_update (GtkAdjustment *adjustment);
+static void gimp_set_color_defaults (void);
+
+static void gimp_dither_algo_callback (GtkWidget *widget,
+ gpointer data);
+
+
+void gimp_build_dither_combo (void);
+
+static GtkDrawingArea *swatch = NULL;
+
+#define SWATCH_W (128)
+#define SWATCH_H (128)
+
+static char *
+c_strdup(const char *s)
+{
+ char *ret = malloc(strlen(s) + 1);
+ if (!s)
+ exit(1);
+ strcpy(ret, s);
+ return ret;
+}
+
+static void
+gimp_dither_algo_callback (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *new_algo =
+ gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dither_algo_combo)->entry));
+ int i;
+
+ for (i = 0; i < stp_dither_algorithm_count (); i ++)
+ if (strcasecmp (new_algo, stp_dither_algorithm_text (i)) == 0)
+ {
+ stp_set_dither_algorithm (*pv, stp_dither_algorithm_name (i));
+ break;
+ }
+}
+
+void
+gimp_build_dither_combo (void)
+{
+ int i;
+ stp_param_t *vec = xmalloc(sizeof(stp_param_t) * stp_dither_algorithm_count());
+
+ for (i = 0; i < stp_dither_algorithm_count(); i++)
+ {
+ vec[i].name = c_strdup (stp_dither_algorithm_name (i));
+ vec[i].text = c_strdup (stp_dither_algorithm_text (i));
+ }
+
+ gimp_plist_build_combo (dither_algo_combo,
+ stp_dither_algorithm_count (),
+ vec,
+ stp_get_dither_algorithm (*pv),
+ stp_default_dither_algorithm (),
+ &gimp_dither_algo_callback,
+ &dither_algo_callback_id);
+
+ for (i = 0; i < stp_dither_algorithm_count (); i++)
+ {
+ free ((void *) vec[i].name);
+ free ((void *) vec[i].text);
+ }
+ free (vec);
+}
+
+void
+gimp_redraw_color_swatch (void)
+{
+ static GdkGC *gc = NULL;
+ static GdkColormap *cmap;
+
+ if (swatch == NULL || swatch->widget.window == NULL)
+ return;
+
+#if 0
+ gdk_window_clear (swatch->widget.window);
+#endif
+
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (swatch->widget.window);
+ cmap = gtk_widget_get_colormap (GTK_WIDGET(swatch));
+ }
+
+ (adjusted_thumbnail_bpp == 1
+ ? gdk_draw_gray_image
+ : gdk_draw_rgb_image) (swatch->widget.window, gc,
+ (SWATCH_W - thumbnail_w) / 2,
+ (SWATCH_H - thumbnail_h) / 2,
+ thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL,
+ adjusted_thumbnail_data,
+ adjusted_thumbnail_bpp * thumbnail_w);
+}
+
+/*
+ * gimp_create_color_adjust_window (void)
+ *
+ * NOTES:
+ * creates the color adjuster popup, allowing the user to adjust brightness,
+ * contrast, saturation, etc.
+ */
+void
+gimp_create_color_adjust_window (void)
+{
+ GtkWidget *table;
+ GtkWidget *event_box;
+ const stp_vars_t lower = stp_minimum_settings ();
+ const stp_vars_t upper = stp_maximum_settings ();
+ const stp_vars_t defvars = stp_default_settings ();
+
+ /*
+ * Fetch a thumbnail of the image we're to print from the Gimp. This must
+ *
+ */
+
+ thumbnail_w = THUMBNAIL_MAXW;
+ thumbnail_h = THUMBNAIL_MAXH;
+ thumbnail_data = gimp_image_get_thumbnail_data (image_ID, &thumbnail_w,
+ &thumbnail_h, &thumbnail_bpp);
+
+ /*
+ * thumbnail_w and thumbnail_h have now been adjusted to the actual
+ * thumbnail dimensions. Now initialize a color-adjusted version of
+ * the thumbnail.
+ */
+
+ adjusted_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+
+ gimp_color_adjust_dialog =
+ gimp_dialog_new (_("Print Color Adjust"), "print",
+ gimp_standard_help_func, "filters/print.html",
+ GTK_WIN_POS_MOUSE, FALSE, TRUE, FALSE,
+
+ _("Set Defaults"), gimp_set_color_defaults,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Close"), gtk_widget_hide,
+ NULL, 1, NULL, TRUE, TRUE,
+
+ NULL);
+
+ table = gtk_table_new (10, 3, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 2, 6);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 5, 6);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 8, 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (gimp_color_adjust_dialog)->vbox),
+ table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Drawing area for color swatch feedback display...
+ */
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (GTK_WIDGET (event_box));
+ gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box),
+ 0, 3, 0, 1, 0, 0, 0, 0);
+
+ swatch = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_widget_set_events (GTK_WIDGET (swatch), GDK_EXPOSURE_MASK);
+ gtk_drawing_area_size (swatch, SWATCH_W, SWATCH_H);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (swatch));
+ gtk_widget_show (GTK_WIDGET (swatch));
+
+ gimp_help_set_help_data (GTK_WIDGET (event_box), _("Image preview"), NULL);
+ gtk_signal_connect (GTK_OBJECT (swatch), "expose_event",
+ GTK_SIGNAL_FUNC (gimp_redraw_color_swatch),
+ NULL);
+
+ /*
+ * Brightness slider...
+ */
+
+ brightness_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 1, _("Brightness:"), 200, 0,
+ stp_get_brightness (defvars),
+ stp_get_brightness (lower),
+ stp_get_brightness (upper),
+ stp_get_brightness (defvars) / 100,
+ stp_get_brightness (defvars) / 10,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (brightness_adjustment,
+ _("Set the brightness of the print.\n"
+ "0 is solid black, 2 is solid white"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (brightness_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_brightness_update),
+ NULL);
+
+ /*
+ * Contrast slider...
+ */
+
+ contrast_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 2, _("Contrast:"), 200, 0,
+ stp_get_contrast (defvars),
+ stp_get_contrast (lower),
+ stp_get_contrast (upper),
+ stp_get_contrast (defvars) / 100,
+ stp_get_contrast (defvars) / 10,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (contrast_adjustment,
+ _("Set the contrast of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (contrast_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_contrast_update),
+ NULL);
+
+ /*
+ * Cyan slider...
+ */
+
+ cyan_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 3, _("Cyan:"), 200, 0,
+ stp_get_cyan (defvars),
+ stp_get_cyan (lower),
+ stp_get_cyan (upper),
+ stp_get_cyan (defvars) / 100,
+ stp_get_cyan (defvars) / 10,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (cyan_adjustment,
+ _("Adjust the cyan balance of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (cyan_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_cyan_update),
+ NULL);
+
+ /*
+ * Magenta slider...
+ */
+
+ magenta_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 4, _("Magenta:"), 200, 0,
+ stp_get_magenta (defvars),
+ stp_get_magenta (lower),
+ stp_get_magenta (upper),
+ stp_get_magenta (defvars) / 100,
+ stp_get_magenta (defvars) / 10,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (magenta_adjustment,
+ _("Adjust the magenta balance of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (magenta_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_magenta_update),
+ NULL);
+
+ /*
+ * Yellow slider...
+ */
+
+ yellow_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 5, _("Yellow:"), 200, 0,
+ stp_get_yellow (defvars),
+ stp_get_yellow (lower),
+ stp_get_yellow (upper),
+ stp_get_yellow (defvars) / 100,
+ stp_get_yellow (defvars) / 10,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (yellow_adjustment,
+ _("Adjust the yellow balance of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (yellow_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_yellow_update),
+ NULL);
+
+ /*
+ * Saturation slider...
+ */
+
+ saturation_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 6, _("Saturation:"), 200, 0,
+ stp_get_saturation (defvars),
+ stp_get_saturation (lower),
+ stp_get_saturation (upper),
+ stp_get_saturation (defvars) / 1000,
+ stp_get_saturation (defvars) / 100,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (saturation_adjustment,
+ _("Adjust the saturation (color balance) of the print\n"
+ "Use zero saturation to produce grayscale output "
+ "using color and black inks"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (saturation_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_saturation_update),
+ NULL);
+
+ /*
+ * Density slider...
+ */
+
+ density_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 7, _("Density:"), 200, 0,
+ stp_get_density (defvars),
+ stp_get_density (lower),
+ stp_get_density (upper),
+ stp_get_density (defvars) / 1000,
+ stp_get_density (defvars) / 100,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (density_adjustment,
+ _("Adjust the density (amount of ink) of the print. "
+ "Reduce the density if the ink bleeds through the "
+ "paper or smears; increase the density if black "
+ "regions are not solid."),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (density_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_density_update),
+ NULL);
+
+ /*
+ * Gamma slider...
+ */
+
+ gamma_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 8, _("Gamma:"), 200, 0,
+ stp_get_gamma (defvars),
+ stp_get_gamma (lower),
+ stp_get_gamma (upper),
+ stp_get_gamma (defvars) / 1000,
+ stp_get_gamma (defvars) / 100,
+ 3, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (gamma_adjustment,
+ _("Adjust the gamma of the print. Larger values will "
+ "produce a generally brighter print, while smaller "
+ "values will produce a generally darker print. "
+ "Black and white will remain the same, unlike with "
+ "the brightness adjustment."),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (gamma_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_gamma_update),
+ NULL);
+
+ /*
+ * Dither algorithm option combo...
+ */
+
+ event_box = gtk_event_box_new ();
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 9,
+ _("Dither Algorithm:"), 1.0, 0.5,
+ event_box, 1, TRUE);
+
+ dither_algo_combo = gtk_combo_new ();
+ gtk_container_add (GTK_CONTAINER(event_box), dither_algo_combo);
+ gtk_widget_show (dither_algo_combo);
+
+ gimp_help_set_help_data (GTK_WIDGET (event_box),
+ _("Choose the dither algorithm to be used.\n"
+ "Adaptive Hybrid usually produces the best "
+ "all-around quality.\n"
+ "Ordered is faster and produces almost as good "
+ "quality on photographs.\n"
+ "Fast and Very Fast are considerably faster, and "
+ "work well for text and line art.\n"
+ "Hybrid Floyd-Steinberg generally produces "
+ "inferior output."),
+ NULL);
+
+ gimp_build_dither_combo ();
+}
+
+static void
+gimp_brightness_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+ if (stp_get_brightness (*pv) != adjustment->value)
+ {
+ stp_set_brightness (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_contrast_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_contrast (*pv) != adjustment->value)
+ {
+ stp_set_contrast (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_cyan_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_cyan (*pv) != adjustment->value)
+ {
+ stp_set_cyan (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_magenta_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_magenta (*pv) != adjustment->value)
+ {
+ stp_set_magenta (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_yellow_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_yellow (*pv) != adjustment->value)
+ {
+ stp_set_yellow (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_saturation_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_saturation (*pv) != adjustment->value)
+ {
+ stp_set_saturation (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_density_update (GtkAdjustment *adjustment)
+{
+ if (stp_get_density (*pv) != adjustment->value)
+ {
+ stp_set_density (*pv, adjustment->value);
+ }
+}
+
+static void
+gimp_gamma_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+
+ if (stp_get_gamma (*pv) != adjustment->value)
+ {
+ stp_set_gamma (*pv, adjustment->value);
+ gimp_update_adjusted_thumbnail ();
+ }
+}
+
+static void
+gimp_set_adjustment_active (GtkObject *adj,
+ gboolean active)
+{
+ gtk_widget_set_sensitive (GTK_WIDGET (GIMP_SCALE_ENTRY_LABEL (adj)), active);
+ gtk_widget_set_sensitive (GTK_WIDGET (GIMP_SCALE_ENTRY_SCALE (adj)), active);
+ gtk_widget_set_sensitive (GTK_WIDGET (GIMP_SCALE_ENTRY_SPINBUTTON (adj)),
+ active);
+}
+
+void
+gimp_set_color_sliders_active (gboolean active)
+{
+ gimp_set_adjustment_active (cyan_adjustment, active);
+ gimp_set_adjustment_active (magenta_adjustment, active);
+ gimp_set_adjustment_active (yellow_adjustment, active);
+ gimp_set_adjustment_active (saturation_adjustment, active);
+}
+
+void
+gimp_do_color_updates (void)
+{
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (brightness_adjustment),
+ stp_get_brightness (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (gamma_adjustment),
+ stp_get_gamma (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (contrast_adjustment),
+ stp_get_contrast (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (cyan_adjustment),
+ stp_get_cyan (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (magenta_adjustment),
+ stp_get_magenta (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (yellow_adjustment),
+ stp_get_yellow (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (saturation_adjustment),
+ stp_get_saturation (*pv));
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (density_adjustment),
+ stp_get_density (*pv));
+
+ gimp_update_adjusted_thumbnail ();
+}
+
+void
+gimp_set_color_defaults (void)
+{
+ const stp_vars_t defvars = stp_default_settings ();
+
+ stp_set_brightness (*pv, stp_get_brightness (defvars));
+ stp_set_gamma (*pv, stp_get_gamma (defvars));
+ stp_set_contrast (*pv, stp_get_contrast (defvars));
+ stp_set_cyan (*pv, stp_get_cyan (defvars));
+ stp_set_magenta (*pv, stp_get_magenta (defvars));
+ stp_set_yellow (*pv, stp_get_yellow (defvars));
+ stp_set_saturation (*pv, stp_get_saturation (defvars));
+ stp_set_density (*pv, stp_get_density (defvars));
+
+ gimp_do_color_updates ();
+}
diff --git a/src/gimp/gimp_main_window.c b/src/gimp/gimp_main_window.c
new file mode 100644
index 0000000..538f7e3
--- /dev/null
+++ b/src/gimp/gimp_main_window.c
@@ -0,0 +1,3314 @@
+/*
+ * "$Id: gimp_main_window.c,v 1.54 2001/10/15 23:45:37 rlk Exp $"
+ *
+ * Main window code for Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
+ * and Michael Natterer (mitch@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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "../../lib/libprintut.h"
+
+#define MAX_PREVIEW_PPI (40)
+
+#include "print_gimp.h"
+
+#include "print-intl.h"
+#include <string.h>
+
+/*
+ * Constants for GUI.
+ */
+#define PREVIEW_SIZE_VERT 360
+#define PREVIEW_SIZE_HORIZ 260
+#define MOVE_CONSTRAIN 0
+#define MOVE_HORIZONTAL 1
+#define MOVE_VERTICAL 2
+#define MOVE_ANY (MOVE_HORIZONTAL | MOVE_VERTICAL)
+
+/*
+ * Main window widgets
+ */
+
+static GtkWidget *main_vbox;
+static GtkWidget *main_hbox;
+static GtkWidget *right_vbox;
+static GtkWidget *notebook;
+
+static GtkWidget *print_dialog; /* Print dialog window */
+static GtkWidget *recenter_button;
+static GtkWidget *recenter_vertical_button;
+static GtkWidget *recenter_horizontal_button;
+static GtkWidget *left_entry;
+static GtkWidget *right_entry;
+static GtkWidget *right_border_entry;
+static GtkWidget *width_entry;
+static GtkWidget *top_entry;
+static GtkWidget *bottom_entry;
+static GtkWidget *bottom_border_entry;
+static GtkWidget *height_entry;
+static GtkWidget *unit_inch;
+static GtkWidget *unit_cm;
+static GtkWidget *media_size_combo = NULL; /* Media size combo box */
+static GtkWidget *custom_size_width = NULL;
+static GtkWidget *custom_size_height = NULL;
+static gint media_size_callback_id = -1;
+static GtkWidget *media_type_combo = NULL; /* Media type combo box */
+static gint media_type_callback_id = -1; /* Media type calback ID */
+static GtkWidget *media_source_combo = NULL; /* Media source combo box */
+static gint media_source_callback_id = -1; /* Media source calback ID */
+static GtkWidget *ink_type_combo = NULL; /* Ink type combo box */
+static gint ink_type_callback_id = -1; /* Ink type calback ID */
+static GtkWidget *resolution_combo = NULL; /* Resolution combo box */
+static gint resolution_callback_id = -1; /* Resolution calback ID */
+static GtkWidget *orientation_menu = NULL; /* Orientation menu */
+static GtkWidget *scaling_percent; /* Scale by percent */
+static GtkWidget *scaling_ppi; /* Scale by pixels-per-inch */
+static GtkWidget *scaling_image; /* Scale to the image */
+static GtkWidget *output_gray; /* Output type toggle, black */
+static GtkWidget *output_color; /* Output type toggle, color */
+static GtkWidget *output_monochrome;
+static GtkWidget *image_line_art;
+static GtkWidget *image_solid_tone;
+static GtkWidget *image_continuous_tone;
+static GtkWidget *setup_dialog; /* Setup dialog window */
+static GtkWidget *printer_driver; /* Printer driver widget */
+static GtkWidget *printer_model_label; /* Printer model name */
+static GtkWidget *printer_crawler; /* Scrolled Window for menu */
+static GtkWidget *printer_combo; /* Combo for menu */
+static gint plist_callback_id = -1;
+static GtkWidget *ppd_file; /* PPD file entry */
+static GtkWidget *ppd_label; /* PPD file entry */
+static GtkWidget *ppd_button; /* PPD file browse button */
+static GtkWidget *output_cmd; /* Output command text entry */
+static GtkWidget *ppd_browser; /* File selection dialog for PPD files */
+static GtkWidget *new_printer_dialog; /* New printer dialog window */
+static GtkWidget *new_printer_entry; /* New printer text entry */
+
+static GtkWidget *file_browser; /* FSD for print files */
+static GtkWidget *adjust_color_button;
+static GtkWidget *about_dialog;
+
+static GtkObject *scaling_adjustment; /* Adjustment object for scaling */
+static gboolean suppress_scaling_adjustment = FALSE;
+static gboolean suppress_scaling_callback = FALSE;
+
+static gint suppress_preview_update = 0;
+
+static gint preview_valid = 0;
+static gint frame_valid = 0;
+static gint need_exposure = 0;
+
+static GtkDrawingArea *preview = NULL; /* Preview drawing area widget */
+static gint mouse_x; /* Last mouse X */
+static gint mouse_y; /* Last mouse Y */
+static gint old_top; /* Previous position */
+static gint old_left; /* Previous position */
+static gint buttons_pressed = 0;
+static gint preview_active = 0;
+static gint buttons_mask = 0;
+static gint move_constraint = 0;
+static gint mouse_button = -1; /* Button being dragged with */
+static gint suppress_preview_reset = 0;
+
+static gint printable_left; /* Left pixel column of page */
+static gint printable_top; /* Top pixel row of page */
+static gint printable_width; /* Width of page on screen */
+static gint printable_height; /* Height of page on screen */
+static gint print_width; /* Printed width of image */
+static gint print_height; /* Printed height of image */
+static gint left, right; /* Imageable area */
+static gint top, bottom;
+static gint paper_width, paper_height; /* Physical width */
+
+static gint num_media_sizes = 0;
+static stp_param_t *media_sizes;
+static gint num_media_types = 0; /* Number of media types */
+static stp_param_t *media_types; /* Media type strings */
+static gint num_media_sources = 0; /* Number of media sources */
+static stp_param_t *media_sources; /* Media source strings */
+static gint num_ink_types = 0; /* Number of ink types */
+static stp_param_t *ink_types; /* Ink type strings */
+static gint num_resolutions = 0; /* Number of resolutions */
+static stp_param_t *resolutions; /* Resolution strings */
+
+static void gimp_scaling_update (GtkAdjustment *adjustment);
+static void gimp_scaling_callback (GtkWidget *widget);
+static void gimp_plist_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_media_size_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_media_type_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_media_source_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_ink_type_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_resolution_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_output_type_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_unit_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_orientation_callback (GtkWidget *widget,
+ gpointer data);
+static void gimp_printandsave_callback (void);
+static void gimp_about_callback (void);
+static void gimp_print_callback (void);
+static void gimp_save_callback (void);
+
+static void gimp_setup_update (void);
+static void gimp_setup_open_callback (void);
+static void gimp_setup_ok_callback (void);
+static void gimp_new_printer_open_callback (void);
+static void gimp_new_printer_ok_callback (void);
+static void gimp_ppd_browse_callback (void);
+static void gimp_ppd_ok_callback (void);
+static void gimp_print_driver_callback (GtkWidget *widget,
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data);
+
+static void gimp_file_ok_callback (void);
+static void gimp_file_cancel_callback (void);
+
+static void gimp_preview_update (void);
+static void gimp_preview_expose (void);
+static void gimp_preview_button_callback (GtkWidget *widget,
+ GdkEventButton *bevent,
+ gpointer data);
+static void gimp_preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *mevent,
+ gpointer data);
+static void gimp_position_callback (GtkWidget *widget);
+static void gimp_image_type_callback (GtkWidget *widget,
+ gpointer data);
+
+static gdouble preview_ppi = 10;
+stp_vars_t *pv;
+
+#define Combo_get_text(combo) \
+ (gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)))
+
+void
+set_adjustment_tooltip (GtkObject *adj,
+ const gchar *tip,
+ const gchar *private)
+{
+ gimp_help_set_help_data (GTK_WIDGET (GIMP_SCALE_ENTRY_SCALE (adj)),
+ tip, private);
+ gimp_help_set_help_data (GTK_WIDGET (GIMP_SCALE_ENTRY_SPINBUTTON (adj)),
+ tip, private);
+}
+
+static const char *
+Combo_get_name(GtkWidget *combo,
+ gint num_options,
+ stp_param_t *options)
+{
+ gchar *text;
+ gint i;
+
+ if ((text = Combo_get_text(combo)) == NULL)
+ return (NULL);
+
+ if (num_options == 0)
+ return ((const char *)text);
+
+ for (i = 0; i < num_options; i ++)
+ if (strcasecmp(options[i].text, text) == 0)
+ return (options[i].name);
+
+ return (NULL);
+}
+
+
+static gchar *
+c_strdup(const gchar *s)
+{
+ gchar *ret = xmalloc(strlen(s) + 1);
+ strcpy(ret, s);
+ return ret;
+}
+
+static stp_param_t *printer_list = 0;
+static int printer_count = 0;
+
+static void
+reset_preview(void)
+{
+ if (!suppress_preview_reset)
+ {
+ gimp_help_enable_tooltips();
+ buttons_pressed = preview_active = 0;
+ }
+}
+
+static void
+set_entry_value(GtkWidget *entry, double value, int block)
+{
+ gchar s[255];
+ g_snprintf(s, sizeof(s), "%.2f", value);
+ if (block)
+ gtk_signal_handler_block_by_data (GTK_OBJECT (entry), NULL);
+ gtk_entry_set_text (GTK_ENTRY (entry), s);
+ if (block)
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (entry), NULL);
+}
+
+static void
+gimp_build_printer_combo(void)
+{
+ int i;
+ if (printer_list)
+ {
+ for (i = 0; i < printer_count; i++)
+ {
+ free((void *)printer_list[i].name);
+ free((void *)printer_list[i].text);
+ }
+ free(printer_list);
+ }
+ printer_list = malloc(sizeof(stp_param_t) * plist_count);
+ for (i = 0; i < plist_count; i++)
+ {
+ if (plist[i].active)
+ {
+ printer_list[i].name = c_strdup(plist[i].name);
+ printer_list[i].text = c_strdup(plist[i].name);
+ }
+ else
+ {
+ printer_list[i].name = malloc(strlen(plist[i].name) + 2);
+ printer_list[i].text = malloc(strlen(plist[i].name) + 2);
+ strcpy((char *)printer_list[i].name + 1, plist[i].name);
+ ((char *)printer_list[i].name)[0] = '*';
+ strcpy((char *)printer_list[i].text + 1, plist[i].name);
+ ((char *)printer_list[i].text)[0] = '*';
+ }
+ }
+ printer_count = plist_count;
+ gimp_plist_build_combo(printer_combo,
+ printer_count,
+ printer_list,
+ printer_list[plist_current].text,
+ NULL,
+ gimp_plist_callback,
+ &plist_callback_id);
+}
+
+static void
+create_top_level_structure(void)
+{
+ gchar *plug_in_name;
+ /*
+ * Create the main dialog
+ */
+
+ plug_in_name = g_strdup_printf (_("%s -- Print v%s"),
+ image_filename, PLUG_IN_VERSION);
+
+ print_dialog =
+ gimp_dialog_new (plug_in_name, "print",
+ gimp_standard_help_func, "filters/print.html",
+ GTK_WIN_POS_MOUSE,
+ FALSE, TRUE, FALSE,
+
+ _("About"), gimp_about_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print and\nSave Settings"), gimp_printandsave_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Save\nSettings"), gimp_save_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print"), gimp_print_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Cancel"), gtk_widget_destroy,
+ NULL, 1, NULL, FALSE, TRUE,
+
+ NULL);
+
+ g_free (plug_in_name);
+
+ gtk_signal_connect (GTK_OBJECT (print_dialog), "destroy",
+ GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+
+ /*
+ * Top-level containers
+ */
+
+ main_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (print_dialog)->vbox), main_vbox,
+ FALSE, FALSE, 0);
+ gtk_widget_show (main_vbox);
+
+ main_hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, FALSE, FALSE, 0);
+ gtk_widget_show (main_hbox);
+
+ right_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_end (GTK_BOX (main_hbox), right_vbox, TRUE, TRUE, 0);
+ gtk_widget_show (right_vbox);
+
+ notebook = gtk_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (right_vbox), notebook, FALSE, FALSE, 0);
+ gtk_widget_show (notebook);
+}
+
+static void
+create_preview (void)
+{
+ GtkWidget *frame;
+ GtkWidget *event_box;
+
+ frame = gtk_frame_new (_("Preview"));
+ gtk_box_pack_start (GTK_BOX (main_hbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ preview = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_drawing_area_size (preview, PREVIEW_SIZE_HORIZ + 1,
+ PREVIEW_SIZE_VERT + 1);
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (preview));
+ gtk_container_add (GTK_CONTAINER (frame), event_box);
+ gtk_widget_show (event_box);
+
+ gtk_signal_connect (GTK_OBJECT (preview), "expose_event",
+ GTK_SIGNAL_FUNC (gimp_preview_expose), NULL);
+ gtk_signal_connect (GTK_OBJECT (preview), "button_press_event",
+ GTK_SIGNAL_FUNC (gimp_preview_button_callback), NULL);
+ gtk_signal_connect (GTK_OBJECT (preview), "button_release_event",
+ GTK_SIGNAL_FUNC (gimp_preview_button_callback), NULL);
+ gtk_signal_connect (GTK_OBJECT (preview), "motion_notify_event",
+ GTK_SIGNAL_FUNC (gimp_preview_motion_callback), NULL);
+ gtk_widget_show (GTK_WIDGET (preview));
+
+ gimp_help_set_help_data
+ (event_box,
+ _("Position the image on the page.\n"
+ "Click and drag with the primary button to position the image.\n"
+ "Click and drag with the second button to move the image with finer precision; "
+ "each unit of motion moves the image one point (1/72\")\n"
+ "Click and drag with the third (middle) button to move the image in units of "
+ "the image size.\n"
+ "Holding down the shift key while clicking and dragging constrains the image to "
+ "only horizontal or vertical motion.\n"
+ "If you click another button while dragging the mouse, the image will return "
+ "to its original position."),
+ NULL);
+
+ gtk_widget_set_events (GTK_WIDGET (preview),
+ GDK_EXPOSURE_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK);
+}
+
+static void
+create_positioning_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *sep;
+
+ frame = gtk_frame_new (_("Position"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (7, 4, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacing (GTK_TABLE (table), 1, 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ /*
+ * Orientation option menu.
+ */
+
+ orientation_menu =
+ gimp_option_menu_new (FALSE,
+ _("Auto"), gimp_orientation_callback,
+ (gpointer) ORIENT_AUTO, NULL, NULL, 0,
+ _("Portrait"), gimp_orientation_callback,
+ (gpointer) ORIENT_PORTRAIT, NULL, NULL, 0,
+ _("Landscape"), gimp_orientation_callback,
+ (gpointer) ORIENT_LANDSCAPE, NULL, NULL, 0,
+ _("Upside down"), gimp_orientation_callback,
+ (gpointer) ORIENT_UPSIDEDOWN, NULL, NULL, 0,
+ _("Seascape"), gimp_orientation_callback,
+ (gpointer) ORIENT_SEASCAPE, NULL, NULL, 0,
+ NULL);
+ gimp_help_set_help_data (orientation_menu,
+ _("Select the orientation: portrait, landscape, "
+ "upside down, or seascape (upside down "
+ "landscape)"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ _("Orientation:"), 1.0, 0.5,
+ orientation_menu, 3, TRUE);
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 4, 1, 2);
+ gtk_widget_show (sep);
+
+ /*
+ * Position entries
+ */
+
+ left_entry = gtk_entry_new ();
+ gtk_widget_set_usize (left_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
+ _("Left:"), 1.0, 0.5,
+ left_entry, 1, TRUE);
+
+ gimp_help_set_help_data (left_entry,
+ _("Distance from the left of the paper to the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (left_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ top_entry = gtk_entry_new ();
+ gtk_widget_set_usize (top_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 2, 2,
+ _("Top:"), 1.0,
+ 0.5, top_entry, 1, TRUE);
+
+ gimp_help_set_help_data (top_entry,
+ _("Distance from the top of the paper to the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (top_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ right_entry = gtk_entry_new ();
+ gtk_widget_set_usize (right_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
+ _("Right:"), 1.0, 0.5,
+ right_entry, 1, TRUE);
+
+ gimp_help_set_help_data (right_entry,
+ _("Distance from the left of the paper to "
+ "the right of the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (right_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ right_border_entry = gtk_entry_new ();
+ gtk_widget_set_usize (right_border_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
+ _("Right Border:"), 1.0, 0.5,
+ right_border_entry, 1, TRUE);
+
+ gimp_help_set_help_data (right_border_entry,
+ _("Distance from the right of the paper to "
+ "the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (right_border_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ bottom_entry = gtk_entry_new ();
+ gtk_widget_set_usize (bottom_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 2, 3,
+ _("Bottom:"), 1.0, 0.5,
+ bottom_entry, 1, TRUE);
+
+ gimp_help_set_help_data (bottom_entry,
+ _("Distance from the top of the paper to "
+ "the bottom of the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (bottom_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ bottom_border_entry = gtk_entry_new ();
+ gtk_widget_set_usize (bottom_border_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 2, 4,
+ _("Bottom Border:"), 1.0, 0.5,
+ bottom_border_entry, 1, TRUE);
+
+ gimp_help_set_help_data (bottom_border_entry,
+ _("Distance from the bottom of the paper to "
+ "the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (bottom_border_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 4, 5, 6);
+ gtk_widget_show (sep);
+
+ /*
+ * Center options
+ */
+
+ box = gtk_hbox_new (TRUE, 4);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 6,
+ _("Center:"), 1.0, 0.5,
+ box, 3, FALSE);
+
+ recenter_vertical_button =
+ gtk_button_new_with_label (_("Vertically"));
+ gtk_box_pack_start (GTK_BOX (box), recenter_vertical_button, FALSE, TRUE, 0);
+ gtk_widget_show (recenter_vertical_button);
+
+ gimp_help_set_help_data (recenter_vertical_button,
+ _("Center the image vertically on the paper"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (recenter_vertical_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ recenter_button = gtk_button_new_with_label (_("Both"));
+ gtk_box_pack_start (GTK_BOX (box), recenter_button, FALSE, TRUE, 0);
+ gtk_widget_show (recenter_button);
+
+ gimp_help_set_help_data (recenter_button,
+ _("Center the image on the paper"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (recenter_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ recenter_horizontal_button =
+ gtk_button_new_with_label (_("Horizontally"));
+ gtk_box_pack_start (GTK_BOX (box), recenter_horizontal_button, FALSE, TRUE, 0);
+ gtk_widget_show (recenter_horizontal_button);
+
+ gimp_help_set_help_data (recenter_horizontal_button,
+ _("Center the image horizontally on the paper"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (recenter_horizontal_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+}
+
+static void
+create_printer_dialog (void)
+{
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ gint i;
+
+ setup_dialog = gimp_dialog_new (_("Setup Printer"), "print",
+ gimp_standard_help_func, "filters/print.html",
+ GTK_WIN_POS_MOUSE, FALSE, TRUE, FALSE,
+
+ _("OK"), gimp_setup_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), gtk_widget_hide,
+ NULL, 1, NULL, FALSE, TRUE,
+
+ NULL);
+
+ /*
+ * Top-level table for dialog.
+ */
+
+ table = gtk_table_new (5, 2, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 8);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 0, 100);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (setup_dialog)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Printer driver option menu.
+ */
+
+ label = gtk_label_new (_("Printer Model:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 1, 3, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ gimp_help_set_help_data (event_box,
+ _("Select your printer model"),
+ NULL);
+
+ printer_crawler = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (printer_crawler),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (event_box), printer_crawler);
+ gtk_widget_show (printer_crawler);
+
+ printer_driver = gtk_clist_new (1);
+ gtk_widget_set_usize (printer_driver, 200, 0);
+ gtk_clist_set_selection_mode (GTK_CLIST (printer_driver),
+ GTK_SELECTION_SINGLE);
+ gtk_container_add (GTK_CONTAINER (printer_crawler), printer_driver);
+ gtk_widget_show (printer_driver);
+
+ gtk_signal_connect (GTK_OBJECT (printer_driver), "select_row",
+ GTK_SIGNAL_FUNC (gimp_print_driver_callback),
+ NULL);
+
+ for (i = 0; i < stp_known_printers (); i ++)
+ {
+ stp_printer_t the_printer = stp_get_printer_by_index (i);
+
+ if (strcmp (stp_printer_get_long_name (the_printer), "") != 0)
+ {
+ gchar *tmp =
+ c_strdup (gettext (stp_printer_get_long_name (the_printer)));
+
+ gtk_clist_insert (GTK_CLIST (printer_driver), i, &tmp);
+ gtk_clist_set_row_data (GTK_CLIST (printer_driver), i, (gpointer) i);
+ }
+ }
+
+ /*
+ * PPD file.
+ */
+
+ ppd_label = gtk_label_new (_("PPD File:"));
+ gtk_misc_set_alignment (GTK_MISC (ppd_label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), ppd_label, 0, 1, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (ppd_label);
+
+ box = gtk_hbox_new (FALSE, 8);
+ gtk_table_attach (GTK_TABLE (table), box, 1, 2, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (box);
+
+ ppd_file = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (box), ppd_file, TRUE, TRUE, 0);
+ gtk_widget_show (ppd_file);
+
+ gimp_help_set_help_data (ppd_file,
+ _("Enter the correct PPD filename for your printer"),
+ NULL);
+
+ ppd_button = gtk_button_new_with_label (_("Browse"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (ppd_button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (box), ppd_button, FALSE, FALSE, 0);
+ gtk_widget_show (ppd_button);
+
+ gimp_help_set_help_data (ppd_button,
+ _("Choose the correct PPD filename for your printer"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (ppd_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_ppd_browse_callback),
+ NULL);
+
+ /*
+ * Print command.
+ */
+
+ label = gtk_label_new (_("Command:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ output_cmd = gtk_entry_new ();
+ gtk_table_attach (GTK_TABLE (table), output_cmd, 1, 2, 2, 3,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (output_cmd);
+
+ gimp_help_set_help_data
+ (output_cmd,
+ _("Enter the correct command to print to your printer. "
+ "Note: Please do not remove the `-l' or `-oraw' from "
+ "the command string, or printing will probably fail!"),
+ NULL);
+
+ /*
+ * Output file selection dialog.
+ */
+
+ file_browser = gtk_file_selection_new (_("Print To File?"));
+
+ gtk_signal_connect
+ (GTK_OBJECT (GTK_FILE_SELECTION (file_browser)->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_file_ok_callback),
+ NULL);
+ gtk_signal_connect
+ (GTK_OBJECT (GTK_FILE_SELECTION (file_browser)->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_file_cancel_callback),
+ NULL);
+
+ /*
+ * PPD file selection dialog.
+ */
+
+ ppd_browser = gtk_file_selection_new (_("PPD File?"));
+ gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (ppd_browser));
+
+ gtk_signal_connect
+ (GTK_OBJECT (GTK_FILE_SELECTION (ppd_browser)->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_ppd_ok_callback),
+ NULL);
+ gtk_signal_connect_object
+ (GTK_OBJECT (GTK_FILE_SELECTION (ppd_browser)->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_hide),
+ GTK_OBJECT (ppd_browser));
+}
+
+static void
+create_new_printer_dialog (void)
+{
+ GtkWidget *table;
+
+ new_printer_dialog =
+ gimp_dialog_new (_("Define New Printer"), "print",
+ gimp_standard_help_func, "filters/print.html",
+ GTK_WIN_POS_MOUSE, FALSE, TRUE, FALSE,
+
+ _("OK"), gimp_new_printer_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), gtk_widget_hide,
+ NULL, 1, NULL, FALSE, TRUE,
+
+ NULL);
+
+ table = gtk_table_new (1, 2, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 8);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (new_printer_dialog)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ new_printer_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (new_printer_entry), 127);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, _("Printer Name:"), 1.0,
+ 0.5, new_printer_entry, 1, TRUE);
+
+ gimp_help_set_help_data (new_printer_entry,
+ _("Enter the name you wish to give this logical printer"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (new_printer_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_new_printer_ok_callback),
+ NULL);
+}
+
+static void
+create_about_dialog (void)
+{
+ GtkWidget *label;
+ about_dialog =
+ gimp_dialog_new (_("About Gimp-Print " PLUG_IN_VERSION), "print",
+ gimp_standard_help_func, "filters/print.html",
+ GTK_WIN_POS_MOUSE, FALSE, TRUE, FALSE,
+
+ _("OK"), gtk_widget_hide,
+ NULL, 1, NULL, TRUE, TRUE,
+
+ NULL);
+
+ label = gtk_label_new
+ (_("Gimp-Print Version " PLUG_IN_VERSION "\n"
+ "\n"
+ "Copyright (C) 1997-2001 Michael Sweet, Robert Krawitz,\n"
+ "and the rest of the Gimp-Print Development Team.\n"
+ "\n"
+ "Please visit our web site at http://gimp-print.sourceforge.net.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation; either version 2 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
+ "USA\n"));
+
+ gtk_misc_set_padding (GTK_MISC (label), 12, 4);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_dialog)->vbox), label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+static void
+create_printer_settings_frame (void)
+{
+ GtkWidget *table;
+ GtkWidget *printer_hbox;
+ GtkWidget *media_size_hbox;
+ GtkWidget *button;
+ GtkWidget *label;
+ GtkWidget *event_box;
+
+ create_printer_dialog ();
+ create_about_dialog ();
+ create_new_printer_dialog ();
+
+ table = gtk_table_new (9, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
+ table,
+ gtk_label_new (_("Printer Settings")));
+ gtk_widget_show (table);
+
+ /*
+ * Printer option menu.
+ */
+
+ printer_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), printer_combo);
+ gtk_widget_show (printer_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Select the name of the printer (not the type, "
+ "or model, of printer) that you wish to print to"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ _("Printer Name:"), 1.0, 0.5,
+ event_box, 2, TRUE);
+
+ printer_model_label = gtk_label_new ("");
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ _("Printer Model:"), 1.0, 0.5,
+ printer_model_label, 2, TRUE);
+
+ printer_hbox = gtk_hbox_new (TRUE, 4);
+ gtk_table_attach_defaults (GTK_TABLE (table), printer_hbox, 1, 2, 2, 3);
+ gtk_widget_show (printer_hbox);
+
+ /*
+ * Setup printer button
+ */
+
+ button = gtk_button_new_with_label (_("Setup Printer..."));
+ gimp_help_set_help_data (button,
+ _("Choose the printer model, PPD file, and command "
+ "that is used to print to this printer"),
+ NULL);
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_setup_open_callback),
+ NULL);
+
+ /*
+ * New printer button
+ */
+
+ button = gtk_button_new_with_label (_("New Printer..."));
+ gimp_help_set_help_data (button,
+ _("Define a new logical printer. This can be used to "
+ "name a collection of settings that you wish to "
+ "remember for future use."),
+ NULL);
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (gimp_new_printer_open_callback),
+ NULL);
+
+ /*
+ * Media size combo box.
+ */
+
+ media_size_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), media_size_combo);
+ gtk_widget_show (media_size_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Size of paper that you wish to print to"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
+ _("Media Size:"), 1.0, 0.5,
+ event_box, 1, TRUE);
+
+ /*
+ * Custom media size entries
+ */
+
+ media_size_hbox = gtk_hbox_new (FALSE, 4);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
+ _("Dimensions:"), 1.0, 0.5,
+ media_size_hbox, 2, TRUE);
+
+ label = gtk_label_new (_("Width:"));
+ gtk_box_pack_start (GTK_BOX (media_size_hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ custom_size_width = gtk_entry_new ();
+ gtk_widget_set_usize (custom_size_width, 40, 0);
+ gtk_box_pack_start (GTK_BOX (media_size_hbox), custom_size_width,
+ FALSE, FALSE, 0);
+ gtk_widget_show (custom_size_width);
+
+ gimp_help_set_help_data (custom_size_width,
+ _("Width of the paper that you wish to print to"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (custom_size_width), "activate",
+ GTK_SIGNAL_FUNC (gimp_media_size_callback),
+ NULL);
+
+ label = gtk_label_new (_("Height:"));
+ gtk_box_pack_start (GTK_BOX (media_size_hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ custom_size_height = gtk_entry_new ();
+ gtk_widget_set_usize (custom_size_height, 50, 0);
+ gtk_box_pack_start (GTK_BOX (media_size_hbox), custom_size_height,
+ FALSE, FALSE, 0);
+ gtk_widget_show (custom_size_height);
+
+ gimp_help_set_help_data (custom_size_height,
+ _("Height of the paper that you wish to print to"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (custom_size_height), "activate",
+ GTK_SIGNAL_FUNC (gimp_media_size_callback),
+ NULL);
+
+ /*
+ * Media type combo box.
+ */
+
+ media_type_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), media_type_combo);
+ gtk_widget_show (media_type_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Type of media you're printing to"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 5,
+ _("Media Type:"), 1.0, 0.5,
+ event_box, 2, TRUE);
+
+ /*
+ * Media source combo box.
+ */
+
+ media_source_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), media_source_combo);
+ gtk_widget_show (media_source_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Source (input slot) of media you're printing to"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 6,
+ _("Media Source:"), 1.0, 0.5,
+ event_box, 2, TRUE);
+
+ /*
+ * Ink type combo box.
+ */
+
+ ink_type_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), ink_type_combo);
+ gtk_widget_show (ink_type_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Type of ink in the printer"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 7,
+ _("Ink Type:"), 1.0, 0.5,
+ event_box, 2, TRUE);
+
+ /*
+ * Resolution combo box.
+ */
+
+ resolution_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), resolution_combo);
+ gtk_widget_show (resolution_combo);
+
+ gimp_help_set_help_data (event_box,
+ _("Resolution and quality of the print"),
+ NULL);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 8,
+ _("Resolution:"), 1.0, 0.5,
+ event_box, 2, TRUE);
+}
+
+static void
+create_scaling_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+
+ frame = gtk_frame_new (_("Size"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Create the scaling adjustment using percent. It doesn't really matter,
+ * since as soon as we call gimp_plist_callback at the end of initialization
+ * everything will be put right.
+ */
+ scaling_adjustment =
+ gimp_scale_entry_new (GTK_TABLE (table), 0, 0, _("Scaling:"), 100, 75,
+ stp_get_scaling (stp_default_settings ()),
+ stp_get_scaling (stp_minimum_settings ()),
+ stp_get_scaling (stp_maximum_settings ()),
+ 1.0, 10.0, 1, TRUE, 0, 0, NULL, NULL);
+ set_adjustment_tooltip (scaling_adjustment,
+ _("Set the scale (size) of the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (scaling_adjustment), "value_changed",
+ GTK_SIGNAL_FUNC (gimp_scaling_update),
+ NULL);
+
+ sep = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
+ gtk_widget_show (sep);
+
+ box = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
+ gtk_widget_show (box);
+
+ /*
+ * The scale by percent/ppi toggles
+ */
+
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new ("Scale by:");
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ gimp_help_set_help_data (event_box,
+ _("Select whether scaling is measured as percent of "
+ "available page size or number of output dots per "
+ "inch"),
+ NULL);
+
+ scaling_percent = gtk_radio_button_new_with_label (NULL, _("Percent"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (scaling_percent));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ NULL, 0.5, 0.5,
+ scaling_percent, 1, TRUE);
+
+ gimp_help_set_help_data (scaling_percent,
+ _("Scale the print to the size of the page"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (scaling_percent), "toggled",
+ GTK_SIGNAL_FUNC (gimp_scaling_callback),
+ NULL);
+
+ scaling_ppi = gtk_radio_button_new_with_label (group, _("PPI"));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ NULL, 0.5, 0.5,
+ scaling_ppi, 1, TRUE);
+
+ gimp_help_set_help_data (scaling_ppi,
+ _("Scale the print to the number of dots per inch"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (scaling_ppi), "toggled",
+ GTK_SIGNAL_FUNC (gimp_scaling_callback),
+ NULL);
+
+ sep = gtk_vseparator_new ();
+ gtk_box_pack_start (GTK_BOX (box), sep, FALSE, FALSE, 8);
+ gtk_widget_show (sep);
+
+ /*
+ * The width/height enries
+ */
+
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ width_entry = gtk_entry_new ();
+ gtk_widget_set_usize (width_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ _("Width:"), 1.0, 0.5,
+ width_entry, 1, TRUE);
+
+ gimp_help_set_help_data (width_entry,
+ _("Set the width of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (width_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ height_entry = gtk_entry_new ();
+ gtk_widget_set_usize (height_entry, 60, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ _("Height:"), 1.0, 0.5,
+ height_entry, 1, TRUE);
+
+ gimp_help_set_help_data (height_entry,
+ _("Set the height of the print"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (height_entry), "activate",
+ GTK_SIGNAL_FUNC (gimp_position_callback),
+ NULL);
+
+ /*
+ * The inch/cm toggles
+ */
+
+ table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Units:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ gimp_help_set_help_data (event_box,
+ _("Select the base unit of measurement for printing"),
+ NULL);
+
+ unit_inch = gtk_radio_button_new_with_label (NULL, _("Inch"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (unit_inch));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ NULL, 0.5, 0.5,
+ unit_inch, 1, TRUE);
+
+ gimp_help_set_help_data (unit_inch,
+ _("Set the base unit of measurement to inches"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (unit_inch), "toggled",
+ GTK_SIGNAL_FUNC (gimp_unit_callback),
+ (gpointer) 0);
+
+ unit_cm = gtk_radio_button_new_with_label (group, _("cm"));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ NULL, 0.5, 0.5,
+ unit_cm, 1, TRUE);
+
+ gimp_help_set_help_data (unit_cm,
+ _("Set the base unit of measurement to centimetres"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (unit_cm), "toggled",
+ GTK_SIGNAL_FUNC (gimp_unit_callback),
+ (gpointer) 1);
+
+ /*
+ * The "image size" button
+ */
+
+ scaling_image = gtk_button_new_with_label (_("Use Original\nImage Size"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (scaling_image)->child), 8, 4);
+ gtk_box_pack_end (GTK_BOX (box), scaling_image, FALSE, TRUE, 0);
+ gtk_widget_show (scaling_image);
+
+ gimp_help_set_help_data (scaling_image,
+ _("Set the print size to the size of the image"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (scaling_image), "clicked",
+ GTK_SIGNAL_FUNC (gimp_scaling_callback),
+ NULL);
+
+}
+
+static void
+create_image_settings_frame (void)
+{
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+
+ gimp_create_color_adjust_window ();
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
+ vbox,
+ gtk_label_new (_("Image / Output Settings")));
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (3, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Image Type:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ gimp_help_set_help_data (event_box,
+ _("Optimize the output for the type of image "
+ "being printed"),
+ NULL);
+
+ image_line_art = gtk_radio_button_new_with_label (NULL, _("Line Art"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (image_line_art));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ NULL, 0.5, 0.5,
+ image_line_art, 1, FALSE);
+
+ gimp_help_set_help_data (image_line_art,
+ _("Fastest and brightest color for text and "
+ "line art"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (image_line_art), "toggled",
+ GTK_SIGNAL_FUNC (gimp_image_type_callback),
+ (gpointer) IMAGE_LINE_ART);
+
+ image_solid_tone = gtk_radio_button_new_with_label (group, _("Solid Colors"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (image_solid_tone));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ NULL, 0.5, 0.5,
+ image_solid_tone, 1, FALSE);
+
+ gimp_help_set_help_data (image_solid_tone,
+ _("Best for images dominated by regions of "
+ "solid color"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (image_solid_tone), "toggled",
+ GTK_SIGNAL_FUNC (gimp_image_type_callback),
+ (gpointer) IMAGE_SOLID_TONE);
+
+ image_continuous_tone = gtk_radio_button_new_with_label (group,
+ _("Photograph"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (image_continuous_tone));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
+ NULL, 0.5, 0.5,
+ image_continuous_tone, 1, FALSE);
+ gtk_widget_show (image_continuous_tone);
+
+ gimp_help_set_help_data (image_continuous_tone,
+ _("Slowest, but most accurate and smoothest color "
+ "for continuous tone images and photographs"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (image_continuous_tone), "toggled",
+ GTK_SIGNAL_FUNC (gimp_image_type_callback),
+ (gpointer) IMAGE_CONTINUOUS);
+
+ sep = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
+ gtk_widget_show (sep);
+
+ /*
+ * Output type toggles.
+ */
+
+ table = gtk_table_new (4, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 2, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Output Type:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ gimp_help_set_help_data (event_box,
+ _("Select the desired output type"),
+ NULL);
+
+ output_color = gtk_radio_button_new_with_label (NULL, _("Color"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (output_color));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
+ NULL, 0.5, 0.5,
+ output_color, 1, FALSE);
+
+ gimp_help_set_help_data (output_color, _("Color output"), NULL);
+ gtk_signal_connect (GTK_OBJECT (output_color), "toggled",
+ GTK_SIGNAL_FUNC (gimp_output_type_callback),
+ (gpointer) OUTPUT_COLOR);
+
+ output_gray = gtk_radio_button_new_with_label (group, _("Grayscale"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (output_gray));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
+ NULL, 0.5, 0.5,
+ output_gray, 1, FALSE);
+
+ gimp_help_set_help_data (output_gray,
+ _("Print in shades of gray using black ink"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (output_gray), "toggled",
+ GTK_SIGNAL_FUNC (gimp_output_type_callback),
+ (gpointer) OUTPUT_GRAY);
+
+ output_monochrome = gtk_radio_button_new_with_label (group,
+ _("Black and White"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (output_monochrome));
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
+ NULL, 0.5, 0.5,
+ output_monochrome, 1, FALSE);
+
+ gimp_help_set_help_data (output_monochrome,
+ _("Print in black and white (no color, and no shades "
+ "of gray)"),
+ NULL);
+ gtk_signal_connect (GTK_OBJECT (output_monochrome), "toggled",
+ GTK_SIGNAL_FUNC (gimp_output_type_callback),
+ (gpointer) OUTPUT_MONOCHROME);
+
+ /*
+ * Color adjust button
+ */
+
+ adjust_color_button = gtk_button_new_with_label (_("Adjust Output..."));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (adjust_color_button)->child), 4, 0);
+ gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
+ NULL, 0.5, 0.5,
+ adjust_color_button, 1, TRUE);
+
+ gimp_help_set_help_data (adjust_color_button,
+ _("Adjust color balance, brightness, contrast, "
+ "saturation, and dither algorithm"),
+ NULL);
+ gtk_signal_connect_object (GTK_OBJECT (adjust_color_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_show),
+ GTK_OBJECT (gimp_color_adjust_dialog));
+}
+
+/*
+ * gimp_create_main_window()
+ */
+void
+gimp_create_main_window (void)
+{
+
+ pv = &(plist[plist_current].v);
+ /*
+ * Create the various dialog components. Note that we're not
+ * actually initializing the values at this point; that will be done after
+ * the UI is fully created.
+ */
+ gimp_help_init ();
+
+ create_top_level_structure ();
+
+ create_preview ();
+ create_printer_settings_frame ();
+ create_positioning_frame ();
+ create_scaling_frame ();
+ create_image_settings_frame ();
+
+ /*
+ * Now actually set up the correct values in the dialog
+ */
+
+ gimp_build_printer_combo ();
+ gimp_plist_callback (NULL, (gpointer) plist_current);
+ gimp_update_adjusted_thumbnail ();
+
+ gtk_widget_show (print_dialog);
+}
+
+/*
+ * gimp_scaling_update() - Update the scaling scale using the slider.
+ */
+static void
+gimp_scaling_update (GtkAdjustment *adjustment)
+{
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ if (stp_get_scaling(*pv) != adjustment->value)
+ {
+ if (GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ stp_set_scaling (*pv, -adjustment->value);
+ else
+ stp_set_scaling (*pv, adjustment->value);
+ }
+
+ suppress_scaling_adjustment = TRUE;
+ gimp_preview_update ();
+ suppress_scaling_adjustment = FALSE;
+}
+
+/*
+ * gimp_scaling_callback() - Update the scaling scale using radio buttons.
+ */
+static void
+gimp_scaling_callback (GtkWidget *widget)
+{
+ const stp_vars_t lower = stp_minimum_settings ();
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling, min_ppi_scaling1, min_ppi_scaling2;
+ gdouble current_scale;
+
+ reset_preview ();
+
+ if (suppress_scaling_callback)
+ return;
+
+ min_ppi_scaling1 = 72.0 * (gdouble) image_width /
+ (gdouble) printable_width;
+ min_ppi_scaling2 = 72.0 * (gdouble) image_height /
+ (gdouble) printable_height;
+
+ if (min_ppi_scaling1 > min_ppi_scaling2)
+ min_ppi_scaling = min_ppi_scaling1;
+ else
+ min_ppi_scaling = min_ppi_scaling2;
+
+ max_ppi_scaling = min_ppi_scaling * 100 / stp_get_scaling (lower);
+
+ if (widget == scaling_ppi)
+ {
+ if (! GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ return;
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ /*
+ * Compute the correct PPI to create an image of the same size
+ * as the one measured in percent
+ */
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ min_ppi_scaling / (current_scale / 100);
+ stp_set_scaling (*pv, 0.0);
+ }
+ else if (widget == scaling_percent)
+ {
+ gdouble new_percent;
+
+ if (! GTK_TOGGLE_BUTTON (scaling_percent)->active)
+ return;
+
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = stp_get_scaling (lower);
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+
+ new_percent = 100 * min_ppi_scaling / current_scale;
+
+ if (new_percent > 100)
+ new_percent = 100;
+ if (new_percent < stp_get_scaling(lower))
+ new_percent = stp_get_scaling(lower);
+
+ GTK_ADJUSTMENT (scaling_adjustment)->value = new_percent;
+ stp_set_scaling (*pv, 0.0);
+ }
+ else if (widget == scaling_image)
+ {
+ gdouble xres, yres;
+
+ gimp_invalidate_preview_thumbnail ();
+ gimp_image_get_resolution (image_ID, &xres, &yres);
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ if (yres < min_ppi_scaling)
+ yres = min_ppi_scaling;
+ if (yres > max_ppi_scaling)
+ yres = max_ppi_scaling;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->value = yres;
+ stp_set_scaling (*pv, 0.0);
+ }
+
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+}
+
+/****************************************************************************
+ *
+ * gimp_plist_build_combo
+ *
+ ****************************************************************************/
+void
+gimp_plist_build_combo (GtkWidget *combo, /* I - Combo widget */
+ gint num_items, /* I - Number of items */
+ stp_param_t *items, /* I - Menu items */
+ const gchar *cur_item, /* I - Current item */
+ const gchar *def_value, /* I - default item */
+ GtkSignalFunc callback, /* I - Callback */
+ gint *callback_id) /* IO - Callback ID (init to -1) */
+{
+ gint i; /* Looping var */
+ GList *list = 0;
+ GtkEntry *entry = GTK_ENTRY (GTK_COMBO (combo)->entry);
+
+ if (*callback_id != -1)
+ gtk_signal_disconnect (GTK_OBJECT (entry), *callback_id);
+#if 0
+ gtk_signal_handlers_destroy (GTK_OBJECT (entry));
+#endif
+ gtk_entry_set_editable (entry, FALSE);
+
+ if (num_items == 0)
+ {
+ list = g_list_append (list, _("Standard"));
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+ *callback_id = -1;
+ gtk_widget_set_sensitive (combo, FALSE);
+ gtk_widget_show (combo);
+ return;
+ }
+
+ for (i = 0; i < num_items; i ++)
+ list = g_list_append (list, c_strdup(items[i].text));
+
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+
+ *callback_id = gtk_signal_connect (GTK_OBJECT (entry), "changed", callback,
+ NULL);
+
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(items[i].name, cur_item) == 0)
+ break;
+
+ if (i >= num_items)
+ {
+ if (def_value)
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(items[i].name, def_value) == 0)
+ break;
+
+ if (i >= num_items)
+ i = 0;
+ }
+
+ gtk_entry_set_text (entry, c_strdup (items[i].text));
+
+ gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
+ gtk_widget_set_sensitive (combo, TRUE);
+ gtk_widget_show (combo);
+}
+
+/*
+ * gimp_do_misc_updates() - Build an option menu for the given parameters.
+ */
+static void
+gimp_do_misc_updates (void)
+{
+ const stp_vars_t lower = stp_minimum_settings ();
+
+ suppress_preview_update++;
+ gimp_invalidate_preview_thumbnail ();
+ gimp_preview_update ();
+
+ if (stp_get_scaling (*pv) < 0)
+ {
+ gdouble tmp = -stp_get_scaling (*pv);
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling, min_ppi_scaling1, min_ppi_scaling2;
+
+ min_ppi_scaling1 = 72.0 * (gdouble) image_width /
+ (gdouble) printable_width;
+ min_ppi_scaling2 = 72.0 * (gdouble) image_height /
+ (gdouble) printable_height;
+
+ if (min_ppi_scaling1 > min_ppi_scaling2)
+ min_ppi_scaling = min_ppi_scaling1;
+ else
+ min_ppi_scaling = min_ppi_scaling2;
+
+ max_ppi_scaling = min_ppi_scaling * 100 / stp_get_scaling(lower);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ else
+ {
+ gdouble tmp = stp_get_scaling (*pv);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = stp_get_scaling (lower);
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ gtk_signal_emit_by_name (scaling_adjustment, "changed");
+ gtk_signal_emit_by_name (scaling_adjustment, "value_changed");
+ }
+
+ switch (stp_get_output_type (*pv))
+ {
+ case OUTPUT_GRAY:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_gray), TRUE);
+ break;
+ case OUTPUT_COLOR:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_color), TRUE);
+ break;
+ case OUTPUT_MONOCHROME:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_monochrome), TRUE);
+ break;
+ }
+
+ gimp_do_color_updates ();
+
+ gtk_option_menu_set_history (GTK_OPTION_MENU (orientation_menu),
+ stp_get_orientation (*pv) + 1);
+
+ if (stp_get_unit(*pv) == 0)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (unit_inch), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (unit_cm), TRUE);
+
+ switch (stp_get_image_type (*pv))
+ {
+ case IMAGE_LINE_ART:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_line_art), TRUE);
+ break;
+ case IMAGE_SOLID_TONE:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_solid_tone), TRUE);
+ break;
+ case IMAGE_CONTINUOUS:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_continuous_tone),
+ TRUE);
+ break;
+ default:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_continuous_tone),
+ TRUE);
+ stp_set_image_type (*pv, IMAGE_CONTINUOUS);
+ break;
+ }
+
+ suppress_preview_update--;
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_position_callback() - callback for position entry widgets
+ */
+static void
+gimp_position_callback (GtkWidget *widget)
+{
+ reset_preview ();
+ suppress_preview_update++;
+
+ if (widget == recenter_button)
+ {
+ stp_set_left (*pv, -1);
+ stp_set_top (*pv, -1);
+ }
+ else if (widget == recenter_horizontal_button)
+ {
+ stp_set_left (*pv, -1);
+ }
+ else if (widget == recenter_vertical_button)
+ {
+ stp_set_top (*pv, -1);
+ }
+ else
+ {
+ gdouble new_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+ gdouble unit_scaler = 1.0;
+ gboolean was_percent = 0;
+
+ if (stp_get_unit(*pv))
+ unit_scaler /= 2.54;
+ new_value *= unit_scaler;
+
+ if (widget == top_entry)
+ stp_set_top (*pv, ((new_value + (1.0 / 144.0)) * 72) - top);
+ else if (widget == bottom_entry)
+ stp_set_top (*pv,
+ ((new_value + (1.0 / 144.0)) * 72) - (top + print_height));
+ else if (widget == bottom_border_entry)
+ stp_set_top (*pv, paper_height - print_height - top - (new_value * 72));
+ else if (widget == left_entry)
+ stp_set_left (*pv, ((new_value + (1.0 / 144.0)) * 72) - left);
+ else if (widget == right_entry)
+ stp_set_left (*pv,
+ ((new_value + (1.0 / 144.0)) * 72) - (left +print_width));
+ else if (widget == right_border_entry)
+ stp_set_left (*pv, paper_width - print_width - left - (new_value * 72));
+ else if (widget == width_entry)
+ {
+ if (stp_get_scaling(*pv) >= 0)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi),
+ TRUE);
+ gimp_scaling_callback (scaling_ppi);
+ was_percent = 1;
+ }
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_width) / new_value;
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (was_percent)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent),
+ TRUE);
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ }
+ else if (widget == height_entry)
+ {
+ if (stp_get_scaling(*pv) >= 0)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi),
+ TRUE);
+ gimp_scaling_callback (scaling_ppi);
+ was_percent = 1;
+ }
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_height) / new_value;
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (was_percent)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent),
+ TRUE);
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ }
+ if (stp_get_left (*pv) < 0)
+ stp_set_left (*pv, 0);
+ if (stp_get_top (*pv) < 0)
+ stp_set_top (*pv, 0);
+ }
+
+ suppress_preview_update--;
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_plist_callback() - Update the current system printer.
+ */
+static void
+gimp_plist_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gint i;
+ const gchar *default_parameter;
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ if (widget)
+ {
+ const gchar *result = Combo_get_text (printer_combo);
+
+ for (i = 0; i < plist_count; i++)
+ {
+ if (! strcmp (result, printer_list[i].text))
+ {
+ plist_current = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ plist_current = (gint) data;
+ }
+
+ pv = &(plist[plist_current].v);
+
+ if (strcmp(stp_get_driver(*pv), ""))
+ current_printer = stp_get_printer_by_driver (stp_get_driver (*pv));
+
+ suppress_preview_update++;
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (dither_algo_combo)->entry),
+ stp_get_dither_algorithm (*pv));
+
+ gimp_setup_update ();
+
+ gimp_do_misc_updates ();
+
+ /*
+ * Now get option parameters.
+ */
+
+ if (num_media_sizes > 0)
+ {
+ for (i = 0; i < num_media_sizes; i ++)
+ {
+ free ((void *) media_sizes[i].name);
+ free ((void *) media_sizes[i].text);
+ }
+ free (media_sizes);
+ num_media_sizes = 0;
+ }
+
+ media_sizes = (*(stp_printer_get_printfuncs(current_printer)->parameters))
+ (current_printer, stp_get_ppd_file (*pv), "PageSize", &num_media_sizes);
+ default_parameter =
+ ((stp_printer_get_printfuncs(current_printer)->default_parameters)
+ (current_printer, stp_get_ppd_file (*pv), "PageSize"));
+
+ if (stp_get_media_size(*pv)[0] == '\0')
+ stp_set_media_size (*pv, default_parameter);
+
+ gimp_plist_build_combo (media_size_combo,
+ num_media_sizes,
+ media_sizes,
+ stp_get_media_size (*pv),
+ default_parameter,
+ gimp_media_size_callback,
+ &media_size_callback_id);
+
+ if (num_media_types > 0)
+ {
+ for (i = 0; i < num_media_types; i ++)
+ {
+ free ((void *) media_types[i].name);
+ free ((void *) media_types[i].text);
+ }
+ free (media_types);
+ num_media_types = 0;
+ }
+
+ media_types = (*(stp_printer_get_printfuncs (current_printer)->parameters))
+ (current_printer, stp_get_ppd_file (*pv), "MediaType", &num_media_types);
+ default_parameter =
+ ((stp_printer_get_printfuncs (current_printer)->default_parameters)
+ (current_printer, stp_get_ppd_file (*pv), "MediaType"));
+
+ if (stp_get_media_type (*pv)[0] == '\0' && media_types != NULL)
+ stp_set_media_type (*pv, default_parameter);
+ else if (media_types == NULL)
+ stp_set_media_type (*pv, NULL);
+
+ gimp_plist_build_combo (media_type_combo,
+ num_media_types,
+ media_types,
+ stp_get_media_type (*pv),
+ default_parameter,
+ gimp_media_type_callback,
+ &media_type_callback_id);
+
+ if (num_media_sources > 0)
+ {
+ for (i = 0; i < num_media_sources; i ++)
+ {
+ free ((void *) media_sources[i].name);
+ free ((void *) media_sources[i].text);
+ }
+ free (media_sources);
+ num_media_sources = 0;
+ }
+
+ media_sources = (*(stp_printer_get_printfuncs (current_printer)->parameters))
+ (current_printer, stp_get_ppd_file (*pv), "InputSlot", &num_media_sources);
+ default_parameter =
+ ((stp_printer_get_printfuncs (current_printer)->default_parameters)
+ (current_printer, stp_get_ppd_file (*pv), "InputSlot"));
+
+ if (stp_get_media_source (*pv)[0] == '\0' && media_sources != NULL)
+ stp_set_media_source (*pv, default_parameter);
+ else if (media_sources == NULL)
+ stp_set_media_source (*pv, NULL);
+
+ gimp_plist_build_combo (media_source_combo,
+ num_media_sources,
+ media_sources,
+ stp_get_media_source (*pv),
+ default_parameter,
+ gimp_media_source_callback,
+ &media_source_callback_id);
+
+ if (num_ink_types > 0)
+ {
+ for (i = 0; i < num_ink_types; i ++)
+ {
+ free ((void *) ink_types[i].name);
+ free ((void *) ink_types[i].text);
+ }
+ free (ink_types);
+ num_ink_types = 0;
+ }
+
+ ink_types = (*(stp_printer_get_printfuncs (current_printer)->parameters))
+ (current_printer, stp_get_ppd_file (*pv), "InkType", &num_ink_types);
+ default_parameter =
+ ((stp_printer_get_printfuncs (current_printer)->default_parameters)
+ (current_printer, stp_get_ppd_file (*pv), "InkType"));
+
+ if (stp_get_ink_type (*pv)[0] == '\0' && ink_types != NULL)
+ stp_set_ink_type (*pv, default_parameter);
+ else if (ink_types == NULL)
+ stp_set_ink_type (*pv, NULL);
+
+ gimp_plist_build_combo (ink_type_combo,
+ num_ink_types,
+ ink_types,
+ stp_get_ink_type (*pv),
+ default_parameter,
+ gimp_ink_type_callback,
+ &ink_type_callback_id);
+
+ if (num_resolutions > 0)
+ {
+ for (i = 0; i < num_resolutions; i ++)
+ {
+ free ((void *)resolutions[i].name);
+ free ((void *)resolutions[i].text);
+ }
+ free (resolutions);
+ num_resolutions = 0;
+ }
+
+ resolutions = (*(stp_printer_get_printfuncs (current_printer)->parameters))
+ (current_printer, stp_get_ppd_file (*pv), "Resolution", &num_resolutions);
+ default_parameter =
+ ((stp_printer_get_printfuncs (current_printer)->default_parameters)
+ (current_printer, stp_get_ppd_file (*pv), "Resolution"));
+
+ if (stp_get_resolution (*pv)[0] == '\0' && resolutions != NULL)
+ stp_set_resolution (*pv, default_parameter);
+ else if (resolutions == NULL)
+ stp_set_resolution (*pv, NULL);
+
+ gimp_plist_build_combo (resolution_combo,
+ num_resolutions,
+ resolutions,
+ stp_get_resolution (*pv),
+ default_parameter,
+ gimp_resolution_callback,
+ &resolution_callback_id);
+
+ if (dither_algo_combo)
+ gimp_build_dither_combo ();
+
+ suppress_preview_update--;
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_media_size_callback() - Update the current media size.
+ */
+static void
+gimp_media_size_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ if (widget == custom_size_width)
+ {
+ gint width_limit, height_limit;
+ gint min_width_limit, min_height_limit;
+ gdouble new_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+ gdouble unit_scaler = 1.0;
+
+ new_value *= 72;
+ if (stp_get_unit (*pv))
+ unit_scaler /= 2.54;
+ new_value *= unit_scaler;
+ (stp_printer_get_printfuncs (current_printer)->limit)
+ (current_printer, *pv, &width_limit, &height_limit,
+ &min_width_limit, &min_height_limit);
+ if (new_value < min_width_limit)
+ new_value = min_width_limit;
+ else if (new_value > width_limit)
+ new_value = width_limit;
+ stp_set_page_width (*pv, new_value);
+ stp_set_left(*pv, -1);
+ new_value = new_value / 72.0;
+ if (stp_get_unit (*pv))
+ new_value *= 2.54;
+ set_entry_value (custom_size_width, new_value, 0);
+ gimp_preview_update ();
+ }
+ else if (widget == custom_size_height)
+ {
+ gint width_limit, height_limit;
+ gint min_width_limit, min_height_limit;
+ gdouble new_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+ gdouble unit_scaler = 1.0;
+
+ new_value *= 72;
+ if (stp_get_unit(*pv))
+ unit_scaler /= 2.54;
+ new_value *= unit_scaler;
+ (stp_printer_get_printfuncs (current_printer)->limit)
+ (current_printer, *pv, &width_limit, &height_limit,
+ &min_width_limit, &min_height_limit);
+ if (new_value < min_height_limit)
+ new_value = min_height_limit;
+ else if (new_value > height_limit)
+ new_value = height_limit;
+ stp_set_page_height (*pv, new_value);
+ stp_set_top(*pv, -1);
+ new_value = new_value / 72.0;
+ if (stp_get_unit (*pv))
+ new_value *= 2.54;
+ set_entry_value (custom_size_height, new_value, 0);
+ gimp_preview_update ();
+ }
+ else
+ {
+ const gchar *new_media_size = Combo_get_name (media_size_combo,
+ num_media_sizes,
+ media_sizes);
+ const stp_papersize_t pap = stp_get_papersize_by_name (new_media_size);
+
+ if (pap)
+ {
+ gint default_width, default_height;
+ gdouble size;
+
+ if (stp_papersize_get_width (pap) == 0)
+ {
+ (stp_printer_get_printfuncs (current_printer)->media_size)
+ (current_printer, *pv, &default_width, &default_height);
+ size = default_width / 72.0;
+ if (stp_get_unit (*pv))
+ size *= 2.54;
+ set_entry_value (custom_size_width, size, 0);
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), TRUE);
+ stp_set_page_width (*pv, default_width);
+ }
+ else
+ {
+ size = stp_papersize_get_width (pap) / 72.0;
+ if (stp_get_unit (*pv))
+ size *= 2.54;
+ set_entry_value (custom_size_width, size, 0);
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), FALSE);
+ stp_set_page_width (*pv, stp_papersize_get_width (pap));
+ }
+
+ if (stp_papersize_get_height (pap) == 0)
+ {
+ (stp_printer_get_printfuncs (current_printer)->media_size)
+ (current_printer, *pv, &default_width, &default_height);
+ size = default_height / 72.0;
+ if (stp_get_unit (*pv))
+ size *= 2.54;
+ set_entry_value (custom_size_height, size, 0);
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_height), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), TRUE);
+ stp_set_page_height (*pv, default_height);
+ }
+ else
+ {
+ size = stp_papersize_get_height (pap) / 72.0;
+ if (stp_get_unit (*pv))
+ size *= 2.54;
+ set_entry_value (custom_size_height, size, 0);
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_height), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), FALSE);
+ stp_set_page_height (*pv, stp_papersize_get_height (pap));
+ }
+ }
+
+ if (strcmp (stp_get_media_size (*pv), new_media_size) != 0)
+ {
+ stp_set_media_size (*pv, new_media_size);
+ stp_set_left (*pv, -1);
+ stp_set_top (*pv, -1);
+ gimp_preview_update ();
+ }
+ }
+}
+
+/*
+ * gimp_media_type_callback() - Update the current media type.
+ */
+static void
+gimp_media_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *new_media_type =
+ Combo_get_name (media_type_combo, num_media_types, media_types);
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+ stp_set_media_type (*pv, new_media_type);
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_media_source_callback() - Update the current media source.
+ */
+static void
+gimp_media_source_callback (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *new_media_source =
+ Combo_get_name (media_source_combo, num_media_sources, media_sources);
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+ stp_set_media_source (*pv, new_media_source);
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_ink_type_callback() - Update the current ink type.
+ */
+static void
+gimp_ink_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *new_ink_type =
+ Combo_get_name (ink_type_combo, num_ink_types, ink_types);
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+ stp_set_ink_type (*pv, new_ink_type);
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_resolution_callback() - Update the current resolution.
+ */
+static void
+gimp_resolution_callback (GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *new_resolution =
+ Combo_get_name (resolution_combo, num_resolutions, resolutions);
+
+ gimp_invalidate_frame();
+ gimp_invalidate_preview_thumbnail();
+ reset_preview();
+ stp_set_resolution(*pv, new_resolution);
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_orientation_callback() - Update the current media size.
+ */
+static void
+gimp_orientation_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (stp_get_orientation (*pv) != (gint) data)
+ {
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ stp_set_orientation (*pv, (gint) data);
+ stp_set_left (*pv, -1);
+ stp_set_top (*pv, -1);
+ }
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_output_type_callback() - Update the current output type.
+ */
+static void
+gimp_output_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ stp_set_output_type (*pv, (gint) data);
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ gimp_update_adjusted_thumbnail ();
+ }
+
+ if (widget == output_color)
+ gimp_set_color_sliders_active (TRUE);
+ else
+ gimp_set_color_sliders_active (FALSE);
+
+ gimp_preview_update ();
+}
+
+/*
+ * gimp_unit_callback() - Update the current unit.
+ */
+static void
+gimp_unit_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ stp_set_unit (*pv, (gint) data);
+ gimp_preview_update ();
+ }
+}
+
+/*
+ * gimp_image_type_callback() - Update the current image type mode.
+ */
+static void
+gimp_image_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ stp_set_image_type (*pv, (gint) data);
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ gimp_update_adjusted_thumbnail ();
+ }
+
+ gimp_preview_update ();
+}
+
+static void
+gimp_destroy_dialogs (void)
+{
+ gtk_widget_destroy (gimp_color_adjust_dialog);
+ gtk_widget_destroy (setup_dialog);
+ gtk_widget_destroy (print_dialog);
+ gtk_widget_destroy (new_printer_dialog);
+ gtk_widget_destroy (about_dialog);
+}
+
+static void
+gimp_dialogs_set_sensitive (gboolean sensitive)
+{
+ gtk_widget_set_sensitive (gimp_color_adjust_dialog, sensitive);
+ gtk_widget_set_sensitive (setup_dialog, sensitive);
+ gtk_widget_set_sensitive (print_dialog, sensitive);
+ gtk_widget_set_sensitive (new_printer_dialog, sensitive);
+ gtk_widget_set_sensitive (about_dialog, sensitive);
+}
+
+/*
+ * 'print_callback()' - Start the print.
+ */
+static void
+gimp_print_callback (void)
+{
+ if (plist_current > 0)
+ {
+ runme = TRUE;
+ gimp_destroy_dialogs ();
+ }
+ else
+ {
+ gimp_dialogs_set_sensitive (FALSE);
+ gtk_widget_show (file_browser);
+ }
+}
+
+/*
+ * gimp_printandsave_callback() -
+ */
+static void
+gimp_printandsave_callback (void)
+{
+ saveme = TRUE;
+ gimp_print_callback();
+}
+
+static void
+gimp_about_callback (void)
+{
+ gtk_widget_show (about_dialog);
+}
+
+/*
+ * gimp_save_callback() - save settings, don't destroy dialog
+ */
+static void
+gimp_save_callback (void)
+{
+ reset_preview ();
+ printrc_save ();
+}
+
+/*
+ * gimp_setup_update() - update widgets in the setup dialog
+ */
+static void
+gimp_setup_update (void)
+{
+ GtkAdjustment *adjustment;
+ gint idx;
+
+ current_printer = stp_get_printer_by_driver (stp_get_driver (*pv));
+ idx = stp_get_printer_index_by_driver (stp_get_driver (*pv));
+
+ gtk_clist_select_row (GTK_CLIST (printer_driver), idx, 0);
+
+ gtk_entry_set_text (GTK_ENTRY (ppd_file), stp_get_ppd_file (*pv));
+
+ if (strncmp (stp_get_driver (*pv),"ps", 2) == 0)
+ {
+ gtk_widget_show (ppd_label);
+ gtk_widget_show (ppd_file);
+ gtk_widget_show (ppd_button);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_label);
+ gtk_widget_hide (ppd_file);
+ gtk_widget_hide (ppd_button);
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (output_cmd), stp_get_output_to (*pv));
+
+ if (plist_current == 0)
+ gtk_widget_hide (output_cmd);
+ else
+ gtk_widget_show (output_cmd);
+
+ adjustment = GTK_CLIST (printer_driver)->vadjustment;
+ gtk_adjustment_set_value (adjustment,
+ adjustment->lower +
+ idx * (adjustment->upper - adjustment->lower) /
+ GTK_CLIST (printer_driver)->rows);
+}
+
+/*
+ * gimp_setup_open_callback() -
+ */
+static void
+gimp_setup_open_callback (void)
+{
+ static gboolean first_time = TRUE;
+
+ reset_preview ();
+ gimp_setup_update ();
+
+ gtk_widget_show (setup_dialog);
+
+ if (first_time)
+ {
+ /* Make sure the driver scroller gets positioned correctly. */
+ gimp_setup_update ();
+ first_time = FALSE;
+ }
+}
+
+/*
+ * gimp_new_printer_open_callback() -
+ */
+static void
+gimp_new_printer_open_callback (void)
+{
+ reset_preview ();
+ gtk_entry_set_text (GTK_ENTRY (new_printer_entry), "");
+ gtk_widget_show (new_printer_dialog);
+}
+
+/*
+ * gimp_setup_ok_callback() -
+ */
+static void
+gimp_setup_ok_callback (void)
+{
+ reset_preview ();
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ stp_set_driver (*pv, stp_printer_get_driver (current_printer));
+
+ stp_set_output_to (*pv, gtk_entry_get_text (GTK_ENTRY (output_cmd)));
+
+ stp_set_ppd_file (*pv, gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+
+ gimp_plist_callback (NULL, (gpointer) plist_current);
+
+ gtk_widget_hide (setup_dialog);
+}
+
+/*
+ * gimp_setup_ok_callback() -
+ */
+static void
+gimp_new_printer_ok_callback (void)
+{
+ const gchar *data = gtk_entry_get_text (GTK_ENTRY (new_printer_entry));
+ gp_plist_t key;
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+ initialize_printer (&key);
+ (void) strncpy (key.name, data, sizeof(key.name) - 1);
+
+ if (strlen (key.name))
+ {
+ key.active = 0;
+ key.v = stp_allocate_copy (*pv);
+
+ if (add_printer (&key, 1))
+ {
+ plist_current = plist_count - 1;
+ gimp_build_printer_combo ();
+
+ stp_set_driver (*pv, stp_printer_get_driver (current_printer));
+
+ stp_set_output_to (*pv, gtk_entry_get_text (GTK_ENTRY (output_cmd)));
+
+ stp_set_ppd_file (*pv, gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+
+ gimp_plist_callback (NULL, (gpointer) plist_current);
+ }
+ }
+
+ gtk_widget_hide (new_printer_dialog);
+}
+
+/*
+ * gimp_print_driver_callback() - Update the current printer driver.
+ */
+static void
+gimp_print_driver_callback (GtkWidget *widget, /* I - Driver list */
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data) /* I - Data */
+{
+ stp_vars_t printvars;
+
+ gimp_invalidate_frame ();
+ gimp_invalidate_preview_thumbnail ();
+ reset_preview ();
+ data = gtk_clist_get_row_data (GTK_CLIST (widget), row);
+ current_printer = stp_get_printer_by_index ((gint) data);
+ gtk_label_set_text (GTK_LABEL (printer_model_label),
+ gettext (stp_printer_get_long_name (current_printer)));
+
+ if (strncmp (stp_printer_get_driver (current_printer), "ps", 2) == 0)
+ {
+ gtk_widget_show (ppd_label);
+ gtk_widget_show (ppd_file);
+ gtk_widget_show (ppd_button);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_label);
+ gtk_widget_hide (ppd_file);
+ gtk_widget_hide (ppd_button);
+ }
+
+ printvars = stp_printer_get_printvars (current_printer);
+
+ if (stp_get_output_type (printvars) == OUTPUT_COLOR)
+ {
+ gtk_widget_set_sensitive (output_color, TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_gray), TRUE);
+ gtk_widget_set_sensitive (output_color, FALSE);
+ }
+}
+
+/*
+ * gimp_ppd_browse_callback() -
+ */
+static void
+gimp_ppd_browse_callback (void)
+{
+ reset_preview ();
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION (ppd_browser),
+ gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+ gtk_widget_show (ppd_browser);
+}
+
+/*
+ * gimp_ppd_ok_callback() -
+ */
+static void
+gimp_ppd_ok_callback (void)
+{
+ reset_preview ();
+ gtk_widget_hide (ppd_browser);
+ gtk_entry_set_text
+ (GTK_ENTRY (ppd_file),
+ gtk_file_selection_get_filename (GTK_FILE_SELECTION (ppd_browser)));
+}
+
+/*
+ * gimp_file_ok_callback() - print to file and go away
+ */
+static void
+gimp_file_ok_callback (void)
+{
+ gtk_widget_hide (file_browser);
+ stp_set_output_to (*pv,
+ gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_browser)));
+
+ runme = TRUE;
+ gimp_destroy_dialogs ();
+}
+
+/*
+ * gimp_file_cancel_callback() -
+ */
+static void
+gimp_file_cancel_callback (void)
+{
+ gtk_widget_hide (file_browser);
+ gimp_dialogs_set_sensitive (TRUE);
+}
+
+/*
+ * gimp_update_adjusted_thumbnail()
+ */
+void
+gimp_update_adjusted_thumbnail (void)
+{
+ gint x, y;
+ stp_convert_t colorfunc;
+ gushort out[3 * THUMBNAIL_MAXW];
+ guchar *adjusted_data = adjusted_thumbnail_data;
+ gfloat old_density = stp_get_density(*pv);
+
+ if (thumbnail_data == 0 || adjusted_thumbnail_data == 0)
+ return;
+
+ stp_set_density (*pv, 1.0);
+ stp_compute_lut (*pv, 256);
+ colorfunc = stp_choose_colorfunc (stp_get_output_type(*pv), thumbnail_bpp,
+ NULL, &adjusted_thumbnail_bpp, *pv);
+
+ for (y = 0; y < thumbnail_h; y++)
+ {
+ (*colorfunc) (*pv, thumbnail_data + thumbnail_bpp * thumbnail_w * y,
+ out, NULL, thumbnail_w, thumbnail_bpp, NULL, NULL, NULL,
+ NULL);
+ for (x = 0; x < adjusted_thumbnail_bpp * thumbnail_w; x++)
+ {
+ *adjusted_data++ = out[x] / 0x0101U;
+ }
+ }
+
+ stp_free_lut (*pv);
+
+ stp_set_density (*pv, old_density);
+
+ gimp_redraw_color_swatch ();
+ gimp_preview_update ();
+}
+
+void
+gimp_invalidate_preview_thumbnail (void)
+{
+ preview_valid = 0;
+}
+
+void
+gimp_invalidate_frame (void)
+{
+ frame_valid = 0;
+}
+
+static void
+draw_arrow (GdkWindow *w,
+ GdkGC *gc,
+ gint paper_left,
+ gint paper_top,
+ gint orient)
+{
+ gint u = preview_ppi/2;
+ gint ox = paper_left + preview_ppi * paper_width / 72 / 2;
+ gint oy = paper_top + preview_ppi * paper_height / 72 / 2;
+
+ if (orient == ORIENT_LANDSCAPE)
+ {
+ ox += preview_ppi * paper_width / 72 / 4;
+ if (ox > paper_left + preview_ppi * paper_width / 72 - u)
+ ox = paper_left + preview_ppi * paper_width / 72 - u;
+ gdk_draw_line (w, gc, ox + u, oy, ox, oy - u);
+ gdk_draw_line (w, gc, ox + u, oy, ox, oy + u);
+ gdk_draw_line (w, gc, ox + u, oy, ox - u, oy);
+ }
+ else if (orient == ORIENT_SEASCAPE)
+ {
+ ox -= preview_ppi * paper_width / 72 / 4;
+ if (ox < paper_left + u)
+ ox = paper_left + u;
+ gdk_draw_line (w, gc, ox - u, oy, ox, oy - u);
+ gdk_draw_line (w, gc, ox - u, oy, ox, oy + u);
+ gdk_draw_line (w, gc, ox - u, oy, ox + u, oy);
+ }
+ else if (orient == ORIENT_UPSIDEDOWN)
+ {
+ oy += preview_ppi * paper_height / 72 / 4;
+ if (oy > paper_top + preview_ppi * paper_height / 72 - u)
+ oy = paper_top + preview_ppi * paper_height / 72 - u;
+ gdk_draw_line (w, gc, ox, oy + u, ox - u, oy);
+ gdk_draw_line (w, gc, ox, oy + u, ox + u, oy);
+ gdk_draw_line (w, gc, ox, oy + u, ox, oy - u);
+ }
+ else /* (orient == ORIENT_PORTRAIT) */
+ {
+ oy -= preview_ppi * paper_height / 72 / 4;
+ if (oy < paper_top + u)
+ oy = paper_top + u;
+ gdk_draw_line (w, gc, ox, oy - u, ox - u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox + u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox, oy + u);
+ }
+}
+
+/*
+ * gimp_preview_update_callback() -
+ */
+static void
+gimp_do_preview_thumbnail (gint paper_left,
+ gint paper_top,
+ gint orient)
+{
+ static GdkGC *gc = NULL;
+ static GdkGC *gcinv = NULL;
+ static GdkGC *gcset = NULL;
+ static guchar *preview_data = NULL;
+ static gint opx = 0;
+ static gint opy = 0;
+ static gint oph = 0;
+ static gint opw = 0;
+
+ gint preview_x = 1 + printable_left + preview_ppi * stp_get_left (*pv) / 72;
+ gint preview_y = 1 + printable_top + preview_ppi * stp_get_top (*pv) / 72;
+ gint preview_w = MAX (1, (preview_ppi * print_width) / 72 - 1);
+ gint preview_h = MAX (1, (preview_ppi * print_height) / 72 - 1);
+
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (preview->widget.window);
+ gcinv = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcinv, GDK_INVERT);
+ gcset = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcset, GDK_SET);
+ }
+
+ if (!preview_valid)
+ {
+ gint v_denominator = preview_h > 1 ? preview_h - 1 : 1;
+ gint v_numerator = (thumbnail_h - 1) % v_denominator;
+ gint v_whole = (thumbnail_h - 1) / v_denominator;
+ gint h_denominator = preview_w > 1 ? preview_w - 1 : 1;
+ gint h_numerator = (thumbnail_w - 1) % h_denominator;
+ gint h_whole = (thumbnail_w - 1) / h_denominator;
+ gint adjusted_preview_width = adjusted_thumbnail_bpp * preview_w;
+ gint adjusted_thumbnail_width = adjusted_thumbnail_bpp * thumbnail_w;
+ gint v_cur = 0;
+ gint v_last = -1;
+ gint v_error = v_denominator / 2;
+ gint y;
+ gint i;
+
+ if (preview_data)
+ free (preview_data);
+ preview_data = g_malloc (3 * preview_h * preview_w);
+
+ for (y = 0; y < preview_h; y++)
+ {
+ guchar *outbuf = preview_data + adjusted_preview_width * y;
+
+ if (v_cur == v_last)
+ {
+ memcpy (outbuf, outbuf - adjusted_preview_width,
+ adjusted_preview_width);
+ }
+ else
+ {
+ guchar *inbuf = adjusted_thumbnail_data - adjusted_thumbnail_bpp
+ + adjusted_thumbnail_width * v_cur;
+
+ gint h_cur = 0;
+ gint h_last = -1;
+ gint h_error = h_denominator / 2;
+ gint x;
+
+ v_last = v_cur;
+ for (x = 0; x < preview_w; x++)
+ {
+ if (h_cur == h_last)
+ {
+ for (i = 0; i < adjusted_thumbnail_bpp; i++)
+ outbuf[i] = outbuf[i - adjusted_thumbnail_bpp];
+ }
+ else
+ {
+ inbuf += adjusted_thumbnail_bpp * (h_cur - h_last);
+ h_last = h_cur;
+ for (i = 0; i < adjusted_thumbnail_bpp; i++)
+ outbuf[i] = inbuf[i];
+ }
+ outbuf += adjusted_thumbnail_bpp;
+ h_cur += h_whole;
+ h_error += h_numerator;
+ if (h_error >= h_denominator)
+ {
+ h_error -= h_denominator;
+ h_cur++;
+ }
+ }
+ }
+ v_cur += v_whole;
+ v_error += v_numerator;
+ if (v_error >= v_denominator)
+ {
+ v_error -= v_denominator;
+ v_cur++;
+ }
+ }
+ preview_valid = 1;
+ }
+
+ if (need_exposure)
+ {
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_left, paper_top,
+ MAX(2, preview_ppi * paper_width / 72),
+ MAX(2, preview_ppi * paper_height / 72));
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_left, printable_top,
+ MAX(2, preview_ppi * printable_width / 72),
+ MAX(2, preview_ppi * printable_height / 72));
+ need_exposure = 0;
+ }
+ else if (!frame_valid)
+ {
+ gdk_window_clear (preview->widget.window);
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_left, paper_top,
+ MAX(2, preview_ppi * paper_width / 72),
+ MAX(2, preview_ppi * paper_height / 72));
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_left, printable_top,
+ MAX(2, preview_ppi * printable_width / 72),
+ MAX(2, preview_ppi * printable_height / 72));
+ frame_valid = 1;
+ }
+ else
+ {
+ if (opx + opw <= preview_x || opy + oph <= preview_y ||
+ preview_x + preview_w <= opx || preview_y + preview_h <= opy)
+ {
+ gdk_window_clear_area (preview->widget.window, opx, opy, opw, oph);
+ }
+ else
+ {
+ if (opx < preview_x)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, preview_x - opx, oph);
+ if (opy < preview_y)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, opw, preview_y - opy);
+ if (opx + opw > preview_x + preview_w)
+ gdk_window_clear_area (preview->widget.window,
+ preview_x + preview_w, opy,
+ (opx + opw) - (preview_x + preview_w), oph);
+ if (opy + oph > preview_y + preview_h)
+ gdk_window_clear_area (preview->widget.window,
+ opx, preview_y + preview_h,
+ opw, (opy + oph) - (preview_y + preview_h));
+ }
+ }
+
+ draw_arrow (preview->widget.window, gcset, paper_left, paper_top, orient);
+
+ if (adjusted_thumbnail_bpp == 1)
+ gdk_draw_gray_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, preview_w);
+ else
+ gdk_draw_rgb_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, 3 * preview_w);
+
+ /* draw orientation arrow pointing to top-of-paper */
+ draw_arrow (preview->widget.window, gcinv, paper_left, paper_top, orient);
+
+ opx = preview_x;
+ opy = preview_y;
+ oph = preview_h;
+ opw = preview_w;
+}
+
+static void
+gimp_preview_expose (void)
+{
+ need_exposure = 1;
+ gimp_preview_update ();
+}
+
+static void
+gimp_preview_update (void)
+{
+ gint temp;
+ gint orient; /* True orientation of page */
+ gdouble max_ppi_scaling; /* Maximum PPI for current page size */
+ gdouble min_ppi_scaling; /* Minimum PPI for current page size */
+ gdouble min_ppi_scaling1; /* Minimum PPI for current page size */
+ gdouble min_ppi_scaling2; /* Minimum PPI for current page size */
+ gint paper_left;
+ gint paper_top;
+ gdouble unit_scaler = 72.0;
+
+ (stp_printer_get_printfuncs (current_printer)->media_size)
+ (current_printer, *pv, &paper_width, &paper_height);
+
+ (stp_printer_get_printfuncs (current_printer)->imageable_area)
+ (current_printer, *pv, &left, &right, &bottom, &top);
+
+ /* Rationalise things a bit by measuring everything from the top left */
+ top = paper_height - top;
+ bottom = paper_height - bottom;
+
+ printable_width = right - left;
+ printable_height = bottom - top;
+
+ if (stp_get_orientation (*pv) == ORIENT_AUTO)
+ {
+ if ((printable_width >= printable_height && image_width>=image_height) ||
+ (printable_height >= printable_width && image_height >= image_width))
+ orient = ORIENT_PORTRAIT;
+ else
+ orient = ORIENT_LANDSCAPE;
+ }
+ else
+ orient = stp_get_orientation (*pv);
+
+ /*
+ * Adjust page dimensions depending on the page orientation.
+ */
+
+ bottom = paper_height - bottom;
+ right = paper_width - right;
+
+ if (orient == ORIENT_LANDSCAPE || orient == ORIENT_SEASCAPE)
+ {
+ temp = printable_width;
+ printable_width = printable_height;
+ printable_height = temp;
+ temp = paper_width;
+ paper_width = paper_height;
+ paper_height = temp;
+
+ if (orient == ORIENT_LANDSCAPE)
+ {
+ temp = left;
+ left = bottom;
+ bottom = right;
+ right = top;
+ top = temp;
+ }
+ else
+ {
+ temp = left;
+ left = top;
+ top = right;
+ right = bottom;
+ bottom = temp;
+ }
+ }
+ else if (orient == ORIENT_UPSIDEDOWN)
+ {
+ temp = left;
+ left = right;
+ right = temp;
+ temp = top;
+ top = bottom;
+ bottom = temp;
+ }
+
+ bottom = paper_height - bottom;
+ right = paper_width - right;
+
+ if (stp_get_scaling (*pv) < 0)
+ {
+ gdouble twidth;
+
+ min_ppi_scaling1 = 72.0 * (gdouble) image_width / printable_width;
+ min_ppi_scaling2 = 72.0 * (gdouble) image_height / printable_height;
+
+ if (min_ppi_scaling1 > min_ppi_scaling2)
+ min_ppi_scaling = min_ppi_scaling1;
+ else
+ min_ppi_scaling = min_ppi_scaling2;
+
+ max_ppi_scaling = min_ppi_scaling * 20;
+ if (stp_get_scaling (*pv) < 0 &&
+ stp_get_scaling (*pv) > -min_ppi_scaling)
+ stp_set_scaling (*pv, -min_ppi_scaling);
+
+ twidth = (72.0 * (gdouble) image_width / -stp_get_scaling(*pv));
+ print_width = twidth + .5;
+ print_height = (twidth * (gdouble) image_height / image_width) + .5;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = -stp_get_scaling(*pv);
+
+ if (!suppress_scaling_adjustment)
+ {
+ suppress_preview_reset++;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_scaling_callback = TRUE;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ suppress_scaling_callback = FALSE;
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_preview_reset--;
+ }
+ }
+ else
+ {
+ /* we do stp_get_scaling(*pv) % of height or width, whatever is less */
+ /* this is relative to printable size */
+ if (image_width * printable_height > printable_width * image_height)
+ /* if image_width/image_height > printable_width/printable_height */
+ /* i.e. if image is wider relative to its height than the width
+ of the printable area relative to its height */
+ {
+ gdouble twidth = .5 + printable_width * stp_get_scaling(*pv) / 100;
+
+ print_width = twidth;
+ print_height = twidth * (gdouble) image_height /
+ (gdouble) image_width;
+ }
+ else
+ {
+ gdouble theight = .5 + printable_height * stp_get_scaling(*pv) /100;
+
+ print_height = theight;
+ print_width = theight * (gdouble) image_width /
+ (gdouble) image_height;
+ }
+ }
+
+ preview_ppi = PREVIEW_SIZE_HORIZ * 72.0 / (gdouble) paper_width;
+
+ if (PREVIEW_SIZE_VERT * 72 / paper_height < preview_ppi)
+ preview_ppi = PREVIEW_SIZE_VERT * 72.0 / (gdouble) paper_height;
+ if (preview_ppi > MAX_PREVIEW_PPI)
+ preview_ppi = MAX_PREVIEW_PPI;
+
+ paper_left = (PREVIEW_SIZE_HORIZ - preview_ppi * paper_width / 72) / 2;
+ paper_top = (PREVIEW_SIZE_VERT - preview_ppi * paper_height / 72) / 2;
+ printable_left = paper_left + preview_ppi * left / 72;
+ printable_top = paper_top + preview_ppi * top / 72 ;
+
+ if (preview == NULL || preview->widget.window == NULL)
+ return;
+
+ if (stp_get_left (*pv) < 0)
+ {
+ stp_set_left (*pv, (paper_width - print_width) / 2 - left);
+ if (stp_get_left (*pv) < 0)
+ stp_set_left (*pv, 0);
+ }
+
+ /* we leave stp_get_left(*pv) etc. relative to printable area */
+ if (stp_get_left (*pv) > (printable_width - print_width))
+ stp_set_left (*pv, printable_width - print_width);
+
+ if (stp_get_top (*pv) < 0)
+ {
+ stp_set_top (*pv, ((paper_height - print_height) / 2) - top);
+ if (stp_get_top (*pv) < 0)
+ stp_set_top (*pv, 0);
+ }
+
+ if (stp_get_top (*pv) > (printable_height - print_height))
+ stp_set_top (*pv, printable_height - print_height);
+
+ if(stp_get_unit (*pv))
+ unit_scaler /= 2.54;
+
+ set_entry_value (top_entry, (top + stp_get_top (*pv)) / unit_scaler, 1);
+ set_entry_value (left_entry, (left + stp_get_left (*pv)) / unit_scaler, 1);
+ set_entry_value (bottom_entry,
+ (top + stp_get_top(*pv) + print_height) / unit_scaler, 1);
+ set_entry_value (bottom_border_entry,
+ (paper_height - (top + stp_get_top (*pv) + print_height)) /
+ unit_scaler, 1);
+ set_entry_value (right_entry,
+ (left + stp_get_left(*pv) + print_width) / unit_scaler, 1);
+ set_entry_value (right_border_entry,
+ (paper_width - (left + stp_get_left (*pv) + print_width)) /
+ unit_scaler, 1);
+ set_entry_value (width_entry, print_width / unit_scaler, 1);
+ set_entry_value (height_entry, print_height / unit_scaler, 1);
+ set_entry_value (custom_size_width, stp_get_page_width (*pv)/unit_scaler, 1);
+ set_entry_value (custom_size_height, stp_get_page_height (*pv)/unit_scaler, 1);
+
+ /* draw image */
+ if (! suppress_preview_update)
+ {
+ gimp_do_preview_thumbnail (paper_left, paper_top, orient);
+ gdk_flush ();
+ }
+}
+
+/*
+ * gimp_preview_button_callback() -
+ */
+static void
+gimp_preview_button_callback (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ if (preview_active == 0)
+ {
+ mouse_x = event->x;
+ mouse_y = event->y;
+ old_left = stp_get_left (*pv);
+ old_top = stp_get_top (*pv);
+ mouse_button = event->button;
+ buttons_mask = 1 << event->button;
+ buttons_pressed++;
+ preview_active = 1;
+ gimp_help_disable_tooltips ();
+ if (event->state & GDK_SHIFT_MASK)
+ move_constraint = MOVE_CONSTRAIN;
+ else
+ move_constraint = MOVE_ANY;
+ }
+ else if (preview_active == 1)
+ {
+ if ((buttons_mask & (1 << event->button)) == 0)
+ {
+ gimp_help_enable_tooltips ();
+ preview_active = -1;
+ stp_set_left (*pv, old_left);
+ stp_set_top (*pv, old_top);
+ gimp_preview_update ();
+ buttons_mask |= 1 << event->button;
+ buttons_pressed++;
+ }
+ }
+ else
+ {
+ if ((buttons_mask & (1 << event->button)) == 0)
+ {
+ buttons_mask |= 1 << event->button;
+ buttons_pressed++;
+ }
+ }
+ }
+ else if (event->type == GDK_BUTTON_RELEASE)
+ {
+ buttons_pressed--;
+ buttons_mask &= ~(1 << event->button);
+ if (buttons_pressed == 0)
+ {
+ gimp_help_enable_tooltips ();
+ preview_active = 0;
+ }
+ }
+}
+
+/*
+ * gimp_preview_motion_callback() -
+ */
+static void
+gimp_preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer data)
+{
+ if (event->type != GDK_MOTION_NOTIFY)
+ return;
+ if (preview_active != 1)
+ return;
+ if (stp_get_left(*pv) < 0 || stp_get_top(*pv) < 0)
+ {
+ stp_set_left(*pv, 72 * (printable_width - print_width) / 20);
+ stp_set_top(*pv, 72 * (printable_height - print_height) / 20);
+ }
+ if (move_constraint == MOVE_CONSTRAIN)
+ {
+ int dx = abs(event->x - mouse_x);
+ int dy = abs(event->y - mouse_y);
+ if (dx > dy && dx > 3)
+ move_constraint = MOVE_HORIZONTAL;
+ else if (dy > dx && dy > 3)
+ move_constraint = MOVE_VERTICAL;
+ else
+ return;
+ }
+
+ if (mouse_button == 2)
+ {
+ int changes = 0;
+ int y_threshold = MAX (1, (preview_ppi * print_height) / 72);
+
+ if (move_constraint & MOVE_HORIZONTAL)
+ {
+ int x_threshold = MAX (1, (preview_ppi * print_width) / 72);
+ while (event->x - mouse_x >= x_threshold)
+ {
+ if (left + stp_get_left (*pv) + (print_width * 2) <= right)
+ {
+ stp_set_left (*pv, stp_get_left (*pv) + print_width);
+ mouse_x += x_threshold;
+ changes = 1;
+ }
+ else
+ break;
+ }
+ while (mouse_x - event->x >= x_threshold)
+ {
+ if (stp_get_left (*pv) >= print_width)
+ {
+ stp_set_left (*pv, stp_get_left (*pv) - print_width);
+ mouse_x -= x_threshold;
+ changes = 1;
+ }
+ else
+ break;
+ }
+ }
+
+ if (move_constraint & MOVE_VERTICAL)
+ {
+ while (event->y - mouse_y >= y_threshold)
+ {
+ if (top + stp_get_top (*pv) + (print_height * 2) <= bottom)
+ {
+ stp_set_top (*pv, stp_get_top (*pv) + print_height);
+ mouse_y += y_threshold;
+ changes = 1;
+ }
+ else
+ break;
+ }
+ while (mouse_y - event->y >= y_threshold)
+ {
+ if (stp_get_top (*pv) >= print_height)
+ {
+ stp_set_top (*pv, stp_get_top (*pv) - print_height);
+ mouse_y -= y_threshold;
+ changes = 1;
+ }
+ else
+ break;
+ }
+ }
+ if (!changes)
+ return;
+ }
+ else
+ {
+ gint old_top = stp_get_top (*pv);
+ gint old_left = stp_get_left (*pv);
+ gint new_top = old_top;
+ gint new_left = old_left;
+ gint changes = 0;
+
+ if (mouse_button == 1)
+ {
+ if (move_constraint & MOVE_VERTICAL)
+ new_top += 72 * (event->y - mouse_y) / preview_ppi;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left += 72 * (event->x - mouse_x) / preview_ppi;
+ }
+ else
+ {
+ if (move_constraint & MOVE_VERTICAL)
+ new_top += event->y - mouse_y;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left += event->x - mouse_x;
+ }
+
+ if (new_top < 0)
+ new_top = 0;
+ if (new_top > (bottom - top) - print_height)
+ new_top = (bottom - top) - print_height;
+ if (new_left < 0)
+ new_left = 0;
+ if (new_left > (right - left) - print_width)
+ new_left = (right - left) - print_width;
+
+ if (new_top != old_top)
+ {
+ stp_set_top (*pv, new_top);
+ changes = 1;
+ }
+ if (new_left != old_left)
+ {
+ stp_set_left (*pv, new_left);
+ changes = 1;
+ }
+ mouse_x = event->x;
+ mouse_y = event->y;
+ if (!changes)
+ return;
+ }
+
+ gimp_preview_update ();
+}
diff --git a/src/gimp/print-image-gimp.c b/src/gimp/print-image-gimp.c
new file mode 100644
index 0000000..f10bcc3
--- /dev/null
+++ b/src/gimp/print-image-gimp.c
@@ -0,0 +1,343 @@
+/*
+ * "$Id: print-image-gimp.c,v 1.5 2001/07/28 01:42:25 rlk Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
+ * Robert Krawitz (rlk@alum.mit.edu)
+ * Copyright 2000 Charles Briscoe-Smith <cpbs@debian.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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "../../lib/libprintut.h"
+
+#include "print_gimp.h"
+
+#include "print-intl.h"
+
+
+/*
+ * "Image" ADT
+ *
+ * This file defines an abstract data type called "Image". An Image wraps
+ * a Gimp drawable (or some other application-level image representation)
+ * for presentation to the low-level printer drivers (which do CMYK
+ * separation, dithering and weaving). The Image ADT has the ability
+ * to perform any combination of flips and rotations on the image,
+ * and then deliver individual rows to the driver code.
+ *
+ * Stuff which might be useful to do in this layer:
+ *
+ * - Scaling, optionally with interpolation/filtering.
+ *
+ * - Colour-adjustment.
+ *
+ * - Multiple-image composition.
+ *
+ * Also useful might be to break off a thin application-dependent
+ * sublayer leaving this layer (which does the interesting stuff)
+ * application-independent.
+ */
+
+
+/* Concrete type to represent image */
+typedef struct
+{
+ GimpDrawable *drawable;
+ GimpPixelRgn rgn;
+
+ /*
+ * Transformations we can impose on the image. The transformations
+ * are considered to be performed in the order given here.
+ */
+
+ /* 1: Transpose the x and y axes (flip image over its leading diagonal) */
+ int columns; /* Set if returning columns instead of rows. */
+
+ /* 2: Translate (ox,oy) to the origin */
+ int ox, oy; /* Origin of image */
+
+ /* 3: Flip vertically about the x axis */
+ int increment; /* +1 or -1 for offset of row n+1 from row n. */
+
+ /* 4: Crop to width w, height h */
+ int w, h; /* Width and height of output image */
+
+ /* 5: Flip horizontally about the vertical centre-line of the image */
+ int mirror; /* Set if mirroring rows end-for-end. */
+
+} Gimp_Image_t;
+
+static const char *Image_get_appname(stp_image_t *image);
+static void Image_progress_conclude(stp_image_t *image);
+static void Image_note_progress(stp_image_t *image,
+ double current, double total);
+static void Image_progress_init(stp_image_t *image);
+static stp_image_status_t Image_get_row(stp_image_t *image,
+ unsigned char *data, int row);
+static int Image_height(stp_image_t *image);
+static int Image_width(stp_image_t *image);
+static int Image_bpp(stp_image_t *image);
+static void Image_rotate_180(stp_image_t *image);
+static void Image_rotate_cw(stp_image_t *image);
+static void Image_rotate_ccw(stp_image_t *image);
+static void Image_crop(stp_image_t *image,
+ int left, int top, int right, int bottom);
+static void Image_vflip(stp_image_t *image);
+static void Image_hflip(stp_image_t *image);
+static void Image_transpose(stp_image_t *image);
+static void Image_reset(stp_image_t *image);
+static void Image_init(stp_image_t *image);
+
+static stp_image_t theImage =
+{
+ Image_init,
+ Image_reset,
+ Image_transpose,
+ Image_hflip,
+ Image_vflip,
+ Image_crop,
+ Image_rotate_ccw,
+ Image_rotate_cw,
+ Image_rotate_180,
+ Image_bpp,
+ Image_width,
+ Image_height,
+ Image_get_row,
+ Image_get_appname,
+ Image_progress_init,
+ Image_note_progress,
+ Image_progress_conclude,
+ NULL
+};
+
+stp_image_t *
+Image_GimpDrawable_new(GimpDrawable *drawable)
+{
+ Gimp_Image_t *i = xmalloc(sizeof(Gimp_Image_t));
+ i->drawable = drawable;
+ gimp_pixel_rgn_init(&(i->rgn), drawable, 0, 0,
+ drawable->width, drawable->height, FALSE, FALSE);
+ theImage.rep = i;
+ theImage.reset(&theImage);
+ return &theImage;
+}
+
+static void
+Image_init(stp_image_t *image)
+{
+ /* Nothing to do. */
+}
+
+static void
+Image_reset(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ i->columns = FALSE;
+ i->ox = 0;
+ i->oy = 0;
+ i->increment = 1;
+ i->w = i->drawable->width;
+ i->h = i->drawable->height;
+ i->mirror = FALSE;
+}
+
+static void
+Image_transpose(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ int tmp;
+
+ if (i->mirror) i->ox += i->w - 1;
+
+ i->columns = !i->columns;
+
+ tmp = i->ox;
+ i->ox = i->oy;
+ i->oy = tmp;
+
+ tmp = i->mirror;
+ i->mirror = i->increment < 0;
+ i->increment = tmp ? -1 : 1;
+
+ tmp = i->w;
+ i->w = i->h;
+ i->h = tmp;
+
+ if (i->mirror) i->ox -= i->w - 1;
+}
+
+static void
+Image_hflip(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ i->mirror = !i->mirror;
+}
+
+static void
+Image_vflip(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ i->oy += (i->h-1) * i->increment;
+ i->increment = -i->increment;
+}
+
+/*
+ * Image_crop:
+ *
+ * Crop the given number of pixels off the LEFT, TOP, RIGHT and BOTTOM
+ * of the image.
+ */
+
+static void
+Image_crop(stp_image_t *image, int left, int top, int right, int bottom)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ int xmax = (i->columns ? i->drawable->height : i->drawable->width) - 1;
+ int ymax = (i->columns ? i->drawable->width : i->drawable->height) - 1;
+
+ int nx = i->ox + i->mirror ? right : left;
+ int ny = i->oy + top * (i->increment);
+
+ int nw = i->w - left - right;
+ int nh = i->h - top - bottom;
+
+ int wmax, hmax;
+
+ if (nx < 0) nx = 0;
+ else if (nx > xmax) nx = xmax;
+
+ if (ny < 0) ny = 0;
+ else if (ny > ymax) ny = ymax;
+
+ wmax = xmax - nx + 1;
+ hmax = i->increment ? ny + 1 : ymax - ny + 1;
+
+ if (nw < 1) nw = 1;
+ else if (nw > wmax) nw = wmax;
+
+ if (nh < 1) nh = 1;
+ else if (nh > hmax) nh = hmax;
+
+ i->ox = nx;
+ i->oy = ny;
+ i->w = nw;
+ i->h = nh;
+}
+
+static void
+Image_rotate_ccw(stp_image_t *image)
+{
+ Image_transpose(image);
+ Image_vflip(image);
+}
+
+static void
+Image_rotate_cw(stp_image_t *image)
+{
+ Image_transpose(image);
+ Image_hflip(image);
+}
+
+static void
+Image_rotate_180(stp_image_t *image)
+{
+ Image_vflip(image);
+ Image_hflip(image);
+}
+
+static int
+Image_bpp(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ return i->drawable->bpp;
+}
+
+static int
+Image_width(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ return i->w;
+}
+
+static int
+Image_height(stp_image_t *image)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ return i->h;
+}
+
+static stp_image_status_t
+Image_get_row(stp_image_t *image, unsigned char *data, int row)
+{
+ Gimp_Image_t *i = (Gimp_Image_t *) (image->rep);
+ if (i->columns)
+ gimp_pixel_rgn_get_col(&(i->rgn), data,
+ i->oy + row * i->increment, i->ox, i->w);
+ else
+ gimp_pixel_rgn_get_row(&(i->rgn), data,
+ i->ox, i->oy + row * i->increment, i->w);
+ if (i->mirror)
+ {
+ /* Flip row -- probably inefficiently */
+ int f, l, b = i->drawable->bpp;
+ for (f = 0, l = i->w - 1; f < l; f++, l--)
+ {
+ int c;
+ unsigned char tmp;
+ for (c = 0; c < b; c++)
+ {
+ tmp = data[f*b+c];
+ data[f*b+c] = data[l*b+c];
+ data[l*b+c] = tmp;
+ }
+ }
+ }
+ return STP_IMAGE_OK;
+}
+
+static void
+Image_progress_init(stp_image_t *image)
+{
+ gimp_progress_init(_("Printing..."));
+}
+
+static void
+Image_note_progress(stp_image_t *image, double current, double total)
+{
+ gimp_progress_update(current / total);
+}
+
+static void
+Image_progress_conclude(stp_image_t *image)
+{
+ gimp_progress_update(1);
+}
+
+static const char *
+Image_get_appname(stp_image_t *image)
+{
+ static char pluginname[] = PLUG_IN_NAME " plug-in V" PLUG_IN_VERSION
+ " for GIMP";
+ return pluginname;
+}
+
+/*
+ * End of "$Id: print-image-gimp.c,v 1.5 2001/07/28 01:42:25 rlk Exp $".
+ */
diff --git a/src/gimp/print-intl.h b/src/gimp/print-intl.h
new file mode 100644
index 0000000..dfc5c12
--- /dev/null
+++ b/src/gimp/print-intl.h
@@ -0,0 +1,36 @@
+/*
+ * "$Id: print-intl.h,v 1.2 2001/09/08 17:17:34 rleigh Exp $"
+ *
+ * I18N header file for the gimp-print plugin.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu) and Michael Natterer (mitch@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 __PRINT_INTL_H__
+#define __PRINT_INTL_H__
+
+#include <glib.h>
+#include <gimp-print/gimp-print-intl.h>
+
+#define INIT_LOCALE(domain) G_STMT_START{ \
+ gtk_set_locale (); \
+ setlocale (LC_NUMERIC, "C"); \
+ bindtextdomain (domain, PACKAGE_LOCALE_DIR); \
+ textdomain (domain); \
+ }G_STMT_END
+
+#endif /* __PRINT_INTL_H__ */
diff --git a/src/gimp/print.c b/src/gimp/print.c
new file mode 100644
index 0000000..31347aa
--- /dev/null
+++ b/src/gimp/print.c
@@ -0,0 +1,1319 @@
+/*
+ * "$Id: print.c,v 1.22 2001/09/08 17:17:34 rleigh Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
+ * Robert Krawitz (rlk@alum.mit.edu)
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "../../lib/libprintut.h"
+
+#include "print_gimp.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#ifdef __EMX__
+#define INCL_DOSDEVICES
+#define INCL_DOSERRORS
+#include <os2.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "print-intl.h"
+
+/*
+ * Local functions...
+ */
+
+static void printrc_load (void);
+void printrc_save (void);
+static int compare_printers (gp_plist_t *p1, gp_plist_t *p2);
+static void get_system_printers (void);
+
+static void query (void);
+static void run (char *, int, GimpParam *, int *, GimpParam **);
+static int do_print_dialog (char *proc_name);
+
+/*
+ * Globals...
+ */
+
+GimpPlugInInfo PLUG_IN_INFO = /* Plug-in information */
+{
+ NULL, /* init_proc */
+ NULL, /* quit_proc */
+ query, /* query_proc */
+ run, /* run_proc */
+};
+
+stp_vars_t vars = NULL;
+
+int plist_current = 0, /* Current system printer */
+ plist_count = 0; /* Number of system printers */
+gp_plist_t *plist; /* System printers */
+
+int saveme = FALSE; /* True if print should proceed */
+int runme = FALSE; /* True if print should proceed */
+stp_printer_t current_printer = 0; /* Current printer index */
+gint32 image_ID; /* image ID */
+
+const char *image_filename;
+int image_width;
+int image_height;
+
+static void
+check_plist(int count)
+{
+ static int current_plist_size = 0;
+ if (count <= current_plist_size)
+ return;
+ else if (current_plist_size == 0)
+ {
+ current_plist_size = count;
+ plist = xmalloc(current_plist_size * sizeof(gp_plist_t));
+ }
+ else
+ {
+ current_plist_size *= 2;
+ if (current_plist_size < count)
+ current_plist_size = count;
+ plist = realloc(plist, current_plist_size * sizeof(gp_plist_t));
+ }
+}
+
+/*
+ * 'main()' - Main entry - just call gimp_main()...
+ */
+
+MAIN()
+
+static int print_finished = 0;
+
+/*
+ * 'query()' - Respond to a plug-in query...
+ */
+
+static void
+query (void)
+{
+ static const GimpParamDef args[] =
+ {
+ { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
+ { GIMP_PDB_IMAGE, "image", "Input image" },
+ { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
+ { GIMP_PDB_STRING, "output_to", "Print command or filename (| to pipe to command)" },
+ { GIMP_PDB_STRING, "driver", "Printer driver short name" },
+ { GIMP_PDB_STRING, "ppd_file", "PPD file" },
+ { GIMP_PDB_INT32, "output_type", "Output type (0 = gray, 1 = color)" },
+ { GIMP_PDB_STRING, "resolution", "Resolution (\"300\", \"720\", etc.)" },
+ { GIMP_PDB_STRING, "media_size", "Media size (\"Letter\", \"A4\", etc.)" },
+ { GIMP_PDB_STRING, "media_type", "Media type (\"Plain\", \"Glossy\", etc.)" },
+ { GIMP_PDB_STRING, "media_source", "Media source (\"Tray1\", \"Manual\", etc.)" },
+ { GIMP_PDB_FLOAT, "brightness", "Brightness (0-400%)" },
+ { GIMP_PDB_FLOAT, "scaling", "Output scaling (0-100%, -PPI)" },
+ { GIMP_PDB_INT32, "orientation", "Output orientation (-1 = auto, 0 = portrait, 1 = landscape)" },
+ { GIMP_PDB_INT32, "left", "Left offset (points, -1 = centered)" },
+ { GIMP_PDB_INT32, "top", "Top offset (points, -1 = centered)" },
+ { GIMP_PDB_FLOAT, "gamma", "Output gamma (0.1 - 3.0)" },
+ { GIMP_PDB_FLOAT, "contrast", "Contrast" },
+ { GIMP_PDB_FLOAT, "cyan", "Cyan level" },
+ { GIMP_PDB_FLOAT, "magenta", "Magenta level" },
+ { GIMP_PDB_FLOAT, "yellow", "Yellow level" },
+ { GIMP_PDB_INT32, "linear", "Linear output (0 = normal, 1 = linear)" },
+ { GIMP_PDB_INT32, "image_type", "Image type (0 = line art, 1 = solid tones, 2 = continuous tone, 3 = monochrome)"},
+ { GIMP_PDB_FLOAT, "saturation", "Saturation (0-1000%)" },
+ { GIMP_PDB_FLOAT, "density", "Density (0-200%)" },
+ { GIMP_PDB_STRING, "ink_type", "Type of ink or cartridge" },
+ { GIMP_PDB_STRING, "dither_algorithm", "Dither algorithm" },
+ { GIMP_PDB_INT32, "unit", "Unit 0=Inches 1=Metric" },
+ };
+ static gint nargs = sizeof(args) / sizeof(args[0]);
+
+ static gchar *blurb = "This plug-in prints images from The GIMP.";
+ static gchar *help = "Prints images to PostScript, PCL, or ESC/P2 printers.";
+ static gchar *auth = "Michael Sweet <mike@easysw.com> and Robert Krawitz <rlk@alum.mit.edu>";
+ static gchar *copy = "Copyright 1997-2000 by Michael Sweet and Robert Krawitz";
+ static gchar *types = "RGB*,GRAY*,INDEXED*";
+
+ gimp_plugin_domain_register (PACKAGE, PACKAGE_LOCALE_DIR);
+
+ gimp_install_procedure ("file_print_gimp",
+ blurb, help, auth, copy,
+ PLUG_IN_VERSION,
+ N_("<Image>/File/Print..."),
+ types,
+ GIMP_PLUGIN,
+ nargs, 0,
+ args, NULL);
+}
+
+#ifdef __EMX__
+static char *
+get_tmp_filename()
+{
+ char *tmp_path, *s, filename[80];
+
+ tmp_path = getenv("TMP");
+ if (tmp_path == NULL)
+ tmp_path = "";
+
+ sprintf(filename, "gimp_print_tmp.%d", getpid());
+ s = tmp_path = g_strconcat(tmp_path, "\\", filename, NULL);
+ if (!s)
+ return NULL;
+ for ( ; *s; s++)
+ if (*s == '/') *s = '\\';
+ return tmp_path;
+}
+#endif
+
+/*
+ * 'usr1_handler()' - Make a note when we receive SIGUSR1.
+ */
+
+static volatile int usr1_interrupt;
+
+static void
+usr1_handler (int signal)
+{
+ usr1_interrupt = 1;
+}
+
+void
+gimp_writefunc(void *file, const char *buf, size_t bytes)
+{
+ FILE *prn = (FILE *)file;
+ fwrite(buf, 1, bytes, prn);
+}
+
+/*
+ * 'run()' - Run the plug-in...
+ */
+
+/* #define DEBUG_STARTUP */
+
+#ifdef DEBUG_STARTUP
+volatile int SDEBUG = 1;
+#endif
+
+static void
+run (char *name, /* I - Name of print program. */
+ int nparams, /* I - Number of parameters passed in */
+ GimpParam *param, /* I - Parameter values */
+ int *nreturn_vals, /* O - Number of return values */
+ GimpParam **return_vals) /* O - Return values */
+{
+ GimpDrawable *drawable; /* Drawable for image */
+ GimpRunModeType run_mode; /* Current run mode */
+ FILE *prn = NULL; /* Print file/command */
+ int ncolors; /* Number of colors in colormap */
+ GimpParam *values; /* Return values */
+#ifdef __EMX__
+ char *tmpfile; /* temp filename */
+#endif
+ gint32 drawable_ID; /* drawable ID */
+ GimpExportReturnType export = GIMP_EXPORT_CANCEL; /* return value of gimp_export_image() */
+ int ppid = getpid (), /* PID of plugin */
+ opid, /* PID of output process */
+ cpid = 0, /* PID of control/monitor process */
+ pipefd[2]; /* Fds of the pipe connecting all the above */
+ int dummy;
+#ifdef DEBUG_STARTUP
+ while (SDEBUG)
+ ;
+#endif
+
+ /*
+ * Initialise libgimpprint
+ */
+
+ stp_init();
+
+#ifdef INIT_I18N_UI
+ INIT_I18N_UI();
+#else
+ INIT_LOCALE (PACKAGE);
+#endif
+
+ vars = stp_allocate_copy(stp_default_settings());
+ stp_set_input_color_model(vars, COLOR_MODEL_RGB);
+ stp_set_output_color_model(vars, COLOR_MODEL_RGB);
+ /*
+ * Initialize parameter data...
+ */
+
+ current_printer = stp_get_printer_by_index (0);
+ run_mode = (GimpRunModeType)param[0].data.d_int32;
+
+ values = g_new (GimpParam, 1);
+
+ values[0].type = GIMP_PDB_STATUS;
+ values[0].data.d_status = GIMP_PDB_SUCCESS;
+
+ *nreturn_vals = 1;
+ *return_vals = values;
+
+ image_ID = param[1].data.d_int32;
+ drawable_ID = param[2].data.d_int32;
+
+ image_filename = gimp_image_get_filename (image_ID);
+ if (strchr(image_filename, '/'))
+ image_filename = strrchr(image_filename, '/') + 1;
+
+ /* eventually export the image */
+ switch (run_mode)
+ {
+ case GIMP_RUN_INTERACTIVE:
+ case GIMP_RUN_WITH_LAST_VALS:
+ gimp_ui_init ("print", TRUE);
+ export = gimp_export_image (&image_ID, &drawable_ID, "Print",
+ (GIMP_EXPORT_CAN_HANDLE_RGB |
+ GIMP_EXPORT_CAN_HANDLE_GRAY |
+ GIMP_EXPORT_CAN_HANDLE_INDEXED |
+ GIMP_EXPORT_CAN_HANDLE_ALPHA));
+ if (export == GIMP_EXPORT_CANCEL)
+ {
+ *nreturn_vals = 1;
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Get drawable...
+ */
+
+ drawable = gimp_drawable_get (drawable_ID);
+
+ image_width = drawable->width;
+ image_height = drawable->height;
+
+ /*
+ * See how we will run
+ */
+
+ switch (run_mode)
+ {
+ case GIMP_RUN_INTERACTIVE:
+ /*
+ * Get information from the dialog...
+ */
+
+ if (!do_print_dialog (name))
+ goto cleanup;
+ stp_copy_vars(vars, plist[plist_current].v);
+ break;
+
+ case GIMP_RUN_NONINTERACTIVE:
+ /*
+ * Make sure all the arguments are present...
+ */
+ if (nparams < 11)
+ values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+ else
+ {
+ stp_set_output_to(vars, param[3].data.d_string);
+ stp_set_driver(vars, param[4].data.d_string);
+ stp_set_ppd_file(vars, param[5].data.d_string);
+ stp_set_output_type(vars, param[6].data.d_int32);
+ stp_set_resolution(vars, param[7].data.d_string);
+ stp_set_media_size(vars, param[8].data.d_string);
+ stp_set_media_type(vars, param[9].data.d_string);
+ stp_set_media_source(vars, param[10].data.d_string);
+
+ if (nparams > 11)
+ stp_set_brightness(vars, param[11].data.d_float);
+
+ if (nparams > 12)
+ stp_set_scaling(vars, param[12].data.d_float);
+
+ if (nparams > 13)
+ stp_set_orientation(vars, param[13].data.d_int32);
+
+ if (nparams > 14)
+ stp_set_left(vars, param[14].data.d_int32);
+
+ if (nparams > 15)
+ stp_set_top(vars, param[15].data.d_int32);
+
+ if (nparams > 16)
+ stp_set_gamma(vars, param[16].data.d_float);
+
+ if (nparams > 17)
+ stp_set_contrast(vars, param[17].data.d_float);
+
+ if (nparams > 18)
+ stp_set_cyan(vars, param[18].data.d_float);
+
+ if (nparams > 19)
+ stp_set_magenta(vars, param[19].data.d_float);
+
+ if (nparams > 20)
+ stp_set_yellow(vars, param[20].data.d_float);
+
+ if (nparams > 21)
+ stp_set_image_type(vars, param[22].data.d_int32);
+
+ if (nparams > 22)
+ stp_set_saturation(vars, param[23].data.d_float);
+
+ if (nparams > 23)
+ stp_set_density(vars, param[24].data.d_float);
+
+ if (nparams > 24)
+ stp_set_ink_type(vars, param[25].data.d_string);
+
+ if (nparams > 25)
+ stp_set_dither_algorithm(vars, param[26].data.d_string);
+
+ if (nparams > 26)
+ stp_set_unit(vars, param[27].data.d_int32);
+ }
+
+ current_printer = stp_get_printer_by_driver (stp_get_driver(vars));
+ break;
+
+ case GIMP_RUN_WITH_LAST_VALS:
+ values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+ break;
+
+ default:
+ values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+ break;
+ }
+
+ /*
+ * Print the image...
+ */
+ if (values[0].data.d_status == GIMP_PDB_SUCCESS)
+ {
+ /*
+ * Set the tile cache size...
+ */
+
+ if (drawable->height > drawable->width)
+ gimp_tile_cache_ntiles ((drawable->height + gimp_tile_width () - 1) /
+ gimp_tile_width () + 1);
+ else
+ gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) /
+ gimp_tile_width () + 1);
+
+ /*
+ * Open the file/execute the print command...
+ */
+
+ if (plist_current > 0)
+#ifndef __EMX__
+ {
+ /*
+ * The following IPC code is only necessary because the GIMP kills
+ * plugins with SIGKILL if its "Cancel" button is pressed; this
+ * gives the plugin no chance whatsoever to clean up after itself.
+ */
+ usr1_interrupt = 0;
+ signal (SIGUSR1, usr1_handler);
+ if (pipe (pipefd) != 0) {
+ prn = NULL;
+ } else {
+ cpid = fork ();
+ if (cpid < 0) {
+ prn = NULL;
+ } else if (cpid == 0) {
+ /* LPR monitor process. Printer output is piped to us. */
+ opid = fork ();
+ if (opid < 0) {
+ /* Errors will cause the plugin to get a SIGPIPE. */
+ exit (1);
+ } else if (opid == 0) {
+ dup2 (pipefd[0], 0);
+ close (pipefd[0]);
+ close (pipefd[1]);
+ execl("/bin/sh", "/bin/sh", "-c", stp_get_output_to(vars), NULL);
+ /* NOTREACHED */
+ exit (1);
+ } else {
+ /*
+ * If the print plugin gets SIGKILLed by gimp, we kill lpr
+ * in turn. If the plugin signals us with SIGUSR1 that it's
+ * finished printing normally, we close our end of the pipe,
+ * and go away.
+ */
+ close (pipefd[0]);
+ while (usr1_interrupt == 0) {
+ if (kill (ppid, 0) < 0) {
+ /* The print plugin has been killed! */
+ kill (opid, SIGTERM);
+ waitpid (opid, &dummy, 0);
+ close (pipefd[1]);
+ /*
+ * We do not want to allow cleanup before exiting.
+ * The exiting parent has already closed the connection
+ * to the X server; if we try to clean up, we'll notice
+ * that fact and complain.
+ */
+ _exit (0);
+ }
+ sleep (5);
+ }
+ /* We got SIGUSR1. */
+ close (pipefd[1]);
+ /*
+ * We do not want to allow cleanup before exiting.
+ * The exiting parent has already closed the connection
+ * to the X server; if we try to clean up, we'll notice
+ * that fact and complain.
+ */
+ _exit (0);
+ }
+ } else {
+ close (pipefd[0]);
+ /* Parent process. We generate the printer output. */
+ prn = fdopen (pipefd[1], "w");
+ /* and fall through... */
+ }
+ }
+ }
+#else
+ /* OS/2 PRINT command doesn't support print from stdin, use temp file */
+ prn = (tmpfile = get_tmp_filename ()) ? fopen (tmpfile, "w") : NULL;
+#endif
+ else
+ prn = fopen (stp_get_output_to(vars), "wb");
+
+ if (prn != NULL)
+ {
+ stp_image_t *image = Image_GimpDrawable_new(drawable);
+ stp_set_app_gamma(vars, gimp_gamma());
+ stp_merge_printvars(vars, stp_printer_get_printvars(current_printer));
+
+ /*
+ * Is the image an Indexed type? If so we need the colormap...
+ */
+
+ if (gimp_image_base_type (image_ID) == GIMP_INDEXED)
+ stp_set_cmap(vars, gimp_image_get_cmap (image_ID, &ncolors));
+ else
+ stp_set_cmap(vars, NULL);
+
+ /*
+ * Finally, call the print driver to send the image to the printer
+ * and close the output file/command...
+ */
+
+ stp_set_outfunc(vars, gimp_writefunc);
+ stp_set_errfunc(vars, gimp_writefunc);
+ stp_set_outdata(vars, prn);
+ stp_set_errdata(vars, stderr);
+ if (stp_printer_get_printfuncs(current_printer)->verify
+ (current_printer, vars))
+ stp_printer_get_printfuncs(current_printer)->print
+ (current_printer, image, vars);
+ else
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+
+ if (plist_current > 0)
+#ifndef __EMX__
+ {
+ fclose (prn);
+ kill (cpid, SIGUSR1);
+ waitpid (cpid, &dummy, 0);
+ }
+#else
+ { /* PRINT temp file */
+ char *s;
+ fclose (prn);
+ s = g_strconcat (stp_get_output_to(vars), tmpfile, NULL);
+ if (system(s) != 0)
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+ g_free (s);
+ remove (tmpfile);
+ g_free (tmpfile);
+ }
+#endif
+ else
+ fclose (prn);
+ print_finished = 1;
+ }
+ else
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+
+ /*
+ * Store data...
+ */
+
+ if (run_mode == GIMP_RUN_INTERACTIVE)
+ gimp_set_data (PLUG_IN_NAME, vars, sizeof (vars));
+ }
+
+ /*
+ * Detach from the drawable...
+ */
+ gimp_drawable_detach (drawable);
+
+ cleanup:
+ if (export == GIMP_EXPORT_EXPORT)
+ gimp_image_delete (image_ID);
+ stp_free_vars(vars);
+}
+
+/*
+ * 'do_print_dialog()' - Pop up the print dialog...
+ */
+
+static gint
+do_print_dialog (gchar *proc_name)
+{
+
+ /*
+ * Get printrc options...
+ */
+ printrc_load ();
+
+ /*
+ * Print dialog window...
+ */
+ gimp_create_main_window();
+
+ gtk_main ();
+ gdk_flush ();
+
+ /*
+ * Set printrc options...
+ */
+ if (saveme)
+ printrc_save ();
+
+ /*
+ * Return ok/cancel...
+ */
+ return (runme);
+}
+
+void
+initialize_printer(gp_plist_t *printer)
+{
+ printer->name[0] = '\0';
+ printer->active=0;
+ printer->v = stp_allocate_vars();
+}
+
+#define GET_MANDATORY_INTERNAL_STRING_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ strncpy(key.param, lineptr, commaptr - line); \
+ key.param[commaptr - lineptr] = '\0'; \
+ lineptr = commaptr + 1; \
+} while (0)
+
+#define GET_MANDATORY_STRING_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ stp_set_##param##_n(key.v, lineptr, commaptr - line); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+#define GET_MANDATORY_INT_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ stp_set_##param(key.v, atoi(lineptr)); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+#define GET_OPTIONAL_STRING_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ { \
+ stp_set_##param(key.v, lineptr); \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ stp_set_##param##_n(key.v, lineptr, commaptr - lineptr); \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+#define GET_OPTIONAL_INT_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ stp_set_##param(key.v, atoi(lineptr)); \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+#define IGNORE_OPTIONAL_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+#define GET_OPTIONAL_FLOAT_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ const stp_vars_t maxvars = stp_maximum_settings(); \
+ const stp_vars_t minvars = stp_minimum_settings(); \
+ const stp_vars_t defvars = stp_default_settings(); \
+ stp_set_##param(key.v, atof(lineptr)); \
+ if (stp_get_##param(key.v) > 0 && \
+ (stp_get_##param(key.v) > stp_get_##param(maxvars) || \
+ stp_get_##param(key.v) < stp_get_##param(minvars))) \
+ stp_set_##param(key.v, stp_get_##param(defvars)); \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+static void *
+psearch(const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *))
+{
+ int i;
+ const char *cbase = (const char *) base;
+ for (i = 0; i < nmemb; i++)
+ {
+ if ((*compar)(key, (const void *) cbase) == 0)
+ return (void *) cbase;
+ cbase += size;
+ }
+ return NULL;
+}
+
+int
+add_printer(const gp_plist_t *key, int add_only)
+{
+ /*
+ * The format of the list is the File printer followed by a qsort'ed list
+ * of system printers. So, if we want to update the file printer, it is
+ * always first in the list, else call psearch.
+ */
+ gp_plist_t *p;
+ if (strcmp(_("File"), key->name) == 0
+ && strcmp(plist[0].name, _("File")) == 0)
+ {
+ if (add_only)
+ return 0;
+ if (stp_get_printer_by_driver(stp_get_driver(key->v)))
+ {
+#ifdef DEBUG
+ printf("Updated File printer directly\n");
+#endif
+ p = &plist[0];
+ memcpy(p, key, sizeof(gp_plist_t));
+ p->v = stp_allocate_copy(key->v);
+ p->active = 1;
+ }
+ return 1;
+ }
+ else if (stp_get_printer_by_driver(stp_get_driver(key->v)))
+ {
+ p = psearch(key, plist + 1, plist_count - 1,
+ sizeof(gp_plist_t),
+ (int (*)(const void *, const void *)) compare_printers);
+ if (p == NULL)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "Adding new printer from printrc file: %s\n",
+ key->name);
+#endif
+ check_plist(plist_count + 1);
+ p = plist + plist_count;
+ plist_count++;
+ memcpy(p, key, sizeof(gp_plist_t));
+ p->v = stp_allocate_copy(key->v);
+ p->active = 0;
+ }
+ else
+ {
+ if (add_only)
+ return 0;
+#ifdef DEBUG
+ printf("Updating printer %s.\n", key->name);
+#endif
+ memcpy(p, key, sizeof(gp_plist_t));
+ stp_copy_vars(p->v, key->v);
+ p->active = 1;
+ }
+ }
+ return 1;
+}
+
+/*
+ * 'printrc_load()' - Load the printer resource configuration file.
+ */
+void
+printrc_load(void)
+{
+ int i; /* Looping var */
+ FILE *fp; /* Printrc file */
+ char *filename; /* Its name */
+ char line[1024], /* Line in printrc file */
+ *lineptr, /* Pointer in line */
+ *commaptr; /* Pointer to next comma */
+ gp_plist_t key; /* Search key */
+ int format = 0; /* rc file format version */
+ int system_printers; /* printer count before reading printrc */
+ char * current_printer = 0; /* printer to select */
+
+ check_plist(1);
+
+ /*
+ * Get the printer list...
+ */
+
+ get_system_printers();
+
+ system_printers = plist_count - 1;
+
+ /*
+ * Generate the filename for the current user...
+ */
+
+ filename = gimp_personal_rc_file ("printrc");
+
+#ifdef __EMX__
+ _fnslashify(filename);
+#endif
+
+#ifndef __EMX__
+ if ((fp = fopen(filename, "r")) != NULL)
+#else
+ if ((fp = fopen(filename, "rt")) != NULL)
+#endif
+ {
+ /*
+ * File exists - read the contents and update the printer list...
+ */
+
+ (void) memset(&key, 0, sizeof(gp_plist_t));
+ initialize_printer(&key);
+ strcpy(key.name, _("File"));
+ (void) memset(line, 0, 1024);
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ int keepgoing = 1;
+ if (line[0] == '#')
+ {
+ if (strncmp("#PRINTRCv", line, 9) == 0)
+ {
+#ifdef DEBUG
+ printf("Found printrc version tag: `%s'\n", line);
+ printf("Version number: `%s'\n", &(line[9]));
+#endif
+ (void) sscanf(&(line[9]), "%d", &format);
+ }
+ continue; /* Comment */
+ }
+ if (format == 0)
+ {
+ /*
+ * Read old format printrc lines...
+ */
+
+ initialize_printer(&key);
+ lineptr = line;
+
+ /*
+ * Read the command-delimited printer definition data. Note that
+ * we can't use sscanf because %[^,] fails if the string is empty...
+ */
+
+ GET_MANDATORY_INTERNAL_STRING_PARAM(name);
+ GET_MANDATORY_STRING_PARAM(output_to);
+ GET_MANDATORY_STRING_PARAM(driver);
+
+ if (! stp_get_printer_by_driver(stp_get_driver(key.v)))
+ continue;
+
+ GET_MANDATORY_STRING_PARAM(ppd_file);
+ GET_MANDATORY_INT_PARAM(output_type);
+ GET_MANDATORY_STRING_PARAM(resolution);
+ GET_MANDATORY_STRING_PARAM(media_size);
+ GET_MANDATORY_STRING_PARAM(media_type);
+
+ GET_OPTIONAL_STRING_PARAM(media_source);
+ GET_OPTIONAL_FLOAT_PARAM(brightness);
+ GET_OPTIONAL_FLOAT_PARAM(scaling);
+ GET_OPTIONAL_INT_PARAM(orientation);
+ GET_OPTIONAL_INT_PARAM(left);
+ GET_OPTIONAL_INT_PARAM(top);
+ GET_OPTIONAL_FLOAT_PARAM(gamma);
+ GET_OPTIONAL_FLOAT_PARAM(contrast);
+ GET_OPTIONAL_FLOAT_PARAM(cyan);
+ GET_OPTIONAL_FLOAT_PARAM(magenta);
+ GET_OPTIONAL_FLOAT_PARAM(yellow);
+ IGNORE_OPTIONAL_PARAM(linear);
+ GET_OPTIONAL_INT_PARAM(image_type);
+ GET_OPTIONAL_FLOAT_PARAM(saturation);
+ GET_OPTIONAL_FLOAT_PARAM(density);
+ GET_OPTIONAL_STRING_PARAM(ink_type);
+ GET_OPTIONAL_STRING_PARAM(dither_algorithm);
+ GET_OPTIONAL_INT_PARAM(unit);
+ add_printer(&key, 0);
+ }
+ else if (format == 1)
+ {
+ /*
+ * Read new format printrc lines...
+ */
+
+ char *keyword, *end, *value;
+
+ keyword = line;
+ for (keyword = line; isspace(*keyword); keyword++)
+ {
+ /* skip initial spaces... */
+ }
+ if (!isalpha(*keyword))
+ continue;
+ for (end = keyword; isalnum(*end) || *end == '-'; end++)
+ {
+ /* find end of keyword... */
+ }
+ value = end;
+ while (isspace(*value)) {
+ /* skip over white space... */
+ value++;
+ }
+ if (*value != ':')
+ continue;
+ value++;
+ *end = '\0';
+ while (isspace(*value)) {
+ /* skip over white space... */
+ value++;
+ }
+ for (end = value; *end && *end != '\n'; end++)
+ {
+ /* find end of line... */
+ }
+ *end = '\0';
+#ifdef DEBUG
+ printf("Keyword = `%s', value = `%s'\n", keyword, value);
+#endif
+ if (strcasecmp("current-printer", keyword) == 0) {
+ if (current_printer)
+ free (current_printer);
+ current_printer = g_strdup(value);
+ } else if (strcasecmp("printer", keyword) == 0) {
+ /* Switch to printer named VALUE */
+ add_printer(&key, 0);
+#ifdef DEBUG
+ printf("output_to is now %s\n", stp_get_output_to(p->v));
+#endif
+
+ initialize_printer(&key);
+ strncpy(key.name, value, 127);
+ } else if (strcasecmp("destination", keyword) == 0) {
+ stp_set_output_to(key.v, value);
+ } else if (strcasecmp("driver", keyword) == 0) {
+ stp_set_driver(key.v, value);
+ } else if (strcasecmp("ppd-file", keyword) == 0) {
+ stp_set_ppd_file(key.v, value);
+ } else if (strcasecmp("output-type", keyword) == 0) {
+ stp_set_output_type(key.v, atoi(value));
+ } else if (strcasecmp("resolution", keyword) == 0) {
+ stp_set_resolution(key.v, value);
+ } else if (strcasecmp("media-size", keyword) == 0) {
+ stp_set_media_size(key.v, value);
+ } else if (strcasecmp("media-type", keyword) == 0) {
+ stp_set_media_type(key.v, value);
+ } else if (strcasecmp("media-source", keyword) == 0) {
+ stp_set_media_source(key.v, value);
+ } else if (strcasecmp("brightness", keyword) == 0) {
+ stp_set_brightness(key.v, atof(value));
+ } else if (strcasecmp("scaling", keyword) == 0) {
+ stp_set_scaling(key.v, atof(value));
+ } else if (strcasecmp("orientation", keyword) == 0) {
+ stp_set_orientation(key.v, atoi(value));
+ } else if (strcasecmp("left", keyword) == 0) {
+ stp_set_left(key.v, atoi(value));
+ } else if (strcasecmp("top", keyword) == 0) {
+ stp_set_top(key.v, atoi(value));
+ } else if (strcasecmp("gamma", keyword) == 0) {
+ stp_set_gamma(key.v, atof(value));
+ } else if (strcasecmp("contrast", keyword) == 0) {
+ stp_set_contrast(key.v, atof(value));
+ } else if (strcasecmp("cyan", keyword) == 0) {
+ stp_set_cyan(key.v, atof(value));
+ } else if (strcasecmp("magenta", keyword) == 0) {
+ stp_set_magenta(key.v, atof(value));
+ } else if (strcasecmp("yellow", keyword) == 0) {
+ stp_set_yellow(key.v, atof(value));
+ } else if (strcasecmp("linear", keyword) == 0) {
+ /* Ignore linear */
+ } else if (strcasecmp("image-type", keyword) == 0) {
+ stp_set_image_type(key.v, atoi(value));
+ } else if (strcasecmp("saturation", keyword) == 0) {
+ stp_set_saturation(key.v, atof(value));
+ } else if (strcasecmp("density", keyword) == 0) {
+ stp_set_density(key.v, atof(value));
+ } else if (strcasecmp("ink-type", keyword) == 0) {
+ stp_set_ink_type(key.v, value);
+ } else if (strcasecmp("dither-algorithm", keyword) == 0) {
+ stp_set_dither_algorithm(key.v, value);
+ } else if (strcasecmp("unit", keyword) == 0) {
+ stp_set_unit(key.v, atoi(value));
+ } else if (strcasecmp("custom-page-width", keyword) == 0) {
+ stp_set_page_width(key.v, atoi(value));
+ } else if (strcasecmp("custom-page-height", keyword) == 0) {
+ stp_set_page_height(key.v, atoi(value));
+ } else {
+ /* Unrecognised keyword; ignore it... */
+ printf("Unrecognized keyword `%s' in printrc; value `%s'\n", keyword, value);
+ }
+ }
+ else
+ {
+ /*
+ * We cannot read this file format...
+ */
+ }
+ }
+ if (format > 0)
+ add_printer(&key, 0);
+ fclose(fp);
+ }
+
+ g_free (filename);
+
+ /*
+ * Select the current printer as necessary...
+ */
+
+ if (format == 1)
+ {
+ if (current_printer)
+ {
+ for (i = 0; i < plist_count; i ++)
+ if (strcmp(current_printer, plist[i].name) == 0)
+ plist_current = i;
+ }
+ }
+ else
+ {
+ if (stp_get_output_to(vars)[0] != '\0')
+ {
+ for (i = 0; i < plist_count; i ++)
+ if (strcmp(stp_get_output_to(vars), stp_get_output_to(plist[i].v))== 0)
+ break;
+
+ if (i < plist_count)
+ plist_current = i;
+ }
+ }
+}
+
+/*
+ * 'printrc_save()' - Save the current printer resource configuration.
+ */
+void
+printrc_save(void)
+{
+ FILE *fp; /* Printrc file */
+ char *filename; /* Printrc filename */
+ int i; /* Looping var */
+ gp_plist_t *p; /* Current printer */
+
+ /*
+ * Generate the filename for the current user...
+ */
+
+ filename = gimp_personal_rc_file ("printrc");
+
+#ifdef __EMX__
+ _fnslashify(filename);
+#endif
+
+#ifndef __EMX__
+ if ((fp = fopen(filename, "w")) != NULL)
+#else
+ if ((fp = fopen(filename, "wt")) != NULL)
+#endif
+ {
+ /*
+ * Write the contents of the printer list...
+ */
+
+#ifdef DEBUG
+ fprintf(stderr, "Number of printers: %d\n", plist_count);
+#endif
+
+ fputs("#PRINTRCv1 written by GIMP-PRINT " PLUG_IN_VERSION "\n", fp);
+
+ fprintf(fp, "Current-Printer: %s\n", plist[plist_current].name);
+
+ for (i = 0, p = plist; i < plist_count; i ++, p ++)
+ {
+ fprintf(fp, "\nPrinter: %s\n", p->name);
+ fprintf(fp, "Destination: %s\n", stp_get_output_to(p->v));
+ fprintf(fp, "Driver: %s\n", stp_get_driver(p->v));
+ fprintf(fp, "PPD-File: %s\n", stp_get_ppd_file(p->v));
+ fprintf(fp, "Output-Type: %d\n", stp_get_output_type(p->v));
+ fprintf(fp, "Resolution: %s\n", stp_get_resolution(p->v));
+ fprintf(fp, "Media-Size: %s\n", stp_get_media_size(p->v));
+ fprintf(fp, "Media-Type: %s\n", stp_get_media_type(p->v));
+ fprintf(fp, "Media-Source: %s\n", stp_get_media_source(p->v));
+ fprintf(fp, "Brightness: %.3f\n", stp_get_brightness(p->v));
+ fprintf(fp, "Scaling: %.3f\n", stp_get_scaling(p->v));
+ fprintf(fp, "Orientation: %d\n", stp_get_orientation(p->v));
+ fprintf(fp, "Left: %d\n", stp_get_left(p->v));
+ fprintf(fp, "Top: %d\n", stp_get_top(p->v));
+ fprintf(fp, "Gamma: %.3f\n", stp_get_gamma(p->v));
+ fprintf(fp, "Contrast: %.3f\n", stp_get_contrast(p->v));
+ fprintf(fp, "Cyan: %.3f\n", stp_get_cyan(p->v));
+ fprintf(fp, "Magenta: %.3f\n", stp_get_magenta(p->v));
+ fprintf(fp, "Yellow: %.3f\n", stp_get_yellow(p->v));
+ fprintf(fp, "Image-Type: %d\n", stp_get_image_type(p->v));
+ fprintf(fp, "Saturation: %.3f\n", stp_get_saturation(p->v));
+ fprintf(fp, "Density: %.3f\n", stp_get_density(p->v));
+ fprintf(fp, "Ink-Type: %s\n", stp_get_ink_type(p->v));
+ fprintf(fp, "Dither-Algorithm: %s\n", stp_get_dither_algorithm(p->v));
+ fprintf(fp, "Unit: %d\n", stp_get_unit(p->v));
+ fprintf(fp, "Custom-Page-Width: %d\n", stp_get_page_width(p->v));
+ fprintf(fp, "Custom-Page-Height: %d\n", stp_get_page_height(p->v));
+
+#ifdef DEBUG
+ fprintf(stderr, "Wrote printer %d: %s\n", i, p->name);
+#endif
+
+ }
+ fclose(fp);
+ } else {
+ fprintf(stderr,"could not open printrc file \"%s\"\n",filename);
+ }
+ g_free (filename);
+}
+
+/*
+ * 'compare_printers()' - Compare system printer names for qsort().
+ */
+
+static int
+compare_printers(gp_plist_t *p1, /* I - First printer to compare */
+ gp_plist_t *p2) /* I - Second printer to compare */
+{
+ return (strcmp(p1->name, p2->name));
+}
+
+/*
+ * 'get_system_printers()' - Get a complete list of printers from the spooler.
+ */
+
+#define PRINTERS_NONE 0
+#define PRINTERS_LPC 1
+#define PRINTERS_LPSTAT 2
+
+extern int asprintf (char **result, const char *format, ...);
+
+static void
+get_system_printers(void)
+{
+ int i; /* Looping var */
+ int type; /* 0 = none, 1 = lpc, 2 = lpstat */
+ char command[255]; /* Command to run */
+ char defname[128]; /* Default printer name */
+ FILE *pfile; /* Pipe to status command */
+ char line[255]; /* Line from status command */
+ char *ptr; /* Pointer into line */
+ char name[128]; /* Printer name from status command */
+#ifdef __EMX__
+ BYTE pnum;
+#endif
+ static const char *lpcs[] = /* Possible locations of LPC... */
+ {
+ "/etc"
+ "/usr/bsd",
+ "/usr/etc",
+ "/usr/libexec",
+ "/usr/sbin"
+ };
+
+ /*
+ * Setup defaults...
+ */
+
+ defname[0] = '\0';
+
+ check_plist(1);
+ plist_count = 1;
+ initialize_printer(&plist[0]);
+ strcpy(plist[0].name, _("File"));
+ stp_set_driver(plist[0].v, "ps2");
+ stp_set_output_type(plist[0].v, OUTPUT_COLOR);
+
+ /*
+ * Figure out what command to run... We use lpstat if it is available over
+ * lpc since Solaris, CUPS, etc. provide both commands. No need to list
+ * each printer twice...
+ */
+
+ if (!access("/usr/bin/lpstat", X_OK))
+ {
+ strcpy(command, "/usr/bin/lpstat -d -p");
+ type = PRINTERS_LPSTAT;
+ }
+ else
+ {
+ for (i = 0; i < (sizeof(lpcs) / sizeof(lpcs[0])); i ++)
+ {
+ sprintf(command, "%s/lpc", lpcs[i]);
+
+ if (!access(command, X_OK))
+ break;
+ }
+
+ if (i < (sizeof(lpcs) / sizeof(lpcs[0])))
+ {
+ strcat(command, " status < /dev/null");
+ type = PRINTERS_LPC;
+ }
+ else
+ type = PRINTERS_NONE;
+ }
+
+ /*
+ * Run the command, if any, to get the available printers...
+ */
+
+ if (type > PRINTERS_NONE)
+ {
+ if ((pfile = popen(command, "r")) != NULL)
+ {
+ /*
+ * Read input as needed...
+ */
+
+ while (fgets(line, sizeof(line), pfile) != NULL)
+ switch (type)
+ {
+ char *result;
+ case PRINTERS_LPC :
+ if (!strncmp(line, "Press RETURN to continue", 24) &&
+ (ptr = strchr(line, ':')) != NULL &&
+ (strlen(ptr) - 2) < (ptr - line))
+ strcpy(line, ptr + 2);
+
+ if ((ptr = strchr(line, ':')) != NULL &&
+ line[0] != ' ' && line[0] != '\t')
+ {
+ check_plist(plist_count + 1);
+ *ptr = '\0';
+ initialize_printer(&plist[plist_count]);
+ strncpy(plist[plist_count].name, line,
+ sizeof(plist[plist_count].name) - 1);
+#ifdef DEBUG
+ fprintf(stderr, "Adding new printer from lpc: <%s>\n",
+ line);
+#endif
+ asprintf(&result, "lpr -P%s -l", line);
+ stp_set_output_to(plist[plist_count].v, result);
+ free(result);
+ stp_set_driver(plist[plist_count].v, "ps2");
+ plist_count ++;
+ }
+ break;
+
+ case PRINTERS_LPSTAT :
+ if ((sscanf(line, "printer %127s", name) == 1) ||
+ (sscanf(line, "Printer: %127s", name) == 1))
+ {
+ check_plist(plist_count + 1);
+ initialize_printer(&plist[plist_count]);
+ strncpy(plist[plist_count].name, name,
+ sizeof(plist[plist_count].name) - 1);
+#ifdef DEBUG
+ fprintf(stderr, "Adding new printer from lpc: <%s>\n",
+ name);
+#endif
+ asprintf(&result, "lp -s -d%s -oraw", name);
+ stp_set_output_to(plist[plist_count].v, result);
+ free(result);
+ stp_set_driver(plist[plist_count].v, "ps2");
+ plist_count ++;
+ }
+ else
+ sscanf(line, "system default destination: %127s", defname);
+ break;
+ }
+
+ pclose(pfile);
+ }
+ }
+
+#ifdef __EMX__
+ if (DosDevConfig(&pnum, DEVINFO_PRINTER) == NO_ERROR)
+ {
+ for (i = 1; i <= pnum; i++)
+ {
+ check_plist(plist_count + 1);
+ initialize_printer(&plist[plist_count]);
+ sprintf(plist[plist_count].name, "LPT%d:", i);
+ sprintf(plist[plist_count].v.output_to, "PRINT /D:LPT%d /B ", i);
+ strcpy(plist[plist_count].v.driver, "ps2");
+ plist_count ++;
+ }
+ }
+#endif
+
+ if (plist_count > 2)
+ qsort(plist + 1, plist_count - 1, sizeof(gp_plist_t),
+ (int (*)(const void *, const void *))compare_printers);
+
+ if (defname[0] != '\0' && stp_get_output_to(vars)[0] == '\0')
+ {
+ for (i = 0; i < plist_count; i ++)
+ if (strcmp(defname, plist[i].name) == 0)
+ break;
+
+ if (i < plist_count)
+ plist_current = i;
+ }
+}
+
+/*
+ * End of "$Id: print.c,v 1.22 2001/09/08 17:17:34 rleigh Exp $".
+ */
diff --git a/src/gimp/print_gimp.h b/src/gimp/print_gimp.h
new file mode 100644
index 0000000..cc5e682
--- /dev/null
+++ b/src/gimp/print_gimp.h
@@ -0,0 +1,124 @@
+/*
+ * "$Id: print_gimp.h,v 1.20 2001/09/05 00:39:42 rlk Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu). and Steve Miller (smiller@rni.net
+ *
+ * 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.
+ *
+ *
+ * Revision History:
+ *
+ * See ChangeLog
+ */
+
+#ifndef __PRINT_GIMP_H__
+#define __PRINT_GIMP_H__
+
+#ifdef __GNUC__
+#define inline __inline__
+#endif
+
+#include <gtk/gtk.h>
+
+/*
+ * We define GIMP_ENABLE_COMPAT_CRUFT here because we are still using
+ * the old API names. This is because we have to support 1.0 as well.
+ * This define is required as the default in Gimp was changed 24 Aug 00.
+ * This should be removed when we stop supporting 1.0.
+ */
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#ifdef INCLUDE_GIMP_PRINT_H
+#include INCLUDE_GIMP_PRINT_H
+#else
+#include <gimp-print/gimp-print.h>
+#endif
+
+/*
+ * All Gimp-specific code is in this file.
+ */
+
+#define PLUG_IN_VERSION VERSION " - " RELEASE_DATE
+#define PLUG_IN_NAME "Print"
+
+typedef struct /**** Printer List ****/
+{
+ int active; /* Do we know about this printer? */
+ char name[128]; /* Name of printer */
+ stp_vars_t v;
+} gp_plist_t;
+
+#define THUMBNAIL_MAXW (128)
+#define THUMBNAIL_MAXH (128)
+
+extern gint thumbnail_w, thumbnail_h, thumbnail_bpp;
+extern guchar *thumbnail_data;
+extern gint adjusted_thumbnail_bpp;
+extern guchar *adjusted_thumbnail_data;
+
+extern stp_vars_t vars;
+extern gint plist_count; /* Number of system printers */
+extern gint plist_current; /* Current system printer */
+extern gp_plist_t *plist; /* System printers */
+extern gint32 image_ID;
+extern const gchar *image_filename;
+extern gint image_width;
+extern gint image_height;
+extern stp_printer_t current_printer;
+extern gint runme;
+extern gint saveme;
+
+extern GtkWidget *gimp_color_adjust_dialog;
+extern GtkWidget *dither_algo_combo;
+extern stp_vars_t *pv;
+
+/*
+ * Function prototypes
+ */
+
+/* How to create an Image wrapping a Gimp drawable */
+extern void printrc_save (void);
+
+extern stp_image_t *Image_GimpDrawable_new(GimpDrawable *drawable);
+extern int add_printer(const gp_plist_t *key, int add_only);
+extern void initialize_printer(gp_plist_t *printer);
+extern void gimp_update_adjusted_thumbnail (void);
+extern void gimp_plist_build_combo (GtkWidget *combo,
+ gint num_items,
+ stp_param_t *items,
+ const gchar *cur_item,
+ const gchar *def_value,
+ GtkSignalFunc callback,
+ gint *callback_id);
+
+extern void gimp_invalidate_frame(void);
+extern void gimp_invalidate_preview_thumbnail(void);
+extern void gimp_do_color_updates (void);
+extern void gimp_redraw_color_swatch (void);
+extern void gimp_build_dither_combo (void);
+extern void gimp_create_color_adjust_window (void);
+extern void gimp_update_adjusted_thumbnail (void);
+extern void gimp_create_main_window (void);
+extern void gimp_set_color_sliders_active(int active);
+extern void gimp_writefunc (void *file, const char *buf, size_t bytes);
+extern void set_adjustment_tooltip(GtkObject *adjustment,
+ const gchar *tip, const gchar *private);
+
+#endif /* __PRINT_GIMP_H__ */