home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / commands.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-25  |  33.2 KB  |  1,497 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <glib.h>
  22.  
  23. #include "apptypes.h"
  24.  
  25. #include "appenv.h"
  26. #include "about_dialog.h"
  27. #include "app_procs.h"
  28. #include "brush_select.h"
  29. #include "colormap_dialog.i.h"
  30. #include "color_area.h"
  31. #include "commands.h"
  32. #include "convert.h"
  33. #include "desaturate.h"
  34. #include "devices.h"
  35. #include "docindex.h"
  36. #include "channel_ops.h"
  37. #include "drawable.h"
  38. #include "equalize.h"
  39. #include "errorconsole.h"
  40. #include "fileops.h"
  41. #include "floating_sel.h"
  42. #include "gdisplay_ops.h"
  43. #include "gimage_mask.h"
  44. #include "gimphelp.h"
  45. #include "gimprc.h"
  46. #include "gimpui.h"
  47. #include "global_edit.h"
  48. #include "gradient_select.h"
  49. #include "image_render.h"
  50. #include "info_window.h"
  51. #include "nav_window.h"
  52. #include "invert.h"
  53. #include "lc_dialog.h"
  54. #include "layer_select.h"
  55. #include "module_db.h"
  56. #include "palette.h"
  57. #include "pattern_select.h"
  58. #include "plug_in.h"
  59. #include "resize.h"
  60. #include "scale.h"
  61. #include "tips_dialog.h"
  62. #include "tools.h"
  63. #include "undo.h"
  64.  
  65. #ifdef DISPLAY_FILTERS
  66. #include "gdisplay_color_ui.h"
  67. #endif /* DISPLAY_FILTERS */
  68.  
  69. #include "libgimp/gimpmath.h"
  70. #include "libgimp/gimpintl.h"
  71.  
  72. #define return_if_no_display(gdisp) \
  73.         gdisp = gdisplay_active (); \
  74.         if (!gdisp) return
  75.  
  76. /*  external functions  */
  77. extern void   layers_dialog_layer_merge_query (GImage *, gboolean);
  78.  
  79. /*  local functions  */
  80. static void     image_resize_callback        (GtkWidget *, gpointer);
  81. static void     image_scale_callback         (GtkWidget *, gpointer);
  82. static void     gimage_mask_feather_callback (GtkWidget *, gdouble, GimpUnit,
  83.                           gpointer);
  84. static void     gimage_mask_border_callback  (GtkWidget *, gdouble, GimpUnit,
  85.                             gpointer);
  86. static void     gimage_mask_grow_callback    (GtkWidget *, gdouble, GimpUnit,
  87.                           gpointer);
  88. static void     gimage_mask_shrink_callback  (GtkWidget *, gdouble, GimpUnit,
  89.                           gpointer);
  90.  
  91. /*  local variables  */
  92. static gdouble   selection_feather_radius    = 5.0;
  93. static gint      selection_border_radius     = 5;
  94. static gint      selection_grow_pixels       = 1;
  95. static gint      selection_shrink_pixels     = 1;
  96. static gboolean  selection_shrink_edge_lock  = FALSE;
  97.  
  98.  
  99. /*****  File  *****/
  100.  
  101. void
  102. file_open_cmd_callback (GtkWidget *widget,
  103.             gpointer   client_data)
  104. {
  105.   file_open_callback (widget, client_data);
  106. }
  107.  
  108. void
  109. file_save_cmd_callback (GtkWidget *widget,
  110.             gpointer   client_data)
  111. {
  112.   file_save_callback (widget, client_data);
  113. }
  114.  
  115. void
  116. file_save_as_cmd_callback (GtkWidget *widget,
  117.                gpointer   client_data)
  118. {
  119.   file_save_as_callback (widget, client_data);
  120. }
  121.  
  122. void
  123. file_revert_cmd_callback (GtkWidget *widget,
  124.             gpointer   client_data)
  125. {
  126.   file_revert_callback (widget, client_data);
  127. }
  128.  
  129. void
  130. file_close_cmd_callback (GtkWidget *widget,
  131.              gpointer   client_data)
  132. {
  133.   GDisplay *gdisp;
  134.   return_if_no_display (gdisp);
  135.  
  136.   gdisplay_close_window (gdisp, FALSE);
  137. }
  138.  
  139. void
  140. file_quit_cmd_callback (GtkWidget *widget,
  141.             gpointer   client_data)
  142. {
  143.   app_exit (FALSE);
  144. }
  145.  
  146. /*****  Edit  *****/
  147.  
  148. void
  149. edit_undo_cmd_callback (GtkWidget *widget,
  150.             gpointer   client_data)
  151. {
  152.   GDisplay *gdisp;
  153.   return_if_no_display (gdisp);
  154.  
  155.   undo_pop (gdisp->gimage);
  156. }
  157.  
  158. void
  159. edit_redo_cmd_callback (GtkWidget *widget,
  160.             gpointer   client_data)
  161. {
  162.   GDisplay *gdisp;
  163.   return_if_no_display (gdisp);
  164.  
  165.   undo_redo (gdisp->gimage);
  166. }
  167.  
  168. void
  169. edit_cut_cmd_callback (GtkWidget *widget,
  170.                gpointer   client_data)
  171. {
  172.   GDisplay *gdisp;
  173.   return_if_no_display (gdisp);
  174.  
  175.   global_edit_cut (gdisp);
  176. }
  177.  
  178. void
  179. edit_copy_cmd_callback (GtkWidget *widget,
  180.             gpointer   client_data)
  181. {
  182.   GDisplay *gdisp;
  183.   return_if_no_display (gdisp);
  184.  
  185.   global_edit_copy (gdisp);
  186. }
  187.  
  188. void
  189. edit_paste_cmd_callback (GtkWidget *widget,
  190.              gpointer   client_data)
  191. {
  192.   GDisplay *gdisp;
  193.   return_if_no_display (gdisp);
  194.  
  195.   global_edit_paste (gdisp, 0);
  196. }
  197.  
  198. void
  199. edit_paste_into_cmd_callback (GtkWidget *widget,
  200.                   gpointer   client_data)
  201. {
  202.   GDisplay *gdisp;
  203.   return_if_no_display (gdisp);
  204.  
  205.   global_edit_paste (gdisp, 1);
  206. }
  207.  
  208. void
  209. edit_paste_as_new_cmd_callback (GtkWidget *widget,
  210.                 gpointer   client_data)
  211. {
  212.   GDisplay *gdisp;
  213.   return_if_no_display (gdisp);
  214.  
  215.   global_edit_paste_as_new (gdisp);
  216. }
  217.  
  218. void
  219. edit_named_cut_cmd_callback (GtkWidget *widget,
  220.                  gpointer   client_data)
  221. {
  222.   GDisplay *gdisp;
  223.   return_if_no_display (gdisp);
  224.  
  225.   named_edit_cut (gdisp);
  226. }
  227.  
  228. void
  229. edit_named_copy_cmd_callback (GtkWidget *widget,
  230.                   gpointer   client_data)
  231. {
  232.   GDisplay *gdisp;
  233.   return_if_no_display (gdisp);
  234.  
  235.   named_edit_copy (gdisp);
  236. }
  237.  
  238. void
  239. edit_named_paste_cmd_callback (GtkWidget *widget,
  240.                    gpointer   client_data)
  241. {
  242.   GDisplay *gdisp;
  243.   return_if_no_display (gdisp);
  244.  
  245.   named_edit_paste (gdisp);
  246. }
  247.  
  248. void
  249. edit_clear_cmd_callback (GtkWidget *widget,
  250.              gpointer   client_data)
  251. {
  252.   GDisplay *gdisp;
  253.   return_if_no_display (gdisp);
  254.  
  255.   edit_clear (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
  256.   gdisplays_flush ();
  257. }
  258.  
  259. void
  260. edit_fill_cmd_callback (GtkWidget *widget,
  261.             gpointer   callback_data,
  262.             guint      callback_action)
  263. {
  264.   GimpFillType fill_type;
  265.   GDisplay *gdisp;
  266.   return_if_no_display (gdisp);
  267.  
  268.   fill_type = (GimpFillType) callback_action;
  269.   edit_fill (gdisp->gimage, gimage_active_drawable (gdisp->gimage), fill_type);
  270.   gdisplays_flush ();
  271. }
  272.  
  273. void
  274. edit_stroke_cmd_callback (GtkWidget *widget,
  275.               gpointer   client_data)
  276. {
  277.   GDisplay *gdisp;
  278.   return_if_no_display (gdisp);
  279.  
  280.   gimage_mask_stroke (gdisp->gimage, gimage_active_drawable (gdisp->gimage));
  281.   gdisplays_flush ();
  282. }
  283.  
  284. /*****  Select  *****/
  285.  
  286. void
  287. select_invert_cmd_callback (GtkWidget *widget,
  288.                 gpointer   client_data)
  289. {
  290.   GDisplay *gdisp;
  291.   return_if_no_display (gdisp);
  292.  
  293.   gimage_mask_invert (gdisp->gimage);
  294.   gdisplays_flush ();
  295. }
  296.  
  297. void
  298. select_all_cmd_callback (GtkWidget *widget,
  299.              gpointer   client_data)
  300. {
  301.   GDisplay *gdisp;
  302.   return_if_no_display (gdisp);
  303.  
  304.   gimage_mask_all (gdisp->gimage);
  305.   gdisplays_flush ();
  306. }
  307.  
  308. void
  309. select_none_cmd_callback (GtkWidget *widget,
  310.               gpointer   client_data)
  311. {
  312.   GDisplay *gdisp;
  313.   return_if_no_display (gdisp);
  314.  
  315.   gimage_mask_none (gdisp->gimage);
  316.   gdisplays_flush ();
  317. }
  318.  
  319. void
  320. select_float_cmd_callback (GtkWidget *widget,
  321.                gpointer   client_data)
  322. {
  323.   GDisplay *gdisp;
  324.   return_if_no_display (gdisp);
  325.  
  326.   gimage_mask_float (gdisp->gimage, gimage_active_drawable (gdisp->gimage),
  327.              0, 0);
  328.   gdisplays_flush ();
  329. }
  330.  
  331. void
  332. select_feather_cmd_callback (GtkWidget *widget,
  333.                  gpointer   client_data)
  334. {
  335.   GtkWidget *qbox;
  336.   GDisplay  *gdisp;
  337.  
  338.   return_if_no_display (gdisp);
  339.  
  340.   qbox = gimp_query_size_box (_("Feather Selection"),
  341.                   gimp_standard_help_func,
  342.                   "dialogs/feather_selection.html",
  343.                   _("Feather Selection by:"),
  344.                   selection_feather_radius, 0, 32767, 3,
  345.                   gdisp->gimage->unit,
  346.                   MIN (gdisp->gimage->xresolution,
  347.                    gdisp->gimage->yresolution),
  348.                   gdisp->dot_for_dot,
  349.                   GTK_OBJECT (gdisp->gimage), "destroy",
  350.                   gimage_mask_feather_callback, gdisp->gimage);
  351.   gtk_widget_show (qbox);
  352. }
  353.  
  354. void
  355. select_sharpen_cmd_callback (GtkWidget *widget,
  356.                  gpointer   client_data)
  357. {
  358.   GDisplay *gdisp;
  359.   return_if_no_display (gdisp);
  360.  
  361.   gimage_mask_sharpen (gdisp->gimage);
  362.   gdisplays_flush ();
  363. }
  364.  
  365. void
  366. select_shrink_cmd_callback (GtkWidget *widget,
  367.                 gpointer   client_data)
  368. {
  369.   GtkWidget *edge_lock;
  370.   GtkWidget *shrink_dialog;
  371.  
  372.   GDisplay *gdisp;
  373.   return_if_no_display (gdisp);
  374.  
  375.   shrink_dialog =
  376.     gimp_query_size_box (N_("Shrink Selection"),
  377.              gimp_standard_help_func,
  378.              "dialogs/shrink_selection.html",
  379.              _("Shrink Selection by:"),
  380.              selection_shrink_pixels, 1, 32767, 0,
  381.              gdisp->gimage->unit,
  382.              MIN (gdisp->gimage->xresolution,
  383.                   gdisp->gimage->yresolution),
  384.              gdisp->dot_for_dot,
  385.              GTK_OBJECT (gdisp->gimage), "destroy",
  386.              gimage_mask_shrink_callback, gdisp->gimage);
  387.  
  388.   edge_lock = gtk_check_button_new_with_label (_("Shrink from image border"));
  389.   /* eeek */
  390.   gtk_box_pack_start (GTK_BOX (g_list_nth_data (gtk_container_children (GTK_CONTAINER (GTK_DIALOG (shrink_dialog)->vbox)), 0)), edge_lock,
  391.               FALSE, FALSE, 0);
  392.   gtk_object_set_data (GTK_OBJECT (shrink_dialog), "edge_lock_toggle",
  393.                edge_lock);
  394.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (edge_lock),
  395.                 ! selection_shrink_edge_lock);
  396.   gtk_widget_show (edge_lock);
  397.  
  398.   gtk_widget_show (shrink_dialog);
  399. }
  400.  
  401. void
  402. select_grow_cmd_callback (GtkWidget *widget,
  403.               gpointer   client_data)
  404. {
  405.   GtkWidget *qbox;
  406.   GDisplay  *gdisp;
  407.  
  408.   return_if_no_display (gdisp);
  409.  
  410.   qbox = gimp_query_size_box (_("Grow Selection"),
  411.                   gimp_standard_help_func,
  412.                   "dialogs/grow_selection.html",
  413.                   _("Grow Selection by:"),
  414.                   selection_grow_pixels, 1, 32767, 0,
  415.                   gdisp->gimage->unit,
  416.                   MIN (gdisp->gimage->xresolution,
  417.                    gdisp->gimage->yresolution),
  418.                   gdisp->dot_for_dot,
  419.                   GTK_OBJECT (gdisp->gimage), "destroy",
  420.                   gimage_mask_grow_callback, gdisp->gimage);
  421.   gtk_widget_show (qbox);
  422. }
  423.  
  424. void
  425. select_border_cmd_callback (GtkWidget *widget,
  426.                 gpointer   client_data)
  427. {
  428.   GtkWidget *qbox;
  429.   GDisplay  *gdisp;
  430.  
  431.   return_if_no_display (gdisp);
  432.  
  433.   qbox = gimp_query_size_box (_("Border Selection"),
  434.                   gimp_standard_help_func,
  435.                   "dialogs/border_selection.html",
  436.                   _("Border Selection by:"),
  437.                   selection_border_radius, 1, 32767, 0,
  438.                   gdisp->gimage->unit,
  439.                   MIN (gdisp->gimage->xresolution,
  440.                    gdisp->gimage->yresolution),
  441.                   gdisp->dot_for_dot,
  442.                   GTK_OBJECT (gdisp->gimage), "destroy",
  443.                   gimage_mask_border_callback, gdisp->gimage);
  444.   gtk_widget_show (qbox);
  445. }
  446.  
  447. void
  448. select_save_cmd_callback (GtkWidget *widget,
  449.               gpointer   client_data)
  450. {
  451.   GDisplay *gdisp;
  452.   return_if_no_display (gdisp);
  453.  
  454.   gimage_mask_save (gdisp->gimage);
  455.   gdisplays_flush ();
  456. }
  457.  
  458. /*****  View  *****/
  459.  
  460. void
  461. view_zoomin_cmd_callback (GtkWidget *widget,
  462.               gpointer   client_data)
  463. {
  464.   GDisplay *gdisp;
  465.   return_if_no_display (gdisp);
  466.  
  467.   change_scale (gdisp, ZOOMIN);
  468. }
  469.  
  470. void
  471. view_zoomout_cmd_callback (GtkWidget *widget,
  472.                gpointer   client_data)
  473. {
  474.   GDisplay *gdisp;
  475.   return_if_no_display (gdisp);
  476.  
  477.   change_scale (gdisp, ZOOMOUT);
  478. }
  479.  
  480. static void
  481. view_zoom_val (GtkWidget *widget,
  482.            gpointer   client_data,
  483.            int        val)
  484. {
  485.   GDisplay *gdisp;
  486.   return_if_no_display (gdisp);
  487.  
  488.   change_scale (gdisp, val);
  489. }
  490.  
  491. void
  492. view_zoom_16_1_cmd_callback (GtkWidget *widget,
  493.                  gpointer   client_data)
  494. {
  495.   view_zoom_val (widget, client_data, 1601);
  496. }
  497.  
  498. void
  499. view_zoom_8_1_cmd_callback (GtkWidget *widget,
  500.                 gpointer   client_data)
  501. {
  502.   view_zoom_val (widget, client_data, 801);
  503. }
  504.  
  505. void
  506. view_zoom_4_1_cmd_callback (GtkWidget *widget,
  507.                 gpointer   client_data)
  508. {
  509.   view_zoom_val (widget, client_data, 401);
  510. }
  511.  
  512. void
  513. view_zoom_2_1_cmd_callback (GtkWidget *widget,
  514.                 gpointer   client_data)
  515. {
  516.   view_zoom_val (widget, client_data, 201);
  517. }
  518.  
  519. void
  520. view_zoom_1_1_cmd_callback (GtkWidget *widget,
  521.                 gpointer   client_data)
  522. {
  523.   view_zoom_val (widget, client_data, 101);
  524. }
  525.  
  526. void
  527. view_zoom_1_2_cmd_callback (GtkWidget *widget,
  528.                 gpointer   client_data)
  529. {
  530.   view_zoom_val (widget, client_data, 102);
  531. }
  532.  
  533. void
  534. view_zoom_1_4_cmd_callback (GtkWidget *widget,
  535.                 gpointer   client_data)
  536. {
  537.   view_zoom_val (widget, client_data, 104);
  538. }
  539.  
  540. void
  541. view_zoom_1_8_cmd_callback (GtkWidget *widget,
  542.                 gpointer   client_data)
  543. {
  544.   view_zoom_val (widget, client_data, 108);
  545. }
  546.  
  547. void
  548. view_zoom_1_16_cmd_callback (GtkWidget *widget,
  549.                  gpointer   client_data)
  550. {
  551.   view_zoom_val (widget, client_data, 116);
  552. }
  553.  
  554. void
  555. view_dot_for_dot_cmd_callback (GtkWidget *widget,
  556.                    gpointer   client_data)
  557. {
  558.   GDisplay *gdisp;
  559.   return_if_no_display (gdisp);
  560.  
  561.   gdisplay_set_dot_for_dot (gdisp, GTK_CHECK_MENU_ITEM (widget)->active);
  562. }
  563.  
  564. void
  565. view_info_window_cmd_callback (GtkWidget *widget,
  566.                    gpointer   client_data)
  567. {
  568.   GDisplay *gdisp;
  569.   return_if_no_display (gdisp);
  570.  
  571.   if (!info_window_follows_mouse) 
  572.     {
  573.       if (! gdisp->window_info_dialog)
  574.     gdisp->window_info_dialog = info_window_create ((void *) gdisp);
  575.       info_window_update(gdisp);
  576.       info_dialog_popup (gdisp->window_info_dialog);
  577.     }
  578.   else
  579.     {
  580.       info_window_follow_auto();
  581.     }
  582.  
  583. }
  584.  
  585. void
  586. view_nav_window_cmd_callback (GtkWidget *widget,
  587.                   gpointer   client_data)
  588. {
  589.   GDisplay *gdisp;
  590.   return_if_no_display (gdisp);
  591.  
  592.   if (nav_window_per_display) 
  593.     {
  594.       if (! gdisp->window_nav_dialog)
  595.     gdisp->window_nav_dialog = nav_window_create ((void *) gdisp);
  596.  
  597.       nav_dialog_popup (gdisp->window_nav_dialog);
  598.     }
  599.   else
  600.     {
  601.       nav_window_follow_auto ();
  602.     }
  603. }
  604.  
  605. void
  606. view_toggle_selection_cmd_callback (GtkWidget *widget,
  607.                     gpointer   client_data)
  608. {
  609.   GDisplay *gdisp;
  610.   gint      new_val;
  611.  
  612.   return_if_no_display (gdisp);
  613.  
  614.   new_val = GTK_CHECK_MENU_ITEM (widget)->active;
  615.  
  616.   /*  hidden == TRUE corresponds to the menu toggle being FALSE  */
  617.   if (new_val == gdisp->select->hidden)
  618.     {
  619.       selection_hide (gdisp->select, (void *) gdisp);
  620.       gdisplays_flush ();
  621.     }
  622. }
  623.  
  624. void
  625. view_toggle_rulers_cmd_callback (GtkWidget *widget,
  626.                  gpointer   client_data)
  627. {
  628.   GDisplay *gdisp;
  629.   return_if_no_display (gdisp);
  630.  
  631.   if (!GTK_CHECK_MENU_ITEM (widget)->active)
  632.     {
  633.       if (GTK_WIDGET_VISIBLE (gdisp->origin))
  634.     {
  635.       gtk_widget_hide (gdisp->origin);
  636.       gtk_widget_hide (gdisp->hrule);
  637.       gtk_widget_hide (gdisp->vrule);
  638.  
  639.       gtk_widget_queue_resize (GTK_WIDGET (gdisp->origin->parent));
  640.     }
  641.     }
  642.   else
  643.     {
  644.       if (!GTK_WIDGET_VISIBLE (gdisp->origin))
  645.     {
  646.       gtk_widget_show (gdisp->origin);
  647.       gtk_widget_show (gdisp->hrule);
  648.       gtk_widget_show (gdisp->vrule);
  649.  
  650.       gtk_widget_queue_resize (GTK_WIDGET (gdisp->origin->parent));
  651.     }
  652.     }
  653. }
  654.  
  655. void
  656. view_toggle_statusbar_cmd_callback (GtkWidget *widget,
  657.                     gpointer   client_data)
  658. {
  659.   GDisplay *gdisp;
  660.   return_if_no_display (gdisp);
  661.  
  662.   if (!GTK_CHECK_MENU_ITEM (widget)->active)
  663.     {
  664.       if (GTK_WIDGET_VISIBLE (gdisp->statusarea))
  665.     gtk_widget_hide (gdisp->statusarea);
  666.     }
  667.   else
  668.     {
  669.       if (!GTK_WIDGET_VISIBLE (gdisp->statusarea))
  670.     gtk_widget_show (gdisp->statusarea);
  671.     }
  672. }
  673.  
  674. void
  675. view_toggle_guides_cmd_callback (GtkWidget *widget,
  676.                  gpointer   client_data)
  677. {
  678.   GDisplay *gdisp;
  679.   gint      old_val;
  680.  
  681.   return_if_no_display (gdisp);
  682.  
  683.   old_val = gdisp->draw_guides;
  684.   gdisp->draw_guides = GTK_CHECK_MENU_ITEM (widget)->active;
  685.  
  686.   if ((old_val != gdisp->draw_guides) && gdisp->gimage->guides)
  687.     {
  688.       gdisplay_expose_full (gdisp);
  689.       gdisplays_flush ();
  690.     }
  691. }
  692.  
  693. void
  694. view_snap_to_guides_cmd_callback (GtkWidget *widget,
  695.                   gpointer   client_data)
  696. {
  697.   GDisplay *gdisp;
  698.   return_if_no_display (gdisp);
  699.  
  700.   gdisp->snap_to_guides = GTK_CHECK_MENU_ITEM (widget)->active;
  701. }
  702.  
  703. void
  704. view_new_view_cmd_callback (GtkWidget *widget,
  705.                 gpointer   client_data)
  706. {
  707.   GDisplay *gdisp;
  708.   return_if_no_display (gdisp);
  709.  
  710.   gdisplay_new_view (gdisp);
  711. }
  712.  
  713. void
  714. view_shrink_wrap_cmd_callback (GtkWidget *widget,
  715.                    gpointer   client_data)
  716. {
  717.   GDisplay *gdisp;
  718.   return_if_no_display (gdisp);
  719.  
  720.   shrink_wrap_display (gdisp);
  721. }
  722.  
  723. /*****  Image  *****/
  724.  
  725. void
  726. image_convert_rgb_cmd_callback (GtkWidget *widget,
  727.                 gpointer   client_data)
  728. {
  729.   GDisplay *gdisp;
  730.   return_if_no_display (gdisp);
  731.  
  732.   convert_to_rgb (gdisp->gimage);
  733. }
  734.  
  735. void
  736. image_convert_grayscale_cmd_callback (GtkWidget *widget,
  737.                       gpointer   client_data)
  738. {
  739.   GDisplay *gdisp;
  740.   return_if_no_display (gdisp);
  741.  
  742.   convert_to_grayscale (gdisp->gimage);
  743. }
  744.  
  745. void
  746. image_convert_indexed_cmd_callback (GtkWidget *widget,
  747.                     gpointer   client_data)
  748. {
  749.   GDisplay *gdisp;
  750.   return_if_no_display (gdisp);
  751.  
  752.   convert_to_indexed (gdisp->gimage);
  753. }
  754.  
  755. void
  756. image_desaturate_cmd_callback (GtkWidget *widget,
  757.                    gpointer   client_data)
  758. {
  759.   GDisplay *gdisp;
  760.   return_if_no_display (gdisp);
  761.  
  762.   image_desaturate (gdisp->gimage);
  763.   gdisplays_flush ();
  764. }
  765.  
  766. void
  767. image_invert_cmd_callback (GtkWidget *widget,
  768.                gpointer   client_data)
  769. {
  770.   GDisplay *gdisp;
  771.   return_if_no_display (gdisp);
  772.  
  773.   image_invert (gdisp->gimage);
  774.   gdisplays_flush ();
  775. }
  776.  
  777. void
  778. image_equalize_cmd_callback (GtkWidget *widget,
  779.                  gpointer   client_data)
  780. {
  781.   GDisplay *gdisp;
  782.   return_if_no_display (gdisp);
  783.  
  784.   image_equalize (gdisp->gimage);
  785.   gdisplays_flush ();
  786. }
  787.  
  788. void
  789. image_offset_cmd_callback (GtkWidget *widget,
  790.                gpointer   client_data)
  791. {
  792.   GDisplay *gdisp;
  793.   return_if_no_display (gdisp);
  794.  
  795.   channel_ops_offset (gdisp->gimage);
  796. }
  797.  
  798. void
  799. image_resize_cmd_callback (GtkWidget *widget,
  800.                gpointer   client_data)
  801. {
  802.   GDisplay    *gdisp;
  803.   GimpImage   *gimage;
  804.   ImageResize *image_resize;
  805.  
  806.   return_if_no_display (gdisp);
  807.  
  808.   gimage = gdisp->gimage;
  809.  
  810.   /*  the ImageResize structure  */
  811.   image_resize = g_new (ImageResize, 1);
  812.   image_resize->gimage = gimage;
  813.   image_resize->resize = resize_widget_new (ResizeWidget,
  814.                         ResizeImage,
  815.                         GTK_OBJECT (gimage),
  816.                         "destroy",
  817.                         gimage->width,
  818.                         gimage->height,
  819.                         gimage->xresolution,
  820.                         gimage->yresolution,
  821.                         gimage->unit,
  822.                         gdisp->dot_for_dot,
  823.                         image_resize_callback,
  824.                         NULL,
  825.                         image_resize);
  826.  
  827.   gtk_signal_connect_object (GTK_OBJECT (image_resize->resize->resize_shell),
  828.                  "destroy",
  829.                  GTK_SIGNAL_FUNC (g_free),
  830.                  (GtkObject *) image_resize);
  831.  
  832.   gtk_widget_show (image_resize->resize->resize_shell);
  833. }
  834.  
  835. void
  836. image_scale_cmd_callback (GtkWidget *widget,
  837.               gpointer   client_data)
  838. {
  839.   GDisplay    *gdisp;
  840.   GimpImage   *gimage;
  841.   ImageResize *image_scale;
  842.  
  843.   return_if_no_display (gdisp);
  844.  
  845.   gimage = gdisp->gimage;
  846.  
  847.   /*  the ImageResize structure  */
  848.   image_scale = g_new (ImageResize, 1);
  849.   image_scale->gimage = gimage;
  850.   image_scale->resize = resize_widget_new (ScaleWidget,
  851.                        ResizeImage,
  852.                        GTK_OBJECT (gimage),
  853.                        "destroy",
  854.                        gimage->width,
  855.                        gimage->height,
  856.                        gimage->xresolution,
  857.                        gimage->yresolution,
  858.                        gimage->unit,
  859.                        gdisp->dot_for_dot,
  860.                        image_scale_callback,
  861.                        NULL,
  862.                        image_scale);
  863.  
  864.   gtk_signal_connect_object (GTK_OBJECT (image_scale->resize->resize_shell),
  865.                  "destroy",
  866.                  GTK_SIGNAL_FUNC (g_free),
  867.                  (GtkObject *) image_scale);
  868.  
  869.   gtk_widget_show (image_scale->resize->resize_shell);
  870. }
  871.  
  872. void
  873. image_duplicate_cmd_callback (GtkWidget *widget,
  874.                   gpointer   client_data)
  875. {
  876.   GDisplay *gdisp;
  877.   return_if_no_display (gdisp);
  878.  
  879.   channel_ops_duplicate (gdisp->gimage);
  880. }
  881.  
  882. /*****  Layers  *****/
  883.  
  884. void
  885. layers_previous_cmd_callback (GtkWidget *widget,
  886.                   gpointer   client_data)
  887. {
  888.   GDisplay *gdisp;
  889.   Layer    *new_layer;
  890.   gint      current_layer;
  891.  
  892.   return_if_no_display (gdisp);
  893.  
  894.   current_layer =
  895.     gimage_get_layer_index (gdisp->gimage, gdisp->gimage->active_layer);
  896.  
  897.   /*  FIXME: don't use internal knowledge about layer lists
  898.    *  TODO : implement gimage_get_layer_by_index()
  899.    */
  900.   new_layer =
  901.     (Layer *) g_slist_nth_data (gdisp->gimage->layers, current_layer - 1);
  902.  
  903.   if (new_layer)
  904.     {
  905.       gimage_set_active_layer (gdisp->gimage, new_layer);
  906.       gdisplays_flush ();
  907.     }
  908. }
  909.  
  910. void
  911. layers_next_cmd_callback (GtkWidget *widget,
  912.               gpointer   client_data)
  913. {
  914.   GDisplay *gdisp;
  915.   Layer    *new_layer;
  916.   gint      current_layer;
  917.  
  918.   return_if_no_display (gdisp);
  919.  
  920.   current_layer =
  921.     gimage_get_layer_index (gdisp->gimage, gdisp->gimage->active_layer);
  922.  
  923.   /*  FIXME: don't use internal knowledge about layer lists
  924.    *  TODO : implement gimage_get_layer_by_index()
  925.    */
  926.   new_layer =
  927.     (Layer *) g_slist_nth_data (gdisp->gimage->layers, current_layer + 1);
  928.  
  929.   if (new_layer)
  930.     {
  931.       gimage_set_active_layer (gdisp->gimage, new_layer);
  932.       gdisplays_flush ();
  933.     }
  934. }
  935.  
  936. void
  937. layers_raise_cmd_callback (GtkWidget *widget,
  938.                gpointer   client_data)
  939. {
  940.   GDisplay *gdisp;
  941.   return_if_no_display (gdisp);
  942.  
  943.   gimage_raise_layer (gdisp->gimage, gdisp->gimage->active_layer);
  944.   gdisplays_flush ();
  945. }
  946.  
  947. void
  948. layers_lower_cmd_callback (GtkWidget *widget,
  949.                gpointer   client_data)
  950. {
  951.   GDisplay *gdisp;
  952.   return_if_no_display (gdisp);
  953.  
  954.   gimage_lower_layer (gdisp->gimage, gdisp->gimage->active_layer);
  955.   gdisplays_flush ();
  956. }
  957.  
  958. void
  959. layers_raise_to_top_cmd_callback (GtkWidget *widget,
  960.                   gpointer   client_data)
  961. {
  962.   GDisplay *gdisp;
  963.   return_if_no_display (gdisp);
  964.  
  965.   gimage_raise_layer_to_top (gdisp->gimage, gdisp->gimage->active_layer);
  966.   gdisplays_flush ();
  967. }
  968.  
  969. void
  970. layers_lower_to_bottom_cmd_callback (GtkWidget *widget,
  971.                      gpointer   client_data)
  972. {
  973.   GDisplay *gdisp;
  974.   return_if_no_display (gdisp);
  975.  
  976.   gimage_lower_layer_to_bottom (gdisp->gimage, gdisp->gimage->active_layer);
  977.   gdisplays_flush ();
  978. }
  979.  
  980. void
  981. layers_anchor_cmd_callback (GtkWidget *widget,
  982.                 gpointer   client_data)
  983. {
  984.   GDisplay *gdisp;
  985.   return_if_no_display (gdisp);
  986.  
  987.   floating_sel_anchor (gimage_get_active_layer (gdisp->gimage));
  988.   gdisplays_flush ();
  989. }
  990.  
  991. void
  992. layers_merge_cmd_callback (GtkWidget *widget,
  993.                gpointer   client_data)
  994. {
  995.   GDisplay *gdisp;
  996.   return_if_no_display (gdisp);
  997.  
  998.   layers_dialog_layer_merge_query (gdisp->gimage, TRUE);
  999. }
  1000.  
  1001. void
  1002. layers_flatten_cmd_callback (GtkWidget *widget,
  1003.                  gpointer   client_data)
  1004. {
  1005.   GDisplay *gdisp;
  1006.   return_if_no_display (gdisp);
  1007.  
  1008.   gimage_flatten (gdisp->gimage);
  1009.   gdisplays_flush ();
  1010. }
  1011.  
  1012. void
  1013. layers_mask_select_cmd_callback (GtkWidget *widget,
  1014.                  gpointer   client_data)
  1015. {
  1016.   GDisplay *gdisp;
  1017.   return_if_no_display (gdisp);
  1018.  
  1019.   gimage_mask_layer_mask (gdisp->gimage, gdisp->gimage->active_layer);
  1020.   gdisplays_flush ();
  1021. }
  1022.  
  1023. void
  1024. layers_add_alpha_channel_cmd_callback (GtkWidget *widget,
  1025.                        gpointer   client_data)
  1026. {
  1027.   GDisplay *gdisp;
  1028.   return_if_no_display (gdisp);
  1029.  
  1030.   layer_add_alpha ( gdisp->gimage->active_layer);
  1031.   gdisplays_flush ();
  1032. }
  1033.  
  1034. void
  1035. layers_alpha_select_cmd_callback (GtkWidget *widget,
  1036.                   gpointer   client_data)
  1037. {
  1038.   GDisplay *gdisp;
  1039.   return_if_no_display (gdisp);
  1040.  
  1041.   gimage_mask_layer_alpha (gdisp->gimage, gdisp->gimage->active_layer);
  1042.   gdisplays_flush ();
  1043. }
  1044.  
  1045. void
  1046. layers_resize_to_image_cmd_callback (GtkWidget *widget,
  1047.                      gpointer   client_data)
  1048. {
  1049.   GDisplay *gdisp;
  1050.   return_if_no_display (gdisp);
  1051.  
  1052.   layer_resize_to_image (gdisp->gimage->active_layer);
  1053.   gdisplays_flush ();
  1054. }
  1055.  
  1056. /*****  Tools  *****/
  1057.  
  1058. void
  1059. tools_default_colors_cmd_callback (GtkWidget *widget,
  1060.                    gpointer   client_data)
  1061. {
  1062.   gimp_context_set_default_colors (gimp_context_get_user ());
  1063. }
  1064.  
  1065. void
  1066. tools_swap_colors_cmd_callback (GtkWidget *widget,
  1067.                 gpointer   client_data)
  1068. {
  1069.   gimp_context_swap_colors (gimp_context_get_user ());
  1070. }
  1071.  
  1072. void
  1073. tools_select_cmd_callback (GtkWidget *widget,
  1074.                gpointer   callback_data,
  1075.                guint      callback_action)
  1076. {
  1077.   ToolType  tool_type;
  1078.   GDisplay *gdisp;
  1079.   gdisp = gdisplay_active ();
  1080.  
  1081.   tool_type = (ToolType) callback_action;
  1082.  
  1083.   gimp_context_set_tool (gimp_context_get_user (), tool_type);
  1084.  
  1085.   /*  Paranoia  */
  1086.   active_tool->drawable = NULL;
  1087.  
  1088.   /*  Complete the initialisation by doing the same stuff
  1089.    *  tools_initialize() does after it did what tools_select() does
  1090.    */
  1091.   if (tool_info[tool_type].init_func)
  1092.     {
  1093.       (* tool_info[tool_type].init_func) (gdisp);
  1094.  
  1095.       active_tool->drawable = gimage_active_drawable (gdisp->gimage);
  1096.     }
  1097.  
  1098.   /*  setting the gdisp_ptr here is a HACK to allow the tools'
  1099.    *  dialog windows being hidden if the tool was selected from
  1100.    *  a tear-off-menu and there was no mouse click in the display
  1101.    *  before deleting it
  1102.    */
  1103.   active_tool->gdisp_ptr = gdisp;
  1104. }
  1105.  
  1106. /*****  Filters  *****/
  1107.  
  1108. void
  1109. filters_repeat_cmd_callback (GtkWidget *widget,
  1110.                  gpointer   callback_data,
  1111.                  guint      callback_action)
  1112. {
  1113.   plug_in_repeat (callback_action);
  1114. }
  1115.  
  1116. /*****  Dialogs  ******/
  1117.  
  1118. void
  1119. dialogs_lc_cmd_callback (GtkWidget *widget,
  1120.              gpointer   client_data)
  1121. {
  1122.   GDisplay *gdisp;
  1123.   gdisp = gdisplay_active ();
  1124.  
  1125.   lc_dialog_create (gdisp ? gdisp->gimage : NULL);
  1126. }
  1127.  
  1128. void
  1129. dialogs_tool_options_cmd_callback (GtkWidget *widget,
  1130.                    gpointer   client_data)
  1131. {
  1132.   tool_options_dialog_show ();
  1133. }
  1134.  
  1135. void
  1136. dialogs_brushes_cmd_callback (GtkWidget *widget,
  1137.                   gpointer   client_data)
  1138. {
  1139.   brush_dialog_create ();
  1140. }
  1141.  
  1142. void
  1143. dialogs_patterns_cmd_callback (GtkWidget *widget,
  1144.                    gpointer   client_data)
  1145. {
  1146.   pattern_dialog_create ();
  1147. }
  1148.  
  1149. void
  1150. dialogs_gradients_cmd_callback (GtkWidget *widget,
  1151.                 gpointer   client_data)
  1152. {
  1153.   gradient_dialog_create ();
  1154. }
  1155.  
  1156. void
  1157. dialogs_palette_cmd_callback (GtkWidget *widget,
  1158.                   gpointer   client_data)
  1159. {
  1160.   palette_dialog_create ();
  1161. }
  1162.  
  1163. static void
  1164. dialogs_indexed_palette_select_callback (ColormapDialog *dialog,
  1165.                      gpointer        data)
  1166. {
  1167.   guchar    *color;
  1168.   GimpImage *image = colormap_dialog_image (dialog);
  1169.  
  1170.   color = &image->cmap[colormap_dialog_col_index (dialog) * 3];
  1171.  
  1172.   if (active_color == FOREGROUND)
  1173.     gimp_context_set_foreground (gimp_context_get_user (),
  1174.                  color[0], color[1], color[2]);
  1175.   else if (active_color == BACKGROUND)
  1176.     gimp_context_set_background (gimp_context_get_user (),
  1177.                  color[0], color[1], color[2]);
  1178. }
  1179.  
  1180. void
  1181. dialogs_indexed_palette_cmd_callback (GtkWidget *widget,
  1182.                       gpointer   client_data)
  1183. {
  1184.   static ColormapDialog *cmap_dlg;
  1185.  
  1186.   if (!cmap_dlg)
  1187.     {
  1188.       cmap_dlg = colormap_dialog_create (image_context);
  1189.       colormap_dialog_connect_selected (dialogs_indexed_palette_select_callback,
  1190.                     NULL, cmap_dlg);
  1191.     }
  1192.  
  1193.   gtk_widget_show (GTK_WIDGET (cmap_dlg));
  1194. }
  1195.  
  1196. void
  1197. dialogs_input_devices_cmd_callback (GtkWidget *widget,
  1198.                     gpointer   client_data)
  1199. {
  1200.   input_dialog_create ();
  1201. }
  1202.  
  1203. void
  1204. dialogs_device_status_cmd_callback (GtkWidget *widget,
  1205.                     gpointer   client_data)
  1206. {
  1207.   device_status_create ();
  1208. }
  1209.  
  1210. void
  1211. dialogs_document_index_cmd_callback (GtkWidget *widget,
  1212.                      gpointer   client_data) 
  1213. {
  1214.   document_index_create ();
  1215. }
  1216.  
  1217. void
  1218. dialogs_error_console_cmd_callback (GtkWidget *widget,
  1219.                     gpointer   client_data) 
  1220. {
  1221.   error_console_add (NULL);
  1222. }
  1223.  
  1224. #ifdef DISPLAY_FILTERS
  1225. void
  1226. dialogs_display_filters_cmd_callback (GtkWidget *widget,
  1227.                       gpointer   client_data)
  1228. {
  1229.   GDisplay *gdisp;
  1230.  
  1231.   gdisp = gdisplay_active ();
  1232.   if (!gdisp)
  1233.     gdisp = color_area_gdisp;
  1234.  
  1235.   if (!gdisp->cd_ui)
  1236.     gdisplay_color_ui_new (gdisp);
  1237.  
  1238.   if (!GTK_WIDGET_VISIBLE (gdisp->cd_ui))
  1239.     gtk_widget_show (gdisp->cd_ui);
  1240.   else
  1241.     gdk_window_raise (gdisp->cd_ui->window);
  1242. }
  1243. #endif /* DISPLAY_FILTERS */
  1244.  
  1245. void
  1246. dialogs_undo_history_cmd_callback (GtkWidget *widget,
  1247.                    gpointer   client_data)
  1248. {
  1249.   GDisplay *gdisp;
  1250.   GImage   *gimage;
  1251.   return_if_no_display (gdisp);
  1252.  
  1253.   gimage = gdisp->gimage;
  1254.  
  1255.   if (!gimage->undo_history)
  1256.     gimage->undo_history = undo_history_new (gimage);
  1257.  
  1258.   if (!GTK_WIDGET_VISIBLE (gimage->undo_history))
  1259.     gtk_widget_show (gimage->undo_history);
  1260.   else
  1261.     gdk_window_raise (gimage->undo_history->window);
  1262. }
  1263.  
  1264. void
  1265. dialogs_module_browser_cmd_callback (GtkWidget *widget,
  1266.                      gpointer   client_data)
  1267. {
  1268.   GtkWidget *module_browser;
  1269.  
  1270.   module_browser = module_db_browser_new ();
  1271.   gtk_widget_show (module_browser);
  1272. }
  1273.  
  1274. /*****  Help  *****/
  1275.  
  1276. void
  1277. help_help_cmd_callback (GtkWidget *widget,
  1278.             gpointer   client_data)
  1279. {
  1280.   gimp_standard_help_func (NULL);
  1281. }
  1282.  
  1283. void
  1284. help_context_help_cmd_callback (GtkWidget *widget,
  1285.                 gpointer   client_data)
  1286. {
  1287.   gimp_context_help ();
  1288. }
  1289.  
  1290. void
  1291. help_tips_cmd_callback (GtkWidget *widget,
  1292.             gpointer   client_data)
  1293. {
  1294.   tips_dialog_create ();
  1295. }
  1296.  
  1297. void
  1298. help_about_cmd_callback (GtkWidget *widget,
  1299.              gpointer   client_data)
  1300. {
  1301.   about_dialog_create ();
  1302. }
  1303.  
  1304.  
  1305. /*****************************/
  1306. /*****  Local functions  *****/
  1307. /*****************************/
  1308.  
  1309. static void
  1310. image_resize_callback (GtkWidget *widget,
  1311.                gpointer   client_data)
  1312. {
  1313.   ImageResize *image_resize;
  1314.   GImage      *gimage;
  1315.  
  1316.   image_resize = (ImageResize *) client_data;
  1317.  
  1318.   gtk_widget_set_sensitive (image_resize->resize->resize_shell, FALSE);
  1319.  
  1320.   if ((gimage = image_resize->gimage) != NULL)
  1321.     {
  1322.       if (image_resize->resize->width > 0 &&
  1323.       image_resize->resize->height > 0) 
  1324.     {
  1325.       gimage_resize (gimage,
  1326.              image_resize->resize->width,
  1327.              image_resize->resize->height,
  1328.              image_resize->resize->offset_x,
  1329.              image_resize->resize->offset_y);
  1330.       gdisplays_flush ();
  1331.       lc_dialog_update_image_list ();
  1332.     }
  1333.       else 
  1334.     {
  1335.       g_message (_("Resize Error: Both width and height must be "
  1336.                "greater than zero."));
  1337.       return;
  1338.     }
  1339.     }
  1340.  
  1341.   gtk_widget_destroy (image_resize->resize->resize_shell);
  1342. }
  1343.  
  1344. static void
  1345. image_scale_callback (GtkWidget *widget,
  1346.               gpointer   client_data)
  1347. {
  1348.   ImageResize *image_scale = NULL;
  1349.  
  1350.   g_assert ((image_scale = (ImageResize *) client_data) != NULL);
  1351.   g_assert (image_scale->gimage != NULL);
  1352.  
  1353.   gtk_widget_set_sensitive (image_scale->resize->resize_shell, FALSE);
  1354.  
  1355.   if (resize_check_layer_scaling (image_scale))
  1356.     {
  1357.       resize_scale_implement (image_scale);
  1358.       gtk_widget_destroy (image_scale->resize->resize_shell);
  1359.     }
  1360. }
  1361.  
  1362. static void
  1363. gimage_mask_feather_callback (GtkWidget *widget,
  1364.                   gdouble    size,
  1365.                   GimpUnit   unit,
  1366.                   gpointer   data)
  1367. {
  1368.   GImage  *gimage;
  1369.   gdouble  radius_x;
  1370.   gdouble  radius_y;
  1371.  
  1372.   gimage = GIMP_IMAGE (data);
  1373.  
  1374.   selection_feather_radius = size;
  1375.  
  1376.   radius_x = radius_y = selection_feather_radius;
  1377.  
  1378.   if (unit != GIMP_UNIT_PIXEL)
  1379.     {
  1380.       gdouble factor;
  1381.  
  1382.       factor = (MAX (gimage->xresolution, gimage->yresolution) /
  1383.         MIN (gimage->xresolution, gimage->yresolution));
  1384.  
  1385.       if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
  1386.     radius_y *= factor;
  1387.       else
  1388.     radius_x *= factor;
  1389.     }
  1390.  
  1391.   gimage_mask_feather (gimage, radius_x, radius_y);
  1392.   gdisplays_flush ();
  1393. }
  1394.  
  1395. static void
  1396. gimage_mask_border_callback (GtkWidget *widget,
  1397.                  gdouble    size,
  1398.                  GimpUnit   unit,
  1399.                  gpointer   data)
  1400. {
  1401.   GImage  *gimage;
  1402.   gdouble  radius_x;
  1403.   gdouble  radius_y;
  1404.  
  1405.   gimage = GIMP_IMAGE (data);
  1406.  
  1407.   selection_border_radius = ROUND (size);
  1408.  
  1409.   radius_x = radius_y = selection_border_radius;
  1410.  
  1411.   if (unit != GIMP_UNIT_PIXEL)
  1412.     {
  1413.       gdouble factor;
  1414.  
  1415.       factor = (MAX (gimage->xresolution, gimage->yresolution) /
  1416.         MIN (gimage->xresolution, gimage->yresolution));
  1417.  
  1418.       if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
  1419.     radius_y *= factor;
  1420.       else
  1421.     radius_x *= factor;
  1422.     }
  1423.  
  1424.   gimage_mask_border (gimage, radius_x, radius_y);
  1425.   gdisplays_flush ();
  1426. }
  1427.  
  1428. static void
  1429. gimage_mask_grow_callback (GtkWidget *widget,
  1430.                gdouble    size,
  1431.                GimpUnit   unit,
  1432.                gpointer   data)
  1433. {
  1434.   GImage  *gimage;
  1435.   gdouble  radius_x;
  1436.   gdouble  radius_y;
  1437.  
  1438.   gimage = GIMP_IMAGE (data);
  1439.  
  1440.   selection_grow_pixels = ROUND (size);
  1441.  
  1442.   radius_x = radius_y = selection_grow_pixels;
  1443.  
  1444.   if (unit != GIMP_UNIT_PIXEL)
  1445.     {
  1446.       gdouble factor;
  1447.  
  1448.       factor = (MAX (gimage->xresolution, gimage->yresolution) /
  1449.         MIN (gimage->xresolution, gimage->yresolution));
  1450.  
  1451.       if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
  1452.     radius_y *= factor;
  1453.       else
  1454.     radius_x *= factor;
  1455.     }
  1456.  
  1457.   gimage_mask_grow (gimage, radius_x, radius_y);
  1458.   gdisplays_flush ();
  1459. }
  1460.  
  1461. static void
  1462. gimage_mask_shrink_callback (GtkWidget *widget,
  1463.                  gdouble    size,
  1464.                  GimpUnit   unit,
  1465.                  gpointer   data)
  1466. {
  1467.   GImage *gimage;
  1468.   gint    radius_x;
  1469.   gint    radius_y;
  1470.  
  1471.   gimage = GIMP_IMAGE (data);
  1472.  
  1473.   selection_shrink_pixels = ROUND (size);
  1474.  
  1475.   radius_x = radius_y = selection_shrink_pixels;
  1476.  
  1477.   selection_shrink_edge_lock =
  1478.     ! GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (widget),
  1479.                           "edge_lock_toggle"))->active;
  1480.  
  1481.   if (unit != GIMP_UNIT_PIXEL)
  1482.     {
  1483.       gdouble factor;
  1484.  
  1485.       factor = (MAX (gimage->xresolution, gimage->yresolution) /
  1486.         MIN (gimage->xresolution, gimage->yresolution));
  1487.  
  1488.       if (gimage->xresolution == MIN (gimage->xresolution, gimage->yresolution))
  1489.     radius_y *= factor;
  1490.       else
  1491.     radius_x *= factor;
  1492.     }
  1493.  
  1494.   gimage_mask_shrink (gimage, radius_x, radius_y, selection_shrink_edge_lock);
  1495.   gdisplays_flush ();
  1496. }
  1497.