home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / print / gimp_main_window.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-15  |  75.6 KB  |  2,306 lines

  1. /*
  2.  * "$Id: gimp_main_window.c,v 1.8 2000/10/14 20:01:42 neo Exp $"
  3.  *
  4.  *   Main window code for Print plug-in for the GIMP.
  5.  *
  6.  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com),
  7.  *    Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
  8.  *      and Michael Natterer (mitch@gimp.org)
  9.  *
  10.  *   This program is free software; you can redistribute it and/or modify it
  11.  *   under the terms of the GNU General Public License as published by the Free
  12.  *   Software Foundation; either version 2 of the License, or (at your option)
  13.  *   any later version.
  14.  *
  15.  *   This program is distributed in the hope that it will be useful, but
  16.  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17.  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  18.  *   for more details.
  19.  *
  20.  *   You should have received a copy of the GNU General Public License
  21.  *   along with this program; if not, write to the Free Software
  22.  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  */
  24.  
  25. #ifdef HAVE_CONFIG_H
  26. #include "config.h"
  27. #endif
  28.  
  29. #define EXPANDED_PREVIEW_WINDOW
  30.  
  31. #include "print_gimp.h"
  32.  
  33. #ifndef GIMP_1_0
  34.  
  35. #define MAX_PREVIEW_PPI        (30)
  36.  
  37. #include "print-intl.h"
  38.  
  39. /*
  40.  * Constants for GUI...
  41.  */
  42. #define PREVIEW_SIZE_VERT  320 /* Assuming max media size of 24" A2 */
  43. #define PREVIEW_SIZE_HORIZ 280 /* Assuming max media size of 24" A2 */
  44.  
  45. extern vars_t           vars;
  46. extern gint             plist_count;       /* Number of system printers */
  47. extern gint             plist_current;     /* Current system printer */
  48. extern plist_t         *plist;          /* System printers */
  49. extern gint32           image_ID;
  50. extern const gchar     *image_filename;
  51. extern gint             image_width;
  52. extern gint             image_height;
  53. extern const printer_t *current_printer;
  54. extern gint             runme;
  55. extern gint             saveme;
  56.  
  57. void  printrc_save (void);
  58.  
  59. extern GtkWidget *gimp_color_adjust_dialog;
  60. extern GtkWidget *dither_algo_combo;
  61.  
  62. extern void gimp_do_color_updates    (void);
  63. extern void gimp_redraw_color_swatch (void);
  64. extern void gimp_build_dither_combo  (void);
  65.  
  66. /*
  67.  *  Main window widgets
  68.  */
  69. static GtkWidget *print_dialog;           /* Print dialog window */
  70. static GtkWidget *recenter_button;
  71. static GtkWidget *left_entry;
  72. static GtkWidget *right_entry;
  73. static GtkWidget *right_border_entry;
  74. static GtkWidget *width_entry;
  75. static GtkWidget *top_entry;
  76. static GtkWidget *bottom_entry;
  77. static GtkWidget *bottom_border_entry;
  78. static GtkWidget *height_entry;
  79. static GtkWidget *unit_inch;
  80. static GtkWidget *unit_cm;
  81. static GtkWidget *media_size_combo         = NULL;  /* Media size combo box */
  82. static gint       media_size_callback_id   = -1;    /* Media size calback ID */
  83. static GtkWidget *media_type_combo         = NULL;  /* Media type combo box */
  84. static gint       media_type_callback_id   = -1;    /* Media type calback ID */
  85. static GtkWidget *media_source_combo       = NULL;  /* Media source combo box */
  86. static gint       media_source_callback_id = -1;    /* Media source calback ID */
  87. static GtkWidget *ink_type_combo           = NULL;  /* Ink type combo box */
  88. static gint       ink_type_callback_id     = -1;    /* Ink type calback ID */
  89. static GtkWidget *resolution_combo         = NULL;  /* Resolution combo box */
  90. static gint       resolution_callback_id   = -1;    /* Resolution calback ID */
  91. static GtkWidget *orientation_menu         = NULL;  /* Orientation menu */
  92. static GtkWidget *scaling_percent;        /* Scale by percent */
  93. static GtkWidget *scaling_ppi;            /* Scale by pixels-per-inch */
  94. static GtkWidget *scaling_image;          /* Scale to the image */
  95. static GtkWidget *output_gray;            /* Output type toggle, black */
  96. static GtkWidget *output_color;           /* Output type toggle, color */
  97. static GtkWidget *image_line_art;
  98. static GtkWidget *image_solid_tone;
  99. static GtkWidget *image_continuous_tone;
  100. static GtkWidget *image_monochrome;
  101. static GtkWidget *setup_dialog;         /* Setup dialog window */
  102. static GtkWidget *printer_driver;       /* Printer driver widget */
  103. static GtkWidget *printer_crawler;      /* Scrolled Window for menu */
  104. static GtkWidget *ppd_file;             /* PPD file entry */
  105. static GtkWidget *ppd_button;           /* PPD file browse button */
  106. static GtkWidget *output_cmd;           /* Output command text entry */
  107. static GtkWidget *ppd_browser;          /* File selection dialog for PPD files */
  108. static GtkWidget *file_browser;         /* FSD for print files */
  109. static GtkWidget *adjust_color_button;
  110.  
  111. static GtkObject *scaling_adjustment;    /* Adjustment object for scaling */
  112. static gboolean   suppress_scaling_adjustment = FALSE;
  113. static gboolean   suppress_scaling_callback   = FALSE;
  114.  
  115.  
  116. static GtkDrawingArea *preview = NULL;    /* Preview drawing area widget */
  117. static gint            mouse_x;        /* Last mouse X */
  118. static gint            mouse_y;        /* Last mouse Y */
  119. static gint            mouse_button;    /* Button being dragged with */
  120.  
  121. static gint            printable_left;    /* Left pixel column of page */
  122. static gint            printable_top;    /* Top pixel row of page */
  123. static gint            printable_width;    /* Width of page on screen */
  124. static gint            printable_height;    /* Height of page on screen */
  125. static gint            print_width;    /* Printed width of image */
  126. static gint            print_height;    /* Printed height of image */
  127. static gint           left, right;            /* Imageable area */
  128. static gint            top, bottom;
  129. static gint           paper_width, paper_height;    /* Physical width */
  130.  
  131. static void gimp_scaling_update        (GtkAdjustment *adjustment);
  132. static void gimp_scaling_callback      (GtkWidget     *widget);
  133. static void gimp_plist_callback        (GtkWidget     *widget,
  134.                     gpointer       data);
  135. static void gimp_media_size_callback   (GtkWidget     *widget,
  136.                     gpointer       data);
  137. static void gimp_media_type_callback   (GtkWidget     *widget,
  138.                     gpointer       data);
  139. static void gimp_media_source_callback (GtkWidget     *widget,
  140.                     gpointer       data);
  141. static void gimp_ink_type_callback     (GtkWidget     *widget,
  142.                     gpointer       data);
  143. static void gimp_resolution_callback   (GtkWidget     *widget,
  144.                     gpointer       data);
  145. static void gimp_output_type_callback  (GtkWidget     *widget,
  146.                     gpointer       data);
  147. static void gimp_unit_callback         (GtkWidget     *widget,
  148.                     gpointer       data);
  149. #ifdef DO_LINEAR
  150. static void gimp_linear_callback       (GtkWidget     *widget,
  151.                     gpointer       data);
  152. #endif
  153. static void gimp_orientation_callback  (GtkWidget     *widget,
  154.                     gpointer       data);
  155. static void gimp_printandsave_callback (void);
  156. static void gimp_print_callback        (void);
  157. static void gimp_save_callback         (void);
  158.  
  159. static void gimp_setup_update          (void);
  160. static void gimp_setup_open_callback   (void);
  161. static void gimp_setup_ok_callback     (void);
  162. static void gimp_ppd_browse_callback   (void);
  163. static void gimp_ppd_ok_callback       (void);
  164. static void gimp_print_driver_callback (GtkWidget      *widget,
  165.                     gint            row,
  166.                     gint            column,
  167.                     GdkEventButton *event,
  168.                     gpointer        data);
  169.  
  170. static void gimp_file_ok_callback      (void);
  171. static void gimp_file_cancel_callback  (void);
  172.  
  173. static void gimp_preview_update              (void);
  174. static void gimp_preview_button_callback     (GtkWidget      *widget,
  175.                           GdkEventButton *bevent,
  176.                           gpointer        data);
  177. static void gimp_preview_motion_callback     (GtkWidget      *widget,
  178.                           GdkEventMotion *mevent,
  179.                           gpointer        data);
  180. static void gimp_position_callback           (GtkWidget      *widget);
  181. static void gimp_image_type_callback         (GtkWidget      *widget,
  182.                           gpointer        data);
  183.  
  184. extern void gimp_create_color_adjust_window  (void);
  185. extern void gimp_update_adjusted_thumbnail   (void);
  186.  
  187. static gint preview_ppi = 10;
  188.  
  189. #define THUMBNAIL_MAXW    (128)
  190. #define THUMBNAIL_MAXH    (128)
  191.  
  192. gint    thumbnail_w, thumbnail_h, thumbnail_bpp;
  193. guchar *thumbnail_data;
  194. gint    adjusted_thumbnail_bpp;
  195. guchar *adjusted_thumbnail_data;
  196.  
  197. /*
  198.  *  gimp_create_main_window()
  199.  */
  200. void
  201. gimp_create_main_window (void)
  202. {
  203.   GtkWidget *dialog;
  204.   GtkWidget *main_vbox;
  205.   GtkWidget *hbox;
  206.   GtkWidget *frame;
  207.   GtkWidget *vbox;
  208.   GtkWidget *ppvbox;
  209.   GtkWidget *table;
  210.   GtkWidget *printer_table;
  211.  
  212.   GtkWidget *label;
  213.   GtkWidget *button;
  214.   GtkWidget *entry;
  215.   GtkWidget *menu;
  216.   GtkWidget *list;       /* List of drivers */
  217.   GtkWidget *item;
  218.   GtkWidget *option;
  219.   GtkWidget *combo;      /* Combo box */
  220.   GtkWidget *box;
  221.   GtkWidget *box0;
  222.   GtkWidget *box1;
  223.   GSList    *group;
  224. #ifdef DO_LINEAR
  225.   GSList    *linear_group;
  226. #endif
  227.   GSList    *image_type_group;
  228.   gint       i;
  229.   gchar      s[100];
  230.  
  231.   const printer_t *the_printer = get_printer_by_index (0);
  232.   gchar *plug_in_name;
  233.  
  234.   /*
  235.    * Fetch a thumbnail of the image we're to print from the Gimp...
  236.    */
  237.  
  238.   thumbnail_w = THUMBNAIL_MAXW;
  239.   thumbnail_h = THUMBNAIL_MAXH;
  240.   thumbnail_data = gimp_image_get_thumbnail_data (image_ID, &thumbnail_w,
  241.                                                   &thumbnail_h, &thumbnail_bpp);
  242.  
  243.   /*
  244.    * thumbnail_w and thumbnail_h have now been adjusted to the actual
  245.    * thumbnail dimensions.  Now initialize a colour-adjusted version of
  246.    * the thumbnail...
  247.    */
  248.  
  249.   adjusted_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
  250.  
  251.   /*
  252.    * Create the main dialog
  253.    */
  254.  
  255.   plug_in_name = g_strdup_printf (_("%s -- Print v%s"),
  256.                                   image_filename, PLUG_IN_VERSION);
  257.  
  258.   print_dialog = dialog =
  259.     gimp_dialog_new (plug_in_name, "print",
  260.                      gimp_standard_help_func, "filters/print.html",
  261.                      GTK_WIN_POS_MOUSE,
  262.                      FALSE, TRUE, FALSE,
  263.  
  264.                      _("Print and\nSave Settings"), gimp_printandsave_callback,
  265.                      NULL, NULL, NULL, FALSE, FALSE,
  266.                      _("Save\nSettings"), gimp_save_callback,
  267.                      NULL, NULL, NULL, FALSE, FALSE,
  268.                      _("Print"), gimp_print_callback,
  269.                      NULL, NULL, NULL, TRUE, FALSE,
  270.                      _("Cancel"), gtk_widget_destroy,
  271.                      NULL, 1, NULL, FALSE, TRUE,
  272.  
  273.                      NULL);
  274.  
  275.   g_free (plug_in_name);
  276.  
  277.   gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
  278.                       GTK_SIGNAL_FUNC (gtk_main_quit),
  279.                       NULL);
  280.  
  281.   /*
  282.    * Top-level vbox for dialog...
  283.    */
  284.  
  285.   main_vbox = gtk_vbox_new (FALSE, 4);
  286.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
  287.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_vbox,
  288.                       FALSE, FALSE, 0);
  289.   gtk_widget_show (main_vbox);
  290.  
  291.   hbox = gtk_hbox_new (FALSE, 6);
  292.   gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
  293.   gtk_widget_show (hbox);
  294.  
  295.   frame = gtk_frame_new (_("Preview"));
  296.   gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
  297.   gtk_widget_show (frame);
  298.  
  299.   vbox = gtk_vbox_new (FALSE, 4);
  300.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  301.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  302.   gtk_widget_show (vbox);
  303.  
  304.   ppvbox = gtk_vbox_new (FALSE, 7);
  305.   gtk_box_pack_end (GTK_BOX (hbox), GTK_WIDGET (ppvbox), FALSE, FALSE, 0);
  306.   gtk_widget_show (ppvbox);
  307.  
  308.   /*
  309.    * Drawing area for page preview...
  310.    */
  311.  
  312.   preview = (GtkDrawingArea *) gtk_drawing_area_new ();
  313.   gtk_drawing_area_size (preview, PREVIEW_SIZE_HORIZ, PREVIEW_SIZE_VERT);
  314.   gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (preview), FALSE, FALSE, 0);
  315.   gtk_signal_connect (GTK_OBJECT (preview), "expose_event",
  316.                       GTK_SIGNAL_FUNC (gimp_preview_update),
  317.                       NULL);
  318.   gtk_signal_connect (GTK_OBJECT (preview), "button_press_event",
  319.                       GTK_SIGNAL_FUNC (gimp_preview_button_callback),
  320.                       NULL);
  321.   gtk_signal_connect (GTK_OBJECT (preview), "button_release_event",
  322.                       GTK_SIGNAL_FUNC (gimp_preview_button_callback),
  323.                       NULL);
  324.   gtk_signal_connect (GTK_OBJECT (preview), "motion_notify_event",
  325.                       GTK_SIGNAL_FUNC (gimp_preview_motion_callback),
  326.                       NULL);
  327.   gtk_widget_show (GTK_WIDGET (preview));
  328.  
  329.   gtk_widget_set_events (GTK_WIDGET (preview),
  330.                          GDK_EXPOSURE_MASK |
  331.                          GDK_BUTTON_MOTION_MASK |
  332.                          GDK_BUTTON_PRESS_MASK |
  333.                          GDK_BUTTON_RELEASE_MASK);
  334.  
  335.   frame = gtk_frame_new (_("Position"));
  336.   gtk_box_pack_end (GTK_BOX (ppvbox), frame, TRUE, TRUE, 0);
  337.   gtk_widget_show (frame);
  338.  
  339.   table = gtk_table_new (4, 6, FALSE);
  340.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  341.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  342.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  343.   gtk_container_add (GTK_CONTAINER (frame), table);
  344.   gtk_widget_show (table);
  345.  
  346.   recenter_button = button = gtk_button_new_with_label (_("Center Image"));
  347.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 16, 8);
  348.   gtk_signal_connect(GTK_OBJECT (button), "clicked",
  349.                      GTK_SIGNAL_FUNC (gimp_position_callback),
  350.              NULL);
  351.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  352.                              NULL, 0, 0,
  353.                              button, 2, TRUE);
  354.  
  355.   box = gtk_vbox_new (FALSE, 2);
  356.   gimp_table_attach_aligned (GTK_TABLE (table), 2, 0,
  357.                              _("Units:"), 1.0, 0.15,
  358.                              box, 1, TRUE);
  359.  
  360.   unit_inch = button = gtk_radio_button_new_with_label (NULL, _("Inch"));
  361.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  362.   if (vars.unit == 0)
  363.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  364.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  365.                       GTK_SIGNAL_FUNC (gimp_unit_callback),
  366.                       (gpointer) 0);
  367.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  368.   gtk_widget_show (button);
  369.   unit_cm = button = gtk_radio_button_new_with_label (group, _("cm"));
  370.   if (vars.unit == 1)
  371.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  372.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  373.                       GTK_SIGNAL_FUNC (gimp_unit_callback),
  374.                       (gpointer) 1);
  375.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  376.   gtk_widget_show (button);
  377.  
  378.   left_entry = entry = gtk_entry_new ();
  379.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  380.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  381.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  382.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  383.               NULL);
  384.   gtk_widget_set_usize (entry, 60, 0);
  385.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  386.                              _("Left:"), 1.0, 0.5,
  387.                              entry, 1, TRUE);
  388.  
  389.   top_entry = entry = gtk_entry_new ();
  390.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.top));
  391.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  392.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  393.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  394.               NULL);
  395.   gtk_widget_set_usize (entry, 60, 0);
  396.   gimp_table_attach_aligned (GTK_TABLE (table), 2, 1,
  397.                              _("Top:"), 1.0, 0.5,
  398.                              entry, 1, TRUE);
  399.  
  400.   right_entry = entry = gtk_entry_new ();
  401.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  402.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  403.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  404.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  405.               NULL);
  406.   gtk_widget_set_usize (entry, 60, 0);
  407.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  408.                              _("Right:"), 1.0, 0.5,
  409.                              entry, 1, TRUE);
  410.  
  411.  
  412.   right_border_entry = entry = gtk_entry_new ();
  413.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  414.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  415.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  416.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  417.               NULL);
  418.   gtk_widget_set_usize (entry, 60, 0);
  419.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
  420.                              _("Right Border:"), 1.0, 0.5,
  421.                              entry, 1, TRUE);
  422.  
  423.   bottom_entry = entry = gtk_entry_new ();
  424.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  425.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  426.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  427.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  428.               NULL);
  429.   gtk_widget_set_usize (entry, 60, 0);
  430.   gimp_table_attach_aligned (GTK_TABLE (table), 2, 2,
  431.                              _("Bottom:"), 1.0, 0.5,
  432.                              entry, 1, TRUE);
  433.  
  434.  
  435.   bottom_border_entry = entry = gtk_entry_new ();
  436.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  437.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  438.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  439.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  440.               NULL);
  441.   gtk_widget_set_usize (entry, 60, 0);
  442.   gimp_table_attach_aligned (GTK_TABLE (table), 2, 3,
  443.                              _("Bottom Border:"), 1.0, 0.5,
  444.                              entry, 1, TRUE);
  445.  
  446.   /*
  447.    * Orientation option menu...
  448.    */
  449.  
  450.   orientation_menu = option
  451.          = gimp_option_menu_new (FALSE,
  452.                                  _("Auto"), gimp_orientation_callback,
  453.                                  (gpointer) ORIENT_AUTO, NULL, NULL,
  454.                  vars.orientation == ORIENT_AUTO,
  455.                                  _("Portrait"), gimp_orientation_callback,
  456.                                  (gpointer) ORIENT_PORTRAIT, NULL, NULL,
  457.                  vars.orientation == ORIENT_PORTRAIT,
  458.                                  _("Landscape"), gimp_orientation_callback,
  459.                                  (gpointer) ORIENT_LANDSCAPE, NULL, NULL,
  460.                  vars.orientation == ORIENT_LANDSCAPE,
  461.                                  _("Upside down"), gimp_orientation_callback,
  462.                                  (gpointer) ORIENT_UPSIDEDOWN, NULL, NULL,
  463.                  vars.orientation == ORIENT_UPSIDEDOWN,
  464.                                  _("Seascape"), gimp_orientation_callback,
  465.                                  (gpointer) ORIENT_SEASCAPE, NULL, NULL,
  466.                  vars.orientation == ORIENT_SEASCAPE,
  467.                                  NULL);
  468.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 5,
  469.                              _("Orientation:"), 1.0, 0.5,
  470.                              option, 4, TRUE);
  471.  
  472.   /*
  473.    *  Printer settings frame...
  474.    */
  475.  
  476.   frame = gtk_frame_new (_("Printer Settings"));
  477.   gtk_box_pack_start (GTK_BOX (ppvbox), frame, TRUE, TRUE, 0);
  478.   gtk_widget_show (frame);
  479.  
  480.   vbox = gtk_vbox_new (FALSE, 4);
  481.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  482.   gtk_container_add (GTK_CONTAINER (frame), vbox);
  483.   gtk_widget_show (vbox);
  484.  
  485.   table = printer_table = gtk_table_new (8, 2, FALSE);
  486.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  487.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  488.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  489.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  490.   gtk_widget_show (table);
  491.  
  492.   /*
  493.    * Media size combo box...
  494.    */
  495.  
  496.   media_size_combo = combo = gtk_combo_new();
  497.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  498.                              _("Media Size:"), 1.0, 0.5,
  499.                              combo, 1, TRUE);
  500.  
  501.   /*
  502.    * Media type combo box...
  503.    */
  504.  
  505.   media_type_combo = combo = gtk_combo_new ();
  506.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
  507.                              _("Media Type:"), 1.0, 0.5,
  508.                              combo, 1, TRUE);
  509.  
  510.   /*
  511.    * Media source combo box...
  512.    */
  513.  
  514.   media_source_combo = combo = gtk_combo_new ();
  515.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
  516.                              _("Media Source:"), 1.0, 0.5,
  517.                              combo, 1, TRUE);
  518.  
  519.   /*
  520.    * Ink type combo box...
  521.    */
  522.  
  523.   ink_type_combo = combo = gtk_combo_new ();
  524.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
  525.                              _("Ink Type:"), 1.0, 0.5,
  526.                              combo, 1, TRUE);
  527.  
  528.   /*
  529.    * Resolution combo box...
  530.    */
  531.  
  532.   resolution_combo = combo = gtk_combo_new ();
  533.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 5,
  534.                              _("Resolution:"), 1.0, 0.5,
  535.                              combo, 1, TRUE);
  536.  
  537.   /*
  538.    * Scaling...
  539.    */
  540.   frame = gtk_frame_new (_("Scaling"));
  541.   gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  542.   gtk_widget_show (frame);
  543.  
  544.   table = gtk_table_new (2, 3, FALSE);
  545.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  546.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  547.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  548.   gtk_container_add (GTK_CONTAINER (frame), table);
  549.   gtk_widget_show (table);
  550.  
  551.   (*current_printer->media_size) (current_printer, &vars, &paper_width,
  552.                   &paper_height);
  553.  
  554.   (*current_printer->imageable_area) (current_printer, &vars, &left, &right,
  555.                       &bottom, &top);
  556.  
  557.   /* Rationalise things a bit by measuring everything from the top left */
  558.   top = paper_height - top;
  559.   bottom = paper_height - bottom;
  560.  
  561.   printable_width  = right - left;
  562.   printable_height = bottom - top;
  563.  
  564.   if (vars.scaling < 0.0)
  565.     {
  566.       const vars_t *lower = print_minimum_settings();
  567.       gdouble max_ppi_scaling;
  568.       gdouble min_ppi_scaling, min_ppi_scaling1, min_ppi_scaling2;
  569.       min_ppi_scaling1 = 72.0 * (gdouble) image_width /
  570.     (gdouble) printable_width;
  571.       min_ppi_scaling2 = 72.0 * (gdouble) image_height /
  572.     (gdouble) printable_height;
  573.       if (min_ppi_scaling1 > min_ppi_scaling2)
  574.     min_ppi_scaling = min_ppi_scaling1;
  575.       else
  576.     min_ppi_scaling = min_ppi_scaling2;
  577.       max_ppi_scaling = min_ppi_scaling * 100 / lower->scaling;
  578.       scaling_adjustment =
  579.         gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  580.                               _("Scaling:"), 200, 0,
  581.                               -vars.scaling, min_ppi_scaling, max_ppi_scaling,
  582.                   1.0, 10.0, 1, TRUE, 0, 0, NULL, NULL);
  583.     }
  584.   else
  585.     {
  586.       const vars_t *lower = print_minimum_settings();
  587.       scaling_adjustment =
  588.         gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  589.                               _("Scaling:"), 200, 75,
  590.                               vars.scaling, lower->scaling, 100.0,
  591.                   1.0, 10.0, 1, TRUE, 0, 0,
  592.                               NULL, NULL);
  593.     }
  594.   gtk_signal_connect (GTK_OBJECT (scaling_adjustment), "value_changed",
  595.                       GTK_SIGNAL_FUNC (gimp_scaling_update),
  596.                       NULL);
  597.  
  598.   box = gtk_hbox_new (FALSE, 7);
  599.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
  600.                              NULL, 0, 0,
  601.                              box, 1, FALSE);
  602.  
  603.   scaling_percent = button =
  604.     gtk_radio_button_new_with_label (NULL, _("Percent"));
  605.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  606.   if (vars.scaling > 0.0)
  607.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  608.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  609.                       GTK_SIGNAL_FUNC (gimp_scaling_callback),
  610.                       NULL);
  611.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  612.   gtk_widget_show (button);
  613.  
  614.   scaling_ppi = button = gtk_radio_button_new_with_label (group, _("PPI"));
  615.   if (vars.scaling < 0.0)
  616.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  617.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  618.                       GTK_SIGNAL_FUNC (gimp_scaling_callback),
  619.                       NULL);
  620.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  621.   gtk_widget_show (button);
  622.  
  623.   scaling_image = button = gtk_button_new_with_label (_("Set Image Scale"));
  624.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
  625.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  626.                       GTK_SIGNAL_FUNC (gimp_scaling_callback),
  627.                       NULL);
  628.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
  629.   gtk_widget_show (button);
  630.  
  631.   /*
  632.    * Use a dummy label as a spacer
  633.    */
  634.   label = gtk_label_new ("");
  635.   gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 0);
  636.   gtk_widget_show (label);
  637.  
  638.   label = gtk_label_new (_("Width:"));
  639.   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
  640.   gtk_widget_show (label);
  641.  
  642.   width_entry = entry = gtk_entry_new ();
  643.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  644.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  645.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  646.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  647.               NULL);
  648.   gtk_widget_set_usize (entry, 60, 0);
  649.   gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 0);
  650.   gtk_widget_show (entry);
  651.  
  652.   label = gtk_label_new(_("Height:"));
  653.   gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
  654.   gtk_widget_show (label);
  655.  
  656.   height_entry = entry = gtk_entry_new ();
  657.   g_snprintf (s, sizeof (s), "%.3f", fabs (vars.left));
  658.   gtk_entry_set_text (GTK_ENTRY (entry), s);
  659.   gtk_signal_connect (GTK_OBJECT (entry), "activate",
  660.                       GTK_SIGNAL_FUNC (gimp_position_callback),
  661.               NULL);
  662.   gtk_widget_set_usize (entry, 60, 0);
  663.   gtk_box_pack_end (GTK_BOX (box), entry, FALSE, FALSE, 0);
  664.   gtk_widget_show (entry);
  665.  
  666.   /*
  667.    * Image type
  668.    */
  669.   frame = gtk_frame_new (_("Image Settings"));
  670.   gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  671.   gtk_widget_show (frame);
  672.  
  673.   box = gtk_hbox_new (FALSE, 7);
  674.   gtk_container_set_border_width (GTK_CONTAINER (box), 2);
  675.   gtk_container_add (GTK_CONTAINER (frame), box);
  676.   gtk_widget_show (box);
  677.  
  678.   box0 = gtk_vbox_new(FALSE, 0);
  679.   gtk_container_set_border_width (GTK_CONTAINER (box0), 0);
  680.   gtk_container_add (GTK_CONTAINER (box), box0);
  681.   gtk_widget_show (box0);
  682.  
  683.   box1 = gtk_vbox_new(FALSE, 0);
  684.   gtk_container_set_border_width (GTK_CONTAINER (box1), 0);
  685.   gtk_container_add (GTK_CONTAINER (box), box1);
  686.   gtk_widget_show (box1);
  687.  
  688.   image_line_art = button =
  689.     gtk_radio_button_new_with_label (NULL, _("Line Art"));
  690.   image_type_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  691.   if (vars.image_type == IMAGE_LINE_ART)
  692.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  693.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  694.               GTK_SIGNAL_FUNC (gimp_image_type_callback),
  695.               (gpointer) IMAGE_LINE_ART);
  696.   gtk_box_pack_start (GTK_BOX (box0), button, FALSE, FALSE, 0);
  697.   gtk_widget_show (button);
  698.  
  699.   image_solid_tone= button =
  700.     gtk_radio_button_new_with_label (image_type_group, _("Solid Colors"));
  701.   image_type_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  702.   if (vars.image_type == IMAGE_SOLID_TONE)
  703.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  704.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  705.               GTK_SIGNAL_FUNC (gimp_image_type_callback),
  706.               (gpointer) IMAGE_SOLID_TONE);
  707.   gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
  708.   gtk_widget_show (button);
  709.  
  710.   image_continuous_tone = button =
  711.     gtk_radio_button_new_with_label (image_type_group, _("Photograph"));
  712.   image_type_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  713.   if (vars.image_type == IMAGE_CONTINUOUS)
  714.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  715.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  716.               GTK_SIGNAL_FUNC (gimp_image_type_callback),
  717.               (gpointer) IMAGE_CONTINUOUS);
  718.   gtk_box_pack_start (GTK_BOX (box0), button, FALSE, FALSE, 0);
  719.   gtk_widget_show (button);
  720.  
  721.   image_monochrome= button =
  722.     gtk_radio_button_new_with_label(image_type_group, _("Monochrome"));
  723.   image_type_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  724.   if (vars.image_type == IMAGE_MONOCHROME)
  725.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  726.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  727.               GTK_SIGNAL_FUNC (gimp_image_type_callback),
  728.               (gpointer) IMAGE_MONOCHROME);
  729.   gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
  730.   gtk_widget_show (button);
  731.  
  732.   /*
  733.    *  Color adjust button
  734.    */
  735.   gimp_create_color_adjust_window ();
  736.  
  737.   adjust_color_button = button = gtk_button_new_with_label (_("Adjust Color"));
  738.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
  739.   gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
  740.                  GTK_SIGNAL_FUNC (gtk_widget_show),
  741.                  GTK_OBJECT (gimp_color_adjust_dialog));
  742.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  743.   gtk_widget_show (button);
  744.  
  745.   /*
  746.    * Output type toggles...
  747.    */
  748.  
  749.   label = gtk_label_new (_("Output Type:"));
  750.   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
  751.   gtk_widget_show (label);
  752.   
  753.   vbox = gtk_vbox_new (FALSE, 1);
  754.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
  755.   gtk_box_pack_end (GTK_BOX (box), vbox, TRUE, TRUE, 0);
  756.   gtk_widget_show (vbox);
  757.  
  758.   output_color = button = gtk_radio_button_new_with_label (NULL, _("Color"));
  759.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  760.   if (vars.output_type == 1)
  761.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  762.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  763.                       GTK_SIGNAL_FUNC (gimp_output_type_callback),
  764.                       (gpointer) OUTPUT_COLOR);
  765.   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  766.   gtk_widget_show (button);
  767.  
  768.   output_gray = button = gtk_radio_button_new_with_label (group, _("B&W"));
  769.   if (vars.output_type == 0)
  770.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  771.   gtk_signal_connect (GTK_OBJECT (button), "toggled",
  772.                       GTK_SIGNAL_FUNC (gimp_output_type_callback),
  773.                       (gpointer) OUTPUT_GRAY);
  774.   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  775.   gtk_widget_show (button);
  776.  
  777.   /*
  778.    * Printer option menu...
  779.    */
  780.  
  781.   menu = gtk_menu_new ();
  782.   for (i = 0; i < plist_count; i ++)
  783.   {
  784.     if (plist[i].active)
  785.       item = gtk_menu_item_new_with_label (gettext (plist[i].name));
  786.     else
  787.       {
  788.         gchar buf[18];
  789.         buf[0] = '*';
  790.         memcpy (buf + 1, plist[i].name, 17);
  791.         item = gtk_menu_item_new_with_label (gettext (buf));
  792.       }
  793.     gtk_menu_append (GTK_MENU (menu), item);
  794.     gtk_signal_connect (GTK_OBJECT (item), "activate",
  795.                         GTK_SIGNAL_FUNC (gimp_plist_callback),
  796.                         (gpointer) i);
  797.     gtk_widget_show (item);
  798.   }
  799.  
  800.   box = gtk_hbox_new (FALSE, 6);
  801.   gimp_table_attach_aligned (GTK_TABLE (printer_table), 0, 0,
  802.                              _("Printer:"), 1.0, 0.5,
  803.                              box, 1, TRUE);
  804.  
  805.   option = gtk_option_menu_new ();
  806.   gtk_box_pack_start (GTK_BOX (box), option, FALSE, FALSE, 0);
  807.   gtk_option_menu_set_menu (GTK_OPTION_MENU (option), menu);
  808.   gtk_option_menu_set_history (GTK_OPTION_MENU (option), plist_current);
  809.   gtk_widget_show (option);
  810.  
  811.   button = gtk_button_new_with_label (_("Setup"));
  812.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
  813.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  814.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  815.                       GTK_SIGNAL_FUNC (gimp_setup_open_callback),
  816.                       NULL);
  817.   gtk_widget_show (button);
  818.  
  819.   /*
  820.    * Setup dialog window...
  821.    */
  822.  
  823.   setup_dialog = dialog =
  824.     gimp_dialog_new (_("Setup"), "print",
  825.                      gimp_standard_help_func, "filters/print.html",
  826.                      GTK_WIN_POS_MOUSE,
  827.                      FALSE, TRUE, FALSE,
  828.  
  829.                      _("OK"), gimp_setup_ok_callback,
  830.                      NULL, NULL, NULL, TRUE, FALSE,
  831.                      _("Cancel"), gtk_widget_hide,
  832.                      NULL, 1, NULL, FALSE, TRUE,
  833.  
  834.                      NULL);
  835.  
  836.   /*
  837.    * Top-level table for dialog...
  838.    */
  839.  
  840.   table = gtk_table_new (5, 2, FALSE);
  841.   gtk_container_set_border_width (GTK_CONTAINER (table), 6);
  842.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  843.   gtk_table_set_row_spacings (GTK_TABLE (table), 8);
  844.   gtk_table_set_row_spacing (GTK_TABLE (table), 0, 100);
  845.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table,
  846.                       FALSE, FALSE, 0);
  847.   gtk_widget_show (table);
  848.  
  849.   /*
  850.    * Printer driver option menu...
  851.    */
  852.  
  853.   label = gtk_label_new (_("Printer Model:"));
  854.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  855.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 2,
  856.                     GTK_FILL, GTK_FILL, 0, 0);
  857.   gtk_widget_show (label);
  858.  
  859.   printer_crawler = gtk_scrolled_window_new(NULL, NULL);
  860.   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (printer_crawler),
  861.                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  862.   printer_driver = list = gtk_clist_new(1);
  863.   gtk_clist_set_selection_mode(GTK_CLIST(list), GTK_SELECTION_SINGLE);
  864.   gtk_signal_connect(GTK_OBJECT(list), "select_row",
  865.              (GtkSignalFunc)gimp_print_driver_callback,
  866.              NULL);
  867.   gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW (printer_crawler),
  868.                     list);
  869.   gtk_widget_set_usize(printer_crawler, 200, 0);
  870.   gtk_widget_show (list);
  871.   for (i = 0; i < known_printers(); i ++)
  872.     {
  873.       char *tmp;
  874.       if (!strcmp(the_printer->long_name, ""))
  875.     continue;
  876.       tmp = gettext(the_printer->long_name);
  877.       gtk_clist_insert(GTK_CLIST(list), i, &tmp);
  878.       gtk_clist_set_row_data(GTK_CLIST(list), i, (gpointer)i);
  879.       the_printer++;
  880.     }
  881.   gtk_table_attach (GTK_TABLE (table), printer_crawler, 1, 3, 0, 2,
  882.                     GTK_FILL, GTK_FILL, 0, 0);
  883.   gtk_widget_show (printer_crawler);
  884.  
  885.   /*
  886.    * PPD file...
  887.    */
  888.  
  889.   label = gtk_label_new (_("PPD File:"));
  890.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  891.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
  892.                     GTK_FILL, GTK_FILL, 0, 0);
  893.   gtk_widget_show (label);
  894.  
  895.   box = gtk_hbox_new (FALSE, 8);
  896.   gtk_table_attach (GTK_TABLE (table), box, 1, 2, 2, 3,
  897.                     GTK_FILL, GTK_FILL, 0, 0);
  898.   gtk_widget_show (box);
  899.  
  900.   ppd_file = entry = gtk_entry_new ();
  901.   gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
  902.   gtk_widget_show (entry);
  903.  
  904.   ppd_button = button = gtk_button_new_with_label (_("Browse"));
  905.   gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
  906.   gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
  907.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  908.                       GTK_SIGNAL_FUNC (gimp_ppd_browse_callback),
  909.                       NULL);
  910.   gtk_widget_show (button);
  911.  
  912.   /*
  913.    * Print command...
  914.    */
  915.  
  916.   label = gtk_label_new (_("Command:"));
  917.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  918.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
  919.                     GTK_FILL, GTK_FILL, 0, 0);
  920.   gtk_widget_show (label);
  921.  
  922.   output_cmd = entry = gtk_entry_new ();
  923.   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 3, 4,
  924.                     GTK_FILL, GTK_FILL, 0, 0);
  925.   gtk_widget_show (entry);
  926.  
  927.   /*
  928.    * Output file selection dialog...
  929.    */
  930.  
  931.   file_browser = gtk_file_selection_new (_("Print To File?"));
  932.   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_browser)->ok_button),
  933.                       "clicked",
  934.                       GTK_SIGNAL_FUNC (gimp_file_ok_callback),
  935.                       NULL);
  936.   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_browser)->cancel_button),
  937.                       "clicked",
  938.               GTK_SIGNAL_FUNC (gimp_file_cancel_callback),
  939.                       NULL);
  940.  
  941.   /*
  942.    * PPD file selection dialog...
  943.    */
  944.  
  945.   ppd_browser = gtk_file_selection_new (_("PPD File?"));
  946.   gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (ppd_browser));
  947.   gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (ppd_browser)->ok_button),
  948.                       "clicked",
  949.                       GTK_SIGNAL_FUNC (gimp_ppd_ok_callback),
  950.                       NULL);
  951.   gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (ppd_browser)->cancel_button),
  952.                              "clicked",
  953.                              GTK_SIGNAL_FUNC (gtk_widget_hide),
  954.                              GTK_OBJECT (ppd_browser));
  955.  
  956.   /*
  957.    * Show the main dialog and wait for the user to do something...
  958.    */
  959.  
  960.   gimp_plist_callback (NULL, (gpointer) plist_current);
  961.   gimp_update_adjusted_thumbnail ();
  962.  
  963.   gtk_widget_show (print_dialog);
  964. }
  965.  
  966. /*
  967.  *  gimp_scaling_update() - Update the scaling scale using the slider.
  968.  */
  969. static void
  970. gimp_scaling_update (GtkAdjustment *adjustment)
  971. {
  972.   if (vars.scaling != adjustment->value)
  973.     {
  974.       if (GTK_TOGGLE_BUTTON (scaling_ppi)->active)
  975.         vars.scaling = -adjustment->value;
  976.       else
  977.         vars.scaling = adjustment->value;
  978.       plist[plist_current].v.scaling = vars.scaling;
  979.     }
  980.  
  981.   suppress_scaling_adjustment = TRUE;
  982.   gimp_preview_update ();
  983.   suppress_scaling_adjustment = FALSE;
  984. }
  985.  
  986. /*
  987.  *  gimp_scaling_callback() - Update the scaling scale using radio buttons.
  988.  */
  989. static void
  990. gimp_scaling_callback (GtkWidget *widget)
  991. {
  992.   const vars_t *lower = print_minimum_settings ();
  993.   gdouble max_ppi_scaling;
  994.   gdouble min_ppi_scaling, min_ppi_scaling1, min_ppi_scaling2;
  995.   gdouble current_scale;
  996.  
  997.   if (suppress_scaling_callback)
  998.     return;
  999.  
  1000.   min_ppi_scaling1 = 72.0 * (gdouble) image_width /
  1001.     (gdouble) printable_width;
  1002.   min_ppi_scaling2 = 72.0 * (gdouble) image_height /
  1003.     (gdouble) printable_height;
  1004.   if (min_ppi_scaling1 > min_ppi_scaling2)
  1005.     min_ppi_scaling = min_ppi_scaling1;
  1006.   else
  1007.     min_ppi_scaling = min_ppi_scaling2;
  1008.   max_ppi_scaling = min_ppi_scaling * 100 / lower->scaling;
  1009.   if (widget == scaling_ppi)
  1010.     {
  1011.       if (!(GTK_TOGGLE_BUTTON (scaling_ppi)->active))
  1012.     return;
  1013.       GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
  1014.       GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
  1015.  
  1016.       /*
  1017.        * Compute the correct PPI to create an image of the same size
  1018.        * as the one measured in percent
  1019.        */
  1020.       current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
  1021.       GTK_ADJUSTMENT (scaling_adjustment)->value =
  1022.     min_ppi_scaling / (current_scale / 100);
  1023.       vars.scaling = 0.0;
  1024.       plist[plist_current].v.scaling = vars.scaling;
  1025.     }
  1026.   else if (widget == scaling_percent)
  1027.     {
  1028.       gdouble new_percent;
  1029.       if (!(GTK_TOGGLE_BUTTON (scaling_percent)->active))
  1030.     return;
  1031.       current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
  1032.       GTK_ADJUSTMENT (scaling_adjustment)->lower = lower->scaling;
  1033.       GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
  1034.  
  1035.       new_percent = 100 * min_ppi_scaling / current_scale;
  1036.       if (new_percent > 100)
  1037.     new_percent = 100;
  1038.       if (new_percent < lower->scaling)
  1039.     new_percent = lower->scaling;
  1040.       GTK_ADJUSTMENT (scaling_adjustment)->value = new_percent;
  1041.       vars.scaling = 0.0;
  1042.       plist[plist_current].v.scaling = vars.scaling;
  1043.     }
  1044.   else if (widget == scaling_image)
  1045.     {
  1046.       gdouble xres, yres;
  1047.  
  1048.       gimp_image_get_resolution (image_ID, &xres, &yres);
  1049.  
  1050.       GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
  1051.       GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
  1052.       if (yres < min_ppi_scaling)
  1053.     yres = min_ppi_scaling;
  1054.       if (yres > max_ppi_scaling)
  1055.     yres = max_ppi_scaling;
  1056.  
  1057.       GTK_ADJUSTMENT (scaling_adjustment)->value = yres;
  1058.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
  1059.       vars.scaling = 0.0;
  1060.       plist[plist_current].v.scaling = vars.scaling;
  1061.     }
  1062.  
  1063.   gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1064.   gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1065. }
  1066.  
  1067. /****************************************************************************
  1068.  *
  1069.  * gimp_plist_build_combo
  1070.  *
  1071.  ****************************************************************************/
  1072. void 
  1073. gimp_plist_build_combo (GtkWidget      *combo,       /* I - Combo widget */
  1074.             gint            num_items,   /* I - Number of items */
  1075.             gchar         **items,       /* I - Menu items */
  1076.             gchar          *cur_item,    /* I - Current item */
  1077.             GtkSignalFunc   callback,    /* I - Callback */
  1078.             gint           *callback_id) /* IO - Callback ID (init to -1) */
  1079. {
  1080.   gint      i; /* Looping var */
  1081.   GList    *list = 0;
  1082.   GtkEntry *entry = GTK_ENTRY (GTK_COMBO (combo)->entry);
  1083.  
  1084.   if (*callback_id != -1)
  1085.     gtk_signal_disconnect (GTK_OBJECT (entry), *callback_id);
  1086. #if 0
  1087.   gtk_signal_handlers_destroy (GTK_OBJECT (entry));
  1088. #endif
  1089.   gtk_entry_set_editable (entry, FALSE);
  1090.  
  1091.   if (num_items == 0)
  1092.     {
  1093.       list = g_list_append (list, _("Standard"));
  1094.       gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
  1095.       g_list_free (list);
  1096.       *callback_id = -1;
  1097.       gtk_widget_set_sensitive (combo, FALSE);
  1098.       gtk_widget_show (combo);
  1099.       return;
  1100.     }
  1101.  
  1102.   for (i = 0; i < num_items; i ++)
  1103.     list = g_list_append (list, gettext (items[i]));
  1104.  
  1105.   gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
  1106.  
  1107.   *callback_id = gtk_signal_connect (GTK_OBJECT (entry), "changed",
  1108.                      callback,
  1109.                      NULL);
  1110.  
  1111.   gtk_entry_set_text (entry, cur_item);
  1112.  
  1113.   for (i = 0; i < num_items; i ++)
  1114.     if (strcmp(items[i], cur_item) == 0)
  1115.       break;
  1116.  
  1117.   if (i == num_items)
  1118.     gtk_entry_set_text (entry, gettext (items[0]));
  1119.  
  1120.   gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
  1121.   gtk_widget_set_sensitive (combo, TRUE);
  1122.   gtk_widget_show (combo);
  1123. }
  1124.  
  1125. /*
  1126.  *  gimp_do_misc_updates() - Build an option menu for the given parameters...
  1127.  */
  1128. static void
  1129. gimp_do_misc_updates (void)
  1130. {
  1131.   const vars_t *lower = print_minimum_settings ();
  1132.  
  1133.   vars.scaling     = plist[plist_current].v.scaling;
  1134.   vars.orientation = plist[plist_current].v.orientation;
  1135.   vars.left        = plist[plist_current].v.left;
  1136.   vars.top         = plist[plist_current].v.top;
  1137.   vars.unit        = plist[plist_current].v.unit;
  1138.  
  1139.   gimp_preview_update ();
  1140.  
  1141.   if (plist[plist_current].v.scaling < 0)
  1142.     {
  1143.       gdouble tmp = -plist[plist_current].v.scaling;
  1144.       gdouble max_ppi_scaling;
  1145.       gdouble min_ppi_scaling, min_ppi_scaling1, min_ppi_scaling2;
  1146.  
  1147.       min_ppi_scaling1 = 72.0 * (gdouble) image_width /
  1148.     (gdouble) printable_width;
  1149.       min_ppi_scaling2 = 72.0 * (gdouble) image_height /
  1150.     (gdouble) printable_height;
  1151.  
  1152.       if (min_ppi_scaling1 > min_ppi_scaling2)
  1153.     min_ppi_scaling = min_ppi_scaling1;
  1154.       else
  1155.     min_ppi_scaling = min_ppi_scaling2;
  1156.  
  1157.       max_ppi_scaling = min_ppi_scaling * 100 / lower->scaling;
  1158.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
  1159.       GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
  1160.       GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
  1161.       GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
  1162.       gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1163.       gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1164.       plist[plist_current].v.scaling = vars.scaling;
  1165.     }
  1166.   else
  1167.     {
  1168.       gdouble tmp = plist[plist_current].v.scaling;
  1169.  
  1170.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent), TRUE);
  1171.       GTK_ADJUSTMENT (scaling_adjustment)->lower = lower->scaling;
  1172.       GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
  1173.       GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
  1174.       gtk_signal_emit_by_name (scaling_adjustment, "changed");
  1175.       gtk_signal_emit_by_name (scaling_adjustment, "value_changed");
  1176.     }
  1177.  
  1178.   if (plist[plist_current].v.output_type == OUTPUT_GRAY)
  1179.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_gray), TRUE);
  1180.   else
  1181.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output_color), TRUE);
  1182.  
  1183.   gimp_do_color_updates ();
  1184.  
  1185.   gtk_option_menu_set_history (GTK_OPTION_MENU (orientation_menu),
  1186.                    vars.orientation + 1);
  1187.  
  1188.   if (plist[plist_current].v.unit == 0)
  1189.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (unit_inch), TRUE);
  1190.   else
  1191.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (unit_cm), TRUE);
  1192.  
  1193. #ifdef DO_LINEAR
  1194.   if (plist[plist_current].v.linear == 0)
  1195.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear_off), TRUE);
  1196.   else
  1197.     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear_on), TRUE);
  1198. #endif
  1199.  
  1200.   switch (plist[plist_current].v.image_type)
  1201.     {
  1202.     case IMAGE_LINE_ART:
  1203.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_line_art), TRUE);
  1204.       break;
  1205.     case IMAGE_SOLID_TONE:
  1206.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_solid_tone), TRUE);
  1207.       break;
  1208.     case IMAGE_CONTINUOUS:
  1209.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_continuous_tone), TRUE);
  1210.       break;
  1211.     case IMAGE_MONOCHROME:
  1212.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_monochrome), TRUE);
  1213.       break;
  1214.     default:
  1215.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_continuous_tone), TRUE);
  1216.       plist[plist_current].v.image_type = IMAGE_CONTINUOUS;
  1217.       break;
  1218.     }
  1219.  
  1220.   gimp_preview_update ();
  1221. }
  1222.  
  1223. /*
  1224.  * gimp_position_callback() - callback for position entry widgets
  1225.  */
  1226. static void
  1227. gimp_position_callback (GtkWidget *widget)
  1228. {
  1229.   if (widget == recenter_button)
  1230.     {
  1231.       vars.left = -1;
  1232.       vars.top = -1;
  1233.     }
  1234.   else
  1235.     {
  1236.       gdouble new_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
  1237.       gdouble unit_scaler = 1.0;
  1238.       gboolean was_percent = 0;
  1239.  
  1240.       if (vars.unit)
  1241.     unit_scaler /= 2.54;
  1242.       new_value *= unit_scaler;
  1243.  
  1244.       if (widget == top_entry)
  1245.     vars.top = ((new_value + (1.0 / 144.0)) * 72) - top;
  1246.       else if (widget == bottom_entry)
  1247.     vars.top = ((new_value + (1.0 / 144.0)) * 72) - (top + print_height);
  1248.       else if (widget == bottom_border_entry)
  1249.     vars.top = paper_height - print_height - top - (new_value * 72);
  1250.       else if (widget == left_entry)
  1251.     vars.left = ((new_value + (1.0 / 144.0)) * 72) - left;
  1252.       else if (widget == right_entry)
  1253.     vars.left = ((new_value + (1.0 / 144.0)) * 72) - (left + print_width);
  1254.       else if (widget == right_border_entry)
  1255.     vars.left = paper_width - print_width - left - (new_value * 72);
  1256.       else if (widget == width_entry)
  1257.     {
  1258.       if (vars.scaling >= 0)
  1259.         {
  1260.           gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi),
  1261.                         TRUE);
  1262.           gimp_scaling_callback (scaling_ppi);
  1263.           was_percent = 1;
  1264.         }
  1265.       GTK_ADJUSTMENT (scaling_adjustment)->value =
  1266.         (image_width - .5) / new_value;
  1267.       gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1268.       if (was_percent)
  1269.         {
  1270.           gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent),
  1271.                         TRUE);
  1272.           gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1273.         }
  1274.     }
  1275.       else if (widget == height_entry)
  1276.     {
  1277.       if (vars.scaling >= 0)
  1278.         {
  1279.           gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi),
  1280.                         TRUE);
  1281.           gimp_scaling_callback (scaling_ppi);
  1282.           was_percent = 1;
  1283.         }
  1284.       GTK_ADJUSTMENT (scaling_adjustment)->value =
  1285.         (image_height - .5) / new_value;
  1286.       gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1287.       if (was_percent)
  1288.         {
  1289.           gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent),
  1290.                         TRUE);
  1291.           gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1292.         }
  1293.     }
  1294.       if (vars.left < 0)
  1295.     vars.left = 0;
  1296.       if (vars.top < 0)
  1297.     vars.top = 0;
  1298.     }
  1299.  
  1300.   plist[plist_current].v.left = vars.left;
  1301.   plist[plist_current].v.top = vars.top;
  1302.   gimp_preview_update ();
  1303. }
  1304.  
  1305. /*
  1306.  *  gimp_plist_callback() - Update the current system printer...
  1307.  */
  1308. static void
  1309. gimp_plist_callback (GtkWidget *widget,
  1310.              gpointer   data)
  1311. {
  1312.   gint     i;
  1313.   plist_t *p;
  1314.   int        num_media_sizes;
  1315.   char        **media_sizes;
  1316.   int        num_media_types;    /* Number of media types */
  1317.   char        **media_types;        /* Media type strings */
  1318.   int        num_media_sources;    /* Number of media sources */
  1319.   char        **media_sources;        /* Media source strings */
  1320.   int        num_ink_types;        /* Number of ink types */
  1321.   char        **ink_types;        /* Ink type strings */
  1322.   int        num_resolutions;    /* Number of resolutions */
  1323.   char        **resolutions;        /* Resolution strings */
  1324.  
  1325.   plist_current = (gint) data;
  1326.   p             = plist + plist_current;
  1327.  
  1328.   if (p->v.driver[0] != '\0')
  1329.     {
  1330.       strcpy(vars.driver, p->v.driver);
  1331.  
  1332.       current_printer = get_printer_by_driver (vars.driver);
  1333.     }
  1334.  
  1335.   strcpy (vars.ppd_file, p->v.ppd_file);
  1336.   strcpy (vars.media_size, p->v.media_size);
  1337.   strcpy (vars.media_type, p->v.media_type);
  1338.   strcpy (vars.media_source, p->v.media_source);
  1339.   strcpy (vars.ink_type, p->v.ink_type);
  1340.   strcpy (vars.dither_algorithm, p->v.dither_algorithm);
  1341.   strcpy (vars.resolution, p->v.resolution);
  1342.   strcpy (vars.output_to, p->v.output_to);
  1343.  
  1344.   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (dither_algo_combo)->entry),
  1345.                       vars.dither_algorithm);
  1346.  
  1347.   gimp_setup_update ();
  1348.  
  1349.   gimp_do_misc_updates ();
  1350.  
  1351.   /*
  1352.    * Now get option parameters...
  1353.    */
  1354.  
  1355.   media_sizes = (*(current_printer->parameters)) (current_printer,
  1356.                           p->v.ppd_file,
  1357.                           "PageSize", &num_media_sizes);
  1358.   if (vars.media_size[0] == '\0')
  1359.     strcpy (vars.media_size, media_sizes[0]);
  1360.   gimp_plist_build_combo (media_size_combo,
  1361.               num_media_sizes,
  1362.               media_sizes,
  1363.               p->v.media_size,
  1364.               gimp_media_size_callback,
  1365.               &media_size_callback_id);
  1366.  
  1367.   for (i = 0; i < num_media_sizes; i ++)
  1368.     free (media_sizes[i]);
  1369.   free (media_sizes);
  1370.  
  1371.   media_types = (*(current_printer->parameters)) (current_printer,
  1372.                           p->v.ppd_file,
  1373.                           "MediaType",
  1374.                           &num_media_types);
  1375.   if (vars.media_type[0] == '\0' && media_types != NULL)
  1376.     strcpy (vars.media_type, media_types[0]);
  1377.   else if (media_types == NULL)
  1378.     vars.media_type[0] = '\0';
  1379.   gimp_plist_build_combo (media_type_combo,
  1380.               num_media_types,
  1381.               media_types,
  1382.               p->v.media_type,
  1383.               gimp_media_type_callback,
  1384.               &media_type_callback_id);
  1385.  
  1386.   if (num_media_types > 0)
  1387.     {
  1388.       for (i = 0; i < num_media_types; i ++)
  1389.     free (media_types[i]);
  1390.       free (media_types);
  1391.     }
  1392.  
  1393.   media_sources = (*(current_printer->parameters)) (current_printer,
  1394.                             p->v.ppd_file,
  1395.                             "InputSlot",
  1396.                             &num_media_sources);
  1397.   if (vars.media_source[0] == '\0' && media_sources != NULL)
  1398.     strcpy (vars.media_source, media_sources[0]);
  1399.   else if (media_sources == NULL)
  1400.     vars.media_source[0] = '\0';
  1401.   gimp_plist_build_combo (media_source_combo,
  1402.               num_media_sources,
  1403.               media_sources,
  1404.               p->v.media_source,
  1405.               gimp_media_source_callback,
  1406.               &media_source_callback_id);
  1407.  
  1408.   if (num_media_sources > 0)
  1409.     {
  1410.       for (i = 0; i < num_media_sources; i ++)
  1411.     free (media_sources[i]);
  1412.       free (media_sources);
  1413.     }
  1414.  
  1415.   ink_types = (*(current_printer->parameters)) (current_printer,
  1416.                         p->v.ppd_file,
  1417.                         "InkType", &num_ink_types);
  1418.   if (vars.ink_type[0] == '\0' && ink_types != NULL)
  1419.     strcpy (vars.ink_type, ink_types[0]);
  1420.   else if (ink_types == NULL)
  1421.     vars.ink_type[0] = '\0';
  1422.   gimp_plist_build_combo (ink_type_combo,
  1423.               num_ink_types,
  1424.               ink_types,
  1425.               p->v.ink_type,
  1426.               gimp_ink_type_callback,
  1427.               &ink_type_callback_id);
  1428.  
  1429.   if (num_ink_types > 0)
  1430.     {
  1431.       for (i = 0; i < num_ink_types; i ++)
  1432.     free (ink_types[i]);
  1433.       free (ink_types);
  1434.     }
  1435.  
  1436.   resolutions = (*(current_printer->parameters)) (current_printer,
  1437.                           p->v.ppd_file,
  1438.                           "Resolution",
  1439.                           &num_resolutions);
  1440.   if (vars.resolution[0] == '\0' && resolutions != NULL)
  1441.     strcpy (vars.resolution, resolutions[0]);
  1442.   else if (resolutions == NULL)
  1443.     vars.resolution[0] = '\0';
  1444.   gimp_plist_build_combo (resolution_combo,
  1445.               num_resolutions,
  1446.               resolutions,
  1447.               p->v.resolution,
  1448.               gimp_resolution_callback,
  1449.               &resolution_callback_id);
  1450.  
  1451.   if (num_resolutions > 0)
  1452.     {
  1453.       for (i = 0; i < num_resolutions; i ++)
  1454.     free (resolutions[i]);
  1455.       free (resolutions);
  1456.     }
  1457.   if (dither_algo_combo)
  1458.     gimp_build_dither_combo();
  1459. }
  1460.  
  1461. #define Combo_get_text(combo) \
  1462.     (gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)))
  1463.  
  1464. /*
  1465.  *  gimp_media_size_callback() - Update the current media size...
  1466.  */
  1467. static void
  1468. gimp_media_size_callback (GtkWidget *widget,
  1469.               gpointer   data)
  1470. {
  1471.   const gchar *new_media_size = Combo_get_text (media_size_combo);
  1472.   if (strcmp (vars.media_size, new_media_size) != 0)
  1473.     {
  1474.       strcpy (vars.media_size, new_media_size);
  1475.       strcpy (plist[plist_current].v.media_size, new_media_size);
  1476.       vars.left = -1;
  1477.       vars.top  = -1;
  1478.       plist[plist_current].v.left = vars.left;
  1479.       plist[plist_current].v.top = vars.top;
  1480.       gimp_preview_update ();
  1481.     }
  1482. }
  1483.  
  1484. /*
  1485.  *  gimp_media_type_callback() - Update the current media type...
  1486.  */
  1487. static void
  1488. gimp_media_type_callback (GtkWidget *widget,
  1489.               gpointer   data)
  1490. {
  1491.   const gchar *new_media_type = Combo_get_text (media_type_combo);
  1492.   strcpy (vars.media_type, new_media_type);
  1493.   strcpy (plist[plist_current].v.media_type, new_media_type);
  1494. }
  1495.  
  1496. /*
  1497.  *  gimp_media_source_callback() - Update the current media source...
  1498.  */
  1499. static void
  1500. gimp_media_source_callback (GtkWidget *widget,
  1501.                 gpointer   data)
  1502. {
  1503.   const gchar *new_media_source = Combo_get_text (media_source_combo);
  1504.   strcpy (vars.media_source, new_media_source);
  1505.   strcpy (plist[plist_current].v.media_source, new_media_source);
  1506. }
  1507.  
  1508. /*
  1509.  *  gimp_ink_type_callback() - Update the current media source...
  1510.  */
  1511. static void
  1512. gimp_ink_type_callback (GtkWidget *widget,
  1513.             gpointer   data)
  1514. {
  1515.   const gchar *new_ink_type = Combo_get_text (ink_type_combo);
  1516.   strcpy (vars.ink_type, new_ink_type);
  1517.   strcpy (plist[plist_current].v.ink_type, new_ink_type);
  1518. }
  1519.  
  1520. /*
  1521.  *  gimp_resolution_callback() - Update the current resolution...
  1522.  */
  1523. static void
  1524. gimp_resolution_callback (GtkWidget *widget,
  1525.               gpointer   data)
  1526. {
  1527.   const gchar *new_resolution = Combo_get_text (resolution_combo);
  1528.   strcpy (vars.resolution, new_resolution);
  1529.   strcpy (plist[plist_current].v.resolution, new_resolution);
  1530. }
  1531.  
  1532. /*
  1533.  *  gimp_orientation_callback() - Update the current media size...
  1534.  */
  1535. static void
  1536. gimp_orientation_callback (GtkWidget *widget,
  1537.                gpointer   data)
  1538. {
  1539.   if (vars.orientation != (gint) data)
  1540.     {
  1541.       vars.orientation = (gint) data;
  1542.       vars.left        = -1;
  1543.       vars.top         = -1;
  1544.       plist[plist_current].v.orientation = vars.orientation;
  1545.       plist[plist_current].v.left = vars.left;
  1546.       plist[plist_current].v.top = vars.top;
  1547.     }
  1548.   gimp_preview_update ();
  1549. }
  1550.  
  1551. /*
  1552.  *  gimp_output_type_callback() - Update the current output type...
  1553.  */
  1554. static void
  1555. gimp_output_type_callback (GtkWidget *widget,
  1556.                gpointer   data)
  1557. {
  1558.   if (GTK_TOGGLE_BUTTON (widget)->active)
  1559.     {
  1560.       vars.output_type = (gint) data;
  1561.       plist[plist_current].v.output_type = (gint) data;
  1562.       gimp_update_adjusted_thumbnail();
  1563.     }
  1564. }
  1565.  
  1566. /*
  1567.  *  gimp_unit_callback() - Update the current unit...
  1568.  */
  1569. static void
  1570. gimp_unit_callback (GtkWidget *widget,
  1571.                gpointer   data)
  1572. {
  1573.   if (GTK_TOGGLE_BUTTON (widget)->active)
  1574.     {
  1575.       vars.unit = (gint) data;
  1576.       plist[plist_current].v.unit = (gint) data;
  1577.       gimp_preview_update();
  1578.     }
  1579. }
  1580.  
  1581. /*
  1582.  *  gimp_linear_callback() - Update the current linear gradient mode...
  1583.  */
  1584. #ifdef DO_LINEAR
  1585. static void
  1586. gimp_linear_callback (GtkWidget *widget,
  1587.               gpointer   data)
  1588. {
  1589.   if (GTK_TOGGLE_BUTTON (widget)->active)
  1590.     {
  1591.       vars.linear = (gint) data;
  1592.       plist[plist_current].v.linear = (gint) data;
  1593.     }
  1594. }
  1595. #endif
  1596.  
  1597. /*
  1598.  *  gimp_image_type_callback() - Update the current image type mode...
  1599.  */
  1600. static void
  1601. gimp_image_type_callback (GtkWidget *widget,
  1602.               gpointer   data)
  1603. {
  1604.   if (GTK_TOGGLE_BUTTON (widget)->active)
  1605.     {
  1606.       vars.image_type = (gint) data;
  1607.       gimp_update_adjusted_thumbnail();
  1608.       plist[plist_current].v.image_type = (gint) data;
  1609.     }
  1610. }
  1611.  
  1612. /*
  1613.  * 'print_callback()' - Start the print...
  1614.  */
  1615. static void
  1616. gimp_print_callback (void)
  1617. {
  1618.   if (plist_current > 0)
  1619.     {
  1620.       runme = TRUE;
  1621.       gtk_widget_destroy (gimp_color_adjust_dialog);
  1622.       gtk_widget_destroy (setup_dialog);
  1623.       gtk_widget_destroy (print_dialog);
  1624.     }
  1625.   else
  1626.     {
  1627.       gtk_widget_set_sensitive (gimp_color_adjust_dialog, FALSE);
  1628.       gtk_widget_set_sensitive (setup_dialog, FALSE);
  1629.       gtk_widget_set_sensitive (print_dialog, FALSE);
  1630.       gtk_widget_show (file_browser);
  1631.     }
  1632. }
  1633.  
  1634. /*
  1635.  *  gimp_printandsave_callback() -
  1636.  */
  1637. static void
  1638. gimp_printandsave_callback (void)
  1639. {
  1640.   saveme = TRUE;
  1641.  
  1642.   if (plist_current > 0)
  1643.     {
  1644.       runme = TRUE;
  1645.       gtk_widget_destroy (gimp_color_adjust_dialog);
  1646.       gtk_widget_destroy (setup_dialog);
  1647.       gtk_widget_destroy (print_dialog);
  1648.     }
  1649.   else
  1650.     {
  1651.       gtk_widget_set_sensitive (gimp_color_adjust_dialog, FALSE);
  1652.       gtk_widget_set_sensitive (setup_dialog, FALSE);
  1653.       gtk_widget_set_sensitive (print_dialog, FALSE);
  1654.       gtk_widget_show (file_browser);
  1655.     }
  1656. }
  1657.  
  1658. /*
  1659.  *  gimp_save_callback() - save settings, don't destroy dialog
  1660.  */
  1661. static void
  1662. gimp_save_callback (void)
  1663. {
  1664.   printrc_save ();
  1665. }
  1666.  
  1667. /*
  1668.  *  gimp_setup_update() - update widgets in the setup dialog
  1669.  */
  1670. static void
  1671. gimp_setup_update (void)
  1672. {
  1673.   GtkAdjustment *adjustment;
  1674.   gint idx;
  1675.  
  1676.   current_printer = get_printer_by_driver (plist[plist_current].v.driver);
  1677.   idx = get_printer_index_by_driver (plist[plist_current].v.driver);
  1678.  
  1679.   gtk_clist_select_row(GTK_CLIST(printer_driver), idx, 0);
  1680.  
  1681.   gtk_entry_set_text (GTK_ENTRY (ppd_file), plist[plist_current].v.ppd_file);
  1682.  
  1683.   if (strncmp (plist[plist_current].v.driver, "ps", 2) == 0)
  1684.     {
  1685.       gtk_widget_show (ppd_file);
  1686.       gtk_widget_show (ppd_button);
  1687.     }
  1688.   else
  1689.     {
  1690.       gtk_widget_hide (ppd_file);
  1691.       gtk_widget_hide (ppd_button);
  1692.     }
  1693.  
  1694.   gtk_entry_set_text (GTK_ENTRY (output_cmd), plist[plist_current].v.output_to);
  1695.  
  1696.   if (plist_current == 0)
  1697.     gtk_widget_hide (output_cmd);
  1698.   else
  1699.     gtk_widget_show (output_cmd);
  1700.  
  1701.   adjustment =
  1702.     gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (printer_crawler));
  1703.   gtk_adjustment_set_value (adjustment, idx * (adjustment->step_increment + 3));
  1704. }
  1705.  
  1706. /*
  1707.  *  gimp_setup_open_callback() -
  1708.  */
  1709. static void
  1710. gimp_setup_open_callback (void)
  1711. {
  1712.   static int first_time = 1;
  1713.  
  1714.   gimp_setup_update ();
  1715.  
  1716.   gtk_widget_show (setup_dialog);
  1717.  
  1718.   if (first_time)
  1719.     {
  1720.       /* Make sure the driver scroller gets positioned correctly... */
  1721.       gimp_setup_update ();
  1722.       first_time = 0;
  1723.     }
  1724. }
  1725.  
  1726. /*
  1727.  *  gimp_setup_ok_callback() -
  1728.  */
  1729. static void
  1730. gimp_setup_ok_callback (void)
  1731. {
  1732.   strcpy (vars.driver, current_printer->driver);
  1733.   strcpy (plist[plist_current].v.driver, current_printer->driver);
  1734.  
  1735.   strcpy (vars.output_to, gtk_entry_get_text (GTK_ENTRY (output_cmd)));
  1736.   strcpy (plist[plist_current].v.output_to, vars.output_to);
  1737.  
  1738.   strcpy (vars.ppd_file, gtk_entry_get_text (GTK_ENTRY (ppd_file)));
  1739.   strcpy (plist[plist_current].v.ppd_file, vars.ppd_file);
  1740.  
  1741.   gimp_plist_callback (NULL, (gpointer) plist_current);
  1742.  
  1743.   gtk_widget_hide (setup_dialog);
  1744. }
  1745.  
  1746. /*
  1747.  *  gimp_print_driver_callback() - Update the current printer driver...
  1748.  */
  1749. static void 
  1750. gimp_print_driver_callback (GtkWidget      *widget, /* I - Driver list */
  1751.                 gint            row,
  1752.                 gint            column,
  1753.                 GdkEventButton *event,
  1754.                 gpointer        data)   /* I - Data */
  1755. {
  1756.   data = gtk_clist_get_row_data (GTK_CLIST (widget), row);
  1757.   current_printer = get_printer_by_index ((gint) data);
  1758.  
  1759.   if (strncmp (current_printer->driver, "ps", 2) == 0)
  1760.     {
  1761.       gtk_widget_show (ppd_file);
  1762.       gtk_widget_show (ppd_button);
  1763.     }
  1764.   else
  1765.     {
  1766.       gtk_widget_hide (ppd_file);
  1767.       gtk_widget_hide (ppd_button);
  1768.     }
  1769. }
  1770.  
  1771. /*
  1772.  *  gimp_ppd_browse_callback() -
  1773.  */
  1774. static void
  1775. gimp_ppd_browse_callback (void)
  1776. {
  1777.   gtk_file_selection_set_filename (GTK_FILE_SELECTION (ppd_browser),
  1778.                    gtk_entry_get_text (GTK_ENTRY (ppd_file)));
  1779.   gtk_widget_show (ppd_browser);
  1780. }
  1781.  
  1782. /*
  1783.  *  gimp_ppd_ok_callback() -
  1784.  */
  1785. static void
  1786. gimp_ppd_ok_callback (void)
  1787. {
  1788.   gtk_widget_hide (ppd_browser);
  1789.   gtk_entry_set_text
  1790.     (GTK_ENTRY (ppd_file),
  1791.      gtk_file_selection_get_filename (GTK_FILE_SELECTION (ppd_browser)));
  1792. }
  1793.  
  1794. /*
  1795.  *  gimp_file_ok_callback() - print to file and go away
  1796.  */
  1797. static void
  1798. gimp_file_ok_callback (void)
  1799. {
  1800.   gtk_widget_hide (file_browser);
  1801.   strcpy (vars.output_to,
  1802.       gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_browser)));
  1803.  
  1804.   runme = TRUE;
  1805.   gtk_widget_destroy (gimp_color_adjust_dialog);
  1806.   gtk_widget_destroy (setup_dialog);
  1807.   gtk_widget_destroy (print_dialog);
  1808. }
  1809.  
  1810. /*
  1811.  *  gimp_file_cancel_callback() -
  1812.  */
  1813. static void
  1814. gimp_file_cancel_callback (void)
  1815. {
  1816.   gtk_widget_hide (file_browser);
  1817.   gtk_widget_set_sensitive (gimp_color_adjust_dialog, TRUE);
  1818.   gtk_widget_set_sensitive (print_dialog, TRUE);
  1819.   gtk_widget_set_sensitive (print_dialog, TRUE);
  1820. }
  1821.  
  1822. /*
  1823.  * gimp_update_adjusted_thumbnail()
  1824.  */
  1825. void
  1826. gimp_update_adjusted_thumbnail (void)
  1827. {
  1828.   gint      x, y;
  1829.   convert_t colourfunc;
  1830.   gushort   out[3 * THUMBNAIL_MAXW];
  1831.   guchar   *adjusted_data = adjusted_thumbnail_data;
  1832.   gfloat    old_density = vars.density;
  1833.  
  1834.   if (thumbnail_data == 0 || adjusted_thumbnail_data == 0)
  1835.     return;
  1836.  
  1837.   vars.density = 1.0;
  1838.  
  1839.   compute_lut (256, &vars);
  1840.   colourfunc = choose_colorfunc (vars.output_type, thumbnail_bpp, NULL,
  1841.                  &adjusted_thumbnail_bpp, &vars);
  1842.  
  1843.   for (y = 0; y < thumbnail_h; y++)
  1844.     {
  1845.       (*colourfunc) (thumbnail_data + thumbnail_bpp * thumbnail_w * y,
  1846.              out, thumbnail_w, thumbnail_bpp, NULL, &vars);
  1847.       for (x = 0; x < adjusted_thumbnail_bpp * thumbnail_w; x++)
  1848.     {
  1849.       *adjusted_data++ = out[x] / 0x0101U;
  1850.     }
  1851.     }
  1852.  
  1853.   free_lut (&vars);
  1854.  
  1855.   vars.density = old_density;
  1856.  
  1857.   gimp_redraw_color_swatch ();
  1858.   gimp_preview_update ();
  1859. }
  1860.  
  1861. /*
  1862.  *  gimp_preview_update_callback() -
  1863.  */
  1864. static void
  1865. gimp_preview_update (void)
  1866. {
  1867.   gint            temp;
  1868.   gint          orient;           /* True orientation of page */
  1869.   gdouble    max_ppi_scaling;   /* Maximum PPI for current page size */
  1870.   gdouble    min_ppi_scaling;   /* Minimum PPI for current page size */
  1871.   gdouble    min_ppi_scaling1;   /* Minimum PPI for current page size */
  1872.   gdouble    min_ppi_scaling2;   /* Minimum PPI for current page size */
  1873.   static GdkGC    *gc    = NULL;
  1874.   static GdkGC  *gcinv = NULL;
  1875.   gchar         s[255];
  1876.   gint          paper_left, paper_top;
  1877.   gdouble    unit_scaler = 72.0;
  1878.  
  1879.   (*current_printer->media_size) (current_printer, &vars, &paper_width,
  1880.                   &paper_height);
  1881.  
  1882.   (*current_printer->imageable_area) (current_printer, &vars, &left, &right,
  1883.                       &bottom, &top);
  1884.  
  1885.   /* Rationalise things a bit by measuring everything from the top left */
  1886.   top = paper_height - top;
  1887.   bottom = paper_height - bottom;
  1888.  
  1889.   printable_width  = right - left;
  1890.   printable_height = bottom - top;
  1891.  
  1892.   if (vars.orientation == ORIENT_AUTO)
  1893.     {
  1894.       if ((printable_width >= printable_height && image_width >= image_height)
  1895.       || (printable_height >= printable_width && image_height >= image_width))
  1896.     orient = ORIENT_PORTRAIT;
  1897.       else
  1898.     orient = ORIENT_LANDSCAPE;
  1899.     }
  1900.   else
  1901.     orient = vars.orientation;
  1902.  
  1903.   /*
  1904.    * Adjust page dimensions depending on the page orientation...
  1905.    */
  1906.  
  1907.   bottom = paper_height - bottom;
  1908.   right = paper_width - right;
  1909.  
  1910.   if (orient == ORIENT_LANDSCAPE || orient == ORIENT_SEASCAPE)
  1911.     {
  1912.       temp              = printable_width;
  1913.       printable_width   = printable_height;
  1914.       printable_height  = temp;
  1915.       temp              = paper_width;
  1916.       paper_width       = paper_height;
  1917.       paper_height      = temp;
  1918.     }
  1919.   if (orient == ORIENT_LANDSCAPE)
  1920.     {
  1921.       temp              = left;
  1922.       left              = bottom;
  1923.       bottom            = right;
  1924.       right             = top;
  1925.       top               = temp;
  1926.     }
  1927.   if (orient == ORIENT_SEASCAPE)
  1928.     {
  1929.       temp              = left;
  1930.       left              = top;
  1931.       top               = right;
  1932.       right             = bottom;
  1933.       bottom            = temp;
  1934.     }
  1935.   else if (orient == ORIENT_UPSIDEDOWN)
  1936.     {
  1937.       temp              = left;
  1938.       left              = right;
  1939.       right        = temp;
  1940.       temp              = top;
  1941.       top               = bottom;
  1942.       bottom        = temp;
  1943.     }
  1944.  
  1945.   bottom = paper_height - bottom;
  1946.   right = paper_width - right;
  1947.  
  1948.   if (vars.scaling < 0)
  1949.     {
  1950.       gdouble twidth;
  1951.  
  1952.       min_ppi_scaling1 = 72.0 * (gdouble) image_width / printable_width;
  1953.       min_ppi_scaling2 = 72.0 * (gdouble) image_height / printable_height;
  1954.  
  1955.       if (min_ppi_scaling1 > min_ppi_scaling2)
  1956.     min_ppi_scaling = min_ppi_scaling1;
  1957.       else
  1958.     min_ppi_scaling = min_ppi_scaling2;
  1959.  
  1960.       max_ppi_scaling = min_ppi_scaling * 20;
  1961.       if (vars.scaling < 0 && vars.scaling > -min_ppi_scaling)
  1962.     vars.scaling = -min_ppi_scaling;
  1963.       twidth = (72.0 * image_width / -vars.scaling) + .5;
  1964.       print_width = twidth;
  1965.       print_height = (twidth * (gdouble) image_height / image_width) + .5;
  1966.       GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
  1967.       GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
  1968.       GTK_ADJUSTMENT (scaling_adjustment)->value = -vars.scaling;
  1969.       if (!suppress_scaling_adjustment)
  1970.     {
  1971.       gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1972.       suppress_scaling_callback = TRUE;
  1973.       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
  1974.       suppress_scaling_callback = FALSE;
  1975.       gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
  1976.     }
  1977.     }
  1978.   else
  1979.     {
  1980.       /* we do vars.scaling % of height or width, whatever is smaller */
  1981.       /* this is relative to printable size */
  1982.       if (image_width * printable_height > printable_width * image_height)
  1983.     /* i.e. if image_width/image_height > printable_width/printable_height */
  1984.     /* i.e. if image is wider relative to its height than the width
  1985.        of the printable area relative to its height */
  1986.     {
  1987.       gdouble twidth = .5 + printable_width * vars.scaling / 100;
  1988.  
  1989.       print_width = twidth;
  1990.       print_height = twidth * image_height / image_width;
  1991.     }
  1992.       else
  1993.     {
  1994.       gdouble theight = .5 + printable_height * vars.scaling / 100;
  1995.  
  1996.       print_height = theight;
  1997.       print_width = theight * image_width / image_height;
  1998.     }
  1999.     }
  2000.  
  2001.   preview_ppi = PREVIEW_SIZE_HORIZ * 72 / paper_width;
  2002.   if (PREVIEW_SIZE_VERT * 72 / paper_height < preview_ppi)
  2003.     preview_ppi = PREVIEW_SIZE_VERT * 72 / paper_height;
  2004.   if (preview_ppi > MAX_PREVIEW_PPI)
  2005.     preview_ppi = MAX_PREVIEW_PPI;
  2006.  
  2007.   paper_left = (PREVIEW_SIZE_HORIZ - preview_ppi * paper_width / 72) / 2;
  2008.   paper_top  = (PREVIEW_SIZE_VERT - preview_ppi * paper_height / 72) / 2;
  2009.   printable_left = paper_left +  preview_ppi * left / 72;
  2010.   printable_top  = paper_top + preview_ppi * top / 72 ;
  2011.  
  2012.   if (preview == NULL || preview->widget.window == NULL)
  2013.     return;
  2014.  
  2015.   if (vars.left < 0)
  2016.     {
  2017.       vars.left = (paper_width - print_width) / 2 - left;
  2018.       if (vars.left < 0)
  2019.     vars.left = 0;
  2020.     }
  2021.  
  2022.   /* we leave vars.left etc. relative to printable area */
  2023.   if (vars.left > (printable_width - print_width))
  2024.     vars.left = printable_width - print_width;
  2025.  
  2026.   if (vars.top < 0)
  2027.     {
  2028.       vars.top  = ((paper_height - print_height) / 2) - top;
  2029.       if (vars.top < 0)
  2030.     vars.top = 0;
  2031.     }
  2032.  
  2033.   if (vars.top > (printable_height - print_height))
  2034.     vars.top = printable_height - print_height;
  2035.  
  2036.   plist[plist_current].v.left = vars.left;
  2037.   plist[plist_current].v.top = vars.top;
  2038.  
  2039.   if(vars.unit) unit_scaler /= 2.54;
  2040.   g_snprintf (s, sizeof (s), "%.2f", (top + vars.top) / unit_scaler);
  2041.   gtk_signal_handler_block_by_data (GTK_OBJECT (top_entry), NULL);
  2042.   gtk_entry_set_text (GTK_ENTRY (top_entry), s);
  2043.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (top_entry), NULL);
  2044.  
  2045.   g_snprintf (s, sizeof (s), "%.2f",(left + vars.left) / unit_scaler);
  2046.   gtk_signal_handler_block_by_data (GTK_OBJECT (left_entry), NULL);
  2047.   gtk_entry_set_text (GTK_ENTRY (left_entry), s);
  2048.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (left_entry), NULL);
  2049.  
  2050.   gtk_signal_handler_block_by_data (GTK_OBJECT (bottom_entry), NULL);
  2051.   g_snprintf(s, sizeof (s), "%.2f",
  2052.          (top + vars.top + print_height) / unit_scaler);
  2053.   gtk_entry_set_text (GTK_ENTRY (bottom_entry), s);
  2054.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (bottom_entry), NULL);
  2055.  
  2056.   gtk_signal_handler_block_by_data (GTK_OBJECT (bottom_border_entry), NULL);
  2057.   g_snprintf(s, sizeof (s), "%.2f",
  2058.          (paper_height - (top + vars.top + print_height)) / unit_scaler);
  2059.   gtk_entry_set_text (GTK_ENTRY (bottom_border_entry), s);
  2060.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (bottom_border_entry), NULL);
  2061.  
  2062.   gtk_signal_handler_block_by_data (GTK_OBJECT (right_entry), NULL);
  2063.   g_snprintf (s, sizeof (s), "%.2f",
  2064.           (left + vars.left + print_width) / unit_scaler);
  2065.   gtk_entry_set_text (GTK_ENTRY (right_entry), s);
  2066.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (right_entry), NULL);
  2067.  
  2068.   gtk_signal_handler_block_by_data (GTK_OBJECT (right_border_entry), NULL);
  2069.   g_snprintf (s, sizeof (s), "%.2f",
  2070.           (paper_width - (left + vars.left + print_width)) / unit_scaler);
  2071.   gtk_entry_set_text (GTK_ENTRY (right_border_entry), s);
  2072.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (right_border_entry), NULL);
  2073.  
  2074.   gtk_signal_handler_block_by_data (GTK_OBJECT (width_entry), NULL);
  2075.   g_snprintf (s, sizeof (s), "%.2f", print_width / unit_scaler);
  2076.   gtk_entry_set_text (GTK_ENTRY (width_entry), s);
  2077.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (width_entry), NULL);
  2078.  
  2079.   gtk_signal_handler_block_by_data (GTK_OBJECT (height_entry), NULL);
  2080.   g_snprintf(s, sizeof (s), "%.2f", print_height / unit_scaler);
  2081.   gtk_entry_set_text (GTK_ENTRY (height_entry), s);
  2082.   gtk_signal_handler_unblock_by_data (GTK_OBJECT (height_entry), NULL);
  2083.  
  2084.   /* draw image */
  2085.   {
  2086.     gint ox, oy, u;
  2087.     gint preview_x = 1 + printable_left + preview_ppi * vars.left / 72;
  2088.     gint preview_y = 1 + printable_top + preview_ppi * vars.top / 72;
  2089.     gint preview_w = MAX (1, (preview_ppi * print_width) / 72);
  2090.     gint preview_h = MAX (1, (preview_ppi * print_height) / 72);
  2091.  
  2092.     guchar *preview_data;
  2093.  
  2094.     gint v_denominator = preview_h > 1 ? preview_h - 1 : 1;
  2095.     gint v_numerator = (thumbnail_h - 1) % v_denominator;
  2096.     gint v_whole = (thumbnail_h - 1) / v_denominator;
  2097.     gint v_cur = 0;
  2098.     gint v_last = -1;
  2099.     gint v_error = v_denominator / 2;
  2100.     gint y = 0;
  2101.  
  2102.     preview_data = g_malloc(3 * preview_h * preview_w);
  2103.     while (y < preview_h)
  2104.       {
  2105.     if (v_cur == v_last)
  2106.       {
  2107.         memcpy (preview_data + adjusted_thumbnail_bpp * preview_w * y,
  2108.             preview_data + adjusted_thumbnail_bpp * preview_w * (y - 1),
  2109.             adjusted_thumbnail_bpp * preview_w);
  2110.       }
  2111.     else
  2112.       {
  2113.         guchar *inbuf = adjusted_thumbnail_data - adjusted_thumbnail_bpp
  2114.           + adjusted_thumbnail_bpp * thumbnail_w * v_cur;
  2115.         guchar *outbuf = preview_data
  2116.           + adjusted_thumbnail_bpp * preview_w * y;
  2117.  
  2118.         gint h_denominator = preview_w > 1 ? preview_w - 1 : 1;
  2119.         gint h_numerator = (thumbnail_w - 1) % h_denominator;
  2120.         gint h_whole = (thumbnail_w - 1) / h_denominator;
  2121.         gint h_cur = 0;
  2122.         gint h_last = -1;
  2123.         gint h_error = h_denominator / 2;
  2124.         gint x = 0;
  2125.  
  2126.         v_last = v_cur;
  2127.         while (x < preview_w)
  2128.           {
  2129.         if (h_cur == h_last)
  2130.           {
  2131.             if (adjusted_thumbnail_bpp == 1)
  2132.               {
  2133.             outbuf[0] = outbuf[-1];
  2134.             outbuf++;
  2135.               }
  2136.             else
  2137.               {
  2138.             outbuf[0] = outbuf[-3];
  2139.             outbuf[1] = outbuf[-2];
  2140.             outbuf[2] = outbuf[-1];
  2141.             outbuf += 3;
  2142.               }
  2143.           }
  2144.         else
  2145.           {
  2146.             inbuf += adjusted_thumbnail_bpp * (h_cur - h_last);
  2147.             h_last = h_cur;
  2148.             outbuf[0] = inbuf[0];
  2149.             outbuf++;
  2150.             if (adjusted_thumbnail_bpp == 3)
  2151.               {
  2152.             outbuf[0] = inbuf[1];
  2153.             outbuf[1] = inbuf[2];
  2154.             outbuf += 2;
  2155.               }
  2156.           }
  2157.         x++;
  2158.         h_cur += h_whole;
  2159.         h_error += h_numerator;
  2160.         if (h_error >= h_denominator)
  2161.           {
  2162.             h_error -= h_denominator;
  2163.             h_cur++;
  2164.           }
  2165.           }
  2166.       }
  2167.     y++;
  2168.     v_cur += v_whole;
  2169.     v_error += v_numerator;
  2170.     if (v_error >= v_denominator)
  2171.       {
  2172.         v_error -= v_denominator;
  2173.         v_cur++;
  2174.       }
  2175.       }
  2176.  
  2177.     gdk_window_clear (preview->widget.window);
  2178.  
  2179.     if (gc == NULL)
  2180.       {
  2181.     gc = gdk_gc_new (preview->widget.window);
  2182.     gcinv = gdk_gc_new (preview->widget.window);
  2183.     gdk_gc_set_function (gcinv, GDK_INVERT);
  2184.       }
  2185.  
  2186.     /* draw paper frame */
  2187.     gdk_draw_rectangle (preview->widget.window, gc, 0,
  2188.             paper_left, paper_top,
  2189.             preview_ppi * paper_width / 72,
  2190.             preview_ppi * paper_height / 72);
  2191.  
  2192.     /* draw printable frame */
  2193.     gdk_draw_rectangle (preview->widget.window, gc, 0,
  2194.             printable_left, printable_top,
  2195.             preview_ppi * printable_width / 72,
  2196.             preview_ppi * printable_height / 72);
  2197.  
  2198.     if (adjusted_thumbnail_bpp == 1)
  2199.       gdk_draw_gray_image (preview->widget.window, gc,
  2200.                preview_x, preview_y, preview_w, preview_h,
  2201.                GDK_RGB_DITHER_NORMAL, preview_data, preview_w);
  2202.     else
  2203.       gdk_draw_rgb_image (preview->widget.window, gc,
  2204.               preview_x, preview_y, preview_w, preview_h,
  2205.               GDK_RGB_DITHER_NORMAL, preview_data, 3 * preview_w);
  2206.  
  2207.     /* draw orientation arrow pointing to top-of-paper */
  2208.     u = preview_ppi/2;
  2209.     ox = paper_left + preview_ppi * paper_width / 72 / 2;
  2210.     oy = paper_top + preview_ppi * paper_height / 72 / 2;
  2211.     if (orient == ORIENT_LANDSCAPE)
  2212.       {
  2213.     ox += preview_ppi * paper_width / 72 / 4;
  2214.     if (ox > paper_left + preview_ppi * paper_width / 72 - u)
  2215.       ox = paper_left + preview_ppi * paper_width / 72 - u;
  2216.     gdk_draw_line (preview->widget.window, gcinv, ox + u, oy, ox, oy - u);
  2217.     gdk_draw_line (preview->widget.window, gcinv, ox + u, oy, ox, oy + u);
  2218.     gdk_draw_line (preview->widget.window, gcinv, ox + u, oy, ox - u, oy);
  2219.       }
  2220.     else if (orient == ORIENT_SEASCAPE)
  2221.       {
  2222.     ox -= preview_ppi * paper_width / 72 / 4;
  2223.     if (ox < paper_left + u)
  2224.       ox = paper_left + u;
  2225.     gdk_draw_line (preview->widget.window, gcinv, ox - u, oy, ox, oy - u);
  2226.     gdk_draw_line (preview->widget.window, gcinv, ox - u, oy, ox, oy + u);
  2227.     gdk_draw_line (preview->widget.window, gcinv, ox - u, oy, ox + u, oy);
  2228.       }
  2229.     else if (orient == ORIENT_UPSIDEDOWN)
  2230.       {
  2231.     oy += preview_ppi * paper_height / 72 / 4;
  2232.     if (oy > paper_top + preview_ppi * paper_height / 72 - u)
  2233.       oy = paper_top + preview_ppi * paper_height / 72 - u;
  2234.     gdk_draw_line (preview->widget.window, gcinv, ox, oy + u, ox - u, oy);
  2235.     gdk_draw_line (preview->widget.window, gcinv, ox, oy + u, ox + u, oy);
  2236.     gdk_draw_line (preview->widget.window, gcinv, ox, oy + u, ox, oy - u);
  2237.       }
  2238.     else /* (orient == ORIENT_PORTRAIT) */
  2239.       {
  2240.     oy -= preview_ppi * paper_height / 72 / 4;
  2241.     if (oy < paper_top + u)
  2242.       oy = paper_top + u;
  2243.     gdk_draw_line (preview->widget.window, gcinv, ox, oy - u, ox - u, oy);
  2244.     gdk_draw_line (preview->widget.window, gcinv, ox, oy - u, ox + u, oy);
  2245.     gdk_draw_line (preview->widget.window, gcinv, ox, oy - u, ox, oy + u);
  2246.       }
  2247.     g_free(preview_data);
  2248.   }
  2249.  
  2250.   gdk_flush ();
  2251. }
  2252.  
  2253. /*
  2254.  *  gimp_preview_button_callback() -
  2255.  */
  2256. static void
  2257. gimp_preview_button_callback (GtkWidget      *widget,
  2258.                   GdkEventButton *event,
  2259.                   gpointer        data)
  2260. {
  2261.   mouse_x = event->x;
  2262.   mouse_y = event->y;
  2263.   mouse_button = event->button;
  2264. }
  2265.  
  2266. /*
  2267.  *  gimp_preview_motion_callback() -
  2268.  */
  2269. static void
  2270. gimp_preview_motion_callback (GtkWidget      *widget,
  2271.                   GdkEventMotion *event,
  2272.                   gpointer        data)
  2273. {
  2274.   if (vars.left < 0 || vars.top < 0)
  2275.     {
  2276.       vars.left = 72 * (printable_width - print_width) / 20;
  2277.       vars.top  = 72 * (printable_height - print_height) / 20;
  2278.     }
  2279.  
  2280.   if (mouse_button == 1)
  2281.     {
  2282.       vars.left += 72 * (event->x - mouse_x) / preview_ppi;
  2283.       vars.top  += 72 * (event->y - mouse_y) / preview_ppi;
  2284.     }
  2285.   else
  2286.     {
  2287.       vars.left += event->x - mouse_x;
  2288.       vars.top  += event->y - mouse_y;
  2289.     }
  2290.  
  2291.   if (vars.left < 0)
  2292.     vars.left = 0;
  2293.  
  2294.   if (vars.top < 0)
  2295.     vars.top = 0;
  2296.   plist[plist_current].v.left = vars.left;
  2297.   plist[plist_current].v.top = vars.top;
  2298.  
  2299.   gimp_preview_update ();
  2300.  
  2301.   mouse_x = event->x;
  2302.   mouse_y = event->y;
  2303. }
  2304.  
  2305. #endif  /* ! GIMP_1_0 */
  2306.