home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / illusion.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-01  |  17.9 KB  |  652 lines

  1. /*
  2.  * illusion.c  -- This is a plug-in for the GIMP 1.0
  3.  *                                                                              
  4.  * Copyright (C) 1997  Hirotsuna Mizuno
  5.  *                     s1041150@u-aizu.ac.jp
  6.  *
  7.  * Preview and new mode added May 2000 by tim copperfield
  8.  *                timecop@japan.co.jp
  9.  *                http://www.ne.jp/asahi/linux/timecop
  10.  *                                                                              
  11.  * This program is free software; you can redistribute it and/or modify it
  12.  * under the terms of the GNU General Public License as published by the Free
  13.  * Software Foundation; either version 2 of the License, or (at your option)
  14.  * any later version.
  15.  *                                                                              
  16.  * This program is distributed in the hope that it will be useful, but WITHOUT
  17.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  18.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  19.  * more details.
  20.  *                                                                              
  21.  * You should have received a copy of the GNU General Public License along with
  22.  * this program; if not, write to the Free Software Foundation, Inc.,
  23.  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  */
  26.  
  27. #include "config.h"
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32.  
  33. #include <gtk/gtk.h>
  34.  
  35. #include <libgimp/gimp.h>
  36. #include <libgimp/gimpui.h>
  37.  
  38. #include "libgimp/stdplugins-intl.h"
  39.  
  40.  
  41. #define PLUG_IN_NAME    "plug_in_illusion"
  42. #define PLUG_IN_VERSION "v0.8 (May 14 2000)"
  43.  
  44. #define PREVIEW_SIZE    128 
  45.  
  46. /******************************************************************************/
  47.  
  48. static void      query  (void);
  49. static void      run    (gchar   *name,
  50.              gint     nparam,
  51.              GimpParam  *param,
  52.              gint    *nreturn_vals,
  53.              GimpParam **return_vals);
  54.  
  55. static void      filter                  (GimpDrawable *drawable);
  56. static void      filter_preview          (void);
  57. static void      fill_preview_with_thumb (GtkWidget *preview_widget, 
  58.                       gint32     drawable_ID);
  59. static gboolean  dialog                  (GimpDrawable *drawable);
  60.  
  61. /******************************************************************************/
  62.  
  63. typedef struct
  64. {
  65.   gint32 division;
  66.   gint   type1;
  67.   gint   type2;
  68. } IllValues;
  69.  
  70. /******************************************************************************/
  71.  
  72. GimpPlugInInfo PLUG_IN_INFO =
  73. {
  74.   NULL,  /* init_proc  */
  75.   NULL,  /* quit_proc  */
  76.   query, /* query_proc */
  77.   run    /* run_proc   */
  78. };
  79.  
  80. static IllValues parameters =
  81. {
  82.   8, /* division */
  83.   1, /* type 1 */
  84.   0  /* type 2 */
  85. };
  86.  
  87.  
  88. static GtkWidget *preview;
  89. static guchar    *preview_cache;
  90. static gint       preview_cache_rowstride;
  91. static gint       preview_cache_bpp;
  92.  
  93. /******************************************************************************/
  94.  
  95. MAIN ()
  96.  
  97. /******************************************************************************/
  98.  
  99. static void
  100. query (void)
  101. {
  102.   static GimpParamDef args[] =
  103.   {
  104.     { GIMP_PDB_INT32,    "run_mode",  "interactive / non-interactive" },
  105.     { GIMP_PDB_IMAGE,    "image",     "input image" },
  106.     { GIMP_PDB_DRAWABLE, "drawable",  "input drawable" },
  107.     { GIMP_PDB_INT32,    "division",  "the number of divisions" }
  108.   };
  109.   static gint nargs = sizeof (args) / sizeof (args[0]);;
  110.  
  111.   gimp_install_procedure (PLUG_IN_NAME,
  112.               "produce illusion",
  113.               "produce illusion",
  114.               "Hirotsuna Mizuno <s1041150@u-aizu.ac.jp>",
  115.               "Hirotsuna Mizuno",
  116.               PLUG_IN_VERSION,
  117.               N_("<Image>/Filters/Map/Illusion..."),
  118.               "RGB*, GRAY*",
  119.               GIMP_PLUGIN,
  120.               nargs, 0,
  121.               args, NULL);
  122. }
  123.  
  124. /******************************************************************************/
  125.  
  126. static void
  127. run (gchar   *name,
  128.      gint     nparams,
  129.      GimpParam  *params,
  130.      gint    *nreturn_vals,
  131.      GimpParam **return_vals)
  132. {
  133.   GimpDrawable     *drawable;
  134.   GimpRunModeType   run_mode;
  135.   static GimpParam  returnv[1];
  136.   GimpPDBStatusType    status = GIMP_PDB_SUCCESS;
  137.  
  138.   run_mode = params[0].data.d_int32;
  139.   drawable = gimp_drawable_get (params[2].data.d_drawable);
  140.   *nreturn_vals = 1;
  141.   *return_vals  = returnv;
  142.  
  143.   /* get the drawable info */
  144.  
  145.   /* switch the run mode */
  146.   switch (run_mode)
  147.     {
  148.     case GIMP_RUN_INTERACTIVE:
  149.       INIT_I18N_UI();
  150.       gimp_get_data (PLUG_IN_NAME, ¶meters);
  151.       if (! dialog(drawable))
  152.     return;
  153.       gimp_set_data (PLUG_IN_NAME, ¶meters, sizeof (IllValues));
  154.       g_free(preview_cache);
  155.       break;
  156.  
  157.     case GIMP_RUN_NONINTERACTIVE:
  158.       if (nparams != 6)
  159.     {
  160.       status = GIMP_PDB_CALLING_ERROR;
  161.     }
  162.       else
  163.     {
  164.       parameters.division = params[3].data.d_int32;
  165.           parameters.type1 = params[4].data.d_int32;
  166.       parameters.type2 = params[5].data.d_int32;
  167.     }
  168.       break;
  169.  
  170.     case GIMP_RUN_WITH_LAST_VALS:
  171.       gimp_get_data (PLUG_IN_NAME, ¶meters);
  172.       break;
  173.     }
  174.  
  175.   if (status == GIMP_PDB_SUCCESS)
  176.     {
  177.       if (gimp_drawable_is_rgb (drawable->id) || 
  178.       gimp_drawable_is_gray (drawable->id))
  179.     {
  180.       gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width() + 1));
  181.         gimp_progress_init (_("Illusion..."));
  182.       filter (drawable);
  183.       if (run_mode != GIMP_RUN_NONINTERACTIVE)
  184.         gimp_displays_flush ();
  185.     }
  186.       else
  187.     {
  188.       status = GIMP_PDB_EXECUTION_ERROR;
  189.     }
  190.     }
  191.  
  192.   returnv[0].type          = GIMP_PDB_STATUS;
  193.   returnv[0].data.d_status = status;
  194.  
  195.   gimp_drawable_detach (drawable);
  196. }
  197.  
  198. /******************************************************************************/
  199.  
  200. static void
  201. filter (GimpDrawable *drawable)
  202. {
  203.   GimpPixelRgn srcPR, destPR;
  204.   guchar  **pixels;
  205.   guchar  **destpixels;
  206.   
  207.   gint    image_width;
  208.   gint    image_height;
  209.   gint    image_bpp;
  210.   gint    image_has_alpha;
  211.   gint    x1;
  212.   gint    y1;
  213.   gint    x2;
  214.   gint    y2;
  215.   gint    select_width;
  216.   gint    select_height;
  217.   gdouble center_x;
  218.   gdouble center_y;
  219.  
  220.   gint      x, y, b;
  221.   gint      xx = 0;
  222.   gint      yy = 0;
  223.   gdouble   scale, radius, cx, cy, angle, offset;
  224.  
  225.   image_width     = gimp_drawable_width (drawable->id);
  226.   image_height    = gimp_drawable_height (drawable->id);
  227.   image_bpp       = gimp_drawable_bpp (drawable->id);
  228.   image_has_alpha = gimp_drawable_has_alpha (drawable->id);
  229.   gimp_drawable_mask_bounds (drawable->id,&x1, &y1, &x2, &y2);
  230.   select_width    = x2 - x1;
  231.   select_height   = y2 - y1;
  232.   center_x        = x1 + (gdouble)select_width / 2;
  233.   center_y        = y1 + (gdouble)select_height / 2;
  234.   
  235.   gimp_pixel_rgn_init (&srcPR, drawable,
  236.                0, 0, image_width, image_height, FALSE, FALSE);
  237.   gimp_pixel_rgn_init (&destPR, drawable,
  238.                0, 0, image_width, image_height, TRUE, TRUE);
  239.  
  240.   pixels     = g_new (guchar *, image_height);
  241.   destpixels = g_new (guchar *, image_height);
  242.  
  243.   for (y = 0; y < image_height; y++)
  244.     {
  245.       pixels[y]     = g_new (guchar, image_width * image_bpp);
  246.       destpixels[y] = g_new (guchar, image_width * image_bpp);
  247.       gimp_pixel_rgn_get_row (&srcPR, pixels[y], 0, y, image_width);
  248.     }
  249.  
  250.   scale = sqrt (select_width * select_width + select_height * select_height) / 2;
  251.   offset = (gint) (scale / 2);
  252.  
  253.   for (y = y1; y < y2; y++)
  254.     {
  255.       cy = ((gdouble)y - center_y) / scale; 
  256.       for (x = x1; x < x2; x++)
  257.     {
  258.       cx = ((gdouble)x - center_x) / scale;
  259.       angle = floor (atan2 (cy, cx) * parameters.division / G_PI_2)
  260.         * G_PI_2 / parameters.division + (G_PI / parameters.division);
  261.       radius = sqrt ((gdouble) (cx * cx + cy * cy));
  262.  
  263.       if (parameters.type1) 
  264.         {
  265.           xx = x - offset * cos (angle);
  266.           yy = y - offset * sin (angle);
  267.         }
  268.  
  269.       if (parameters.type2) 
  270.         {
  271.           xx = x - offset * sin (angle);
  272.           yy = y - offset * cos (angle);
  273.         }
  274.  
  275.       if (xx < 0) 
  276.         xx = 0;
  277.       else if (image_width <= xx) 
  278.         xx = image_width - 1;
  279.  
  280.       if (yy < 0) 
  281.         yy = 0;
  282.       else if (image_height <= yy) 
  283.         yy = image_height - 1;
  284.  
  285.       for (b = 0; b < image_bpp; b++)
  286.         destpixels[y][x*image_bpp+b] =
  287.           (1-radius) * pixels[y][x * image_bpp + b] 
  288.           + radius * pixels[yy][xx * image_bpp + b];
  289.     }
  290.       gimp_pixel_rgn_set_row (&destPR, destpixels[y], 0, y, image_width);
  291.       gimp_progress_update ((double) (y - y1) / (double) select_height);
  292.     }
  293.  
  294.   gimp_drawable_flush (drawable);
  295.   gimp_drawable_merge_shadow (drawable->id, TRUE);
  296.   gimp_drawable_update (drawable->id,
  297.             x1, y1, select_width, select_height);
  298.  
  299.   for (y = y1; y < y2; y++) g_free (pixels[y-y1]);
  300.   g_free (pixels);
  301.   for (y = y1; y < y2; y++) g_free (destpixels[y-y1]);
  302.   g_free (destpixels);
  303. }
  304.  
  305. static void
  306. preview_do_row(gint    row,
  307.            gint    width,
  308.            guchar *even,
  309.            guchar *odd,
  310.            guchar *src)
  311. {
  312.   gint    x;
  313.   
  314.   guchar *p0 = even;
  315.   guchar *p1 = odd;
  316.   
  317.   gdouble    r, g, b, a;
  318.   gdouble    c0, c1;
  319.   
  320.   for (x = 0; x < width; x++) 
  321.     {
  322.       if (preview_cache_bpp == 4)
  323.     {
  324.       r = ((gdouble)src[x*4+0]) / 255.0;
  325.       g = ((gdouble)src[x*4+1]) / 255.0;
  326.       b = ((gdouble)src[x*4+2]) / 255.0;
  327.       a = ((gdouble)src[x*4+3]) / 255.0;
  328.     }
  329.       else if (preview_cache_bpp == 3)
  330.     {
  331.       r = ((gdouble)src[x*3+0]) / 255.0;
  332.       g = ((gdouble)src[x*3+1]) / 255.0;
  333.       b = ((gdouble)src[x*3+2]) / 255.0;
  334.       a = 1.0;
  335.     }
  336.       else
  337.     {
  338.       r = ((gdouble)src[x*preview_cache_bpp+0]) / 255.0;
  339.       g = b = r;
  340.       if (preview_cache_bpp == 2)
  341.             a = ((gdouble)src[x*preview_cache_bpp+1]) / 255.0;
  342.       else
  343.         a = 1.0;
  344.     }
  345.       
  346.       if ((x / GIMP_CHECK_SIZE) & 1) 
  347.     {
  348.       c0 = GIMP_CHECK_LIGHT;
  349.       c1 = GIMP_CHECK_DARK;
  350.     } 
  351.       else 
  352.     {
  353.       c0 = GIMP_CHECK_DARK;
  354.       c1 = GIMP_CHECK_LIGHT;
  355.     }
  356.       
  357.       *p0++ = (c0 + (r - c0) * a) * 255.0;
  358.       *p0++ = (c0 + (g - c0) * a) * 255.0;
  359.       *p0++ = (c0 + (b - c0) * a) * 255.0;
  360.       
  361.       *p1++ = (c1 + (r - c1) * a) * 255.0;
  362.       *p1++ = (c1 + (g - c1) * a) * 255.0;
  363.       *p1++ = (c1 + (b - c1) * a) * 255.0;
  364.       
  365.     } /* for */
  366.   
  367.   if ((row / GIMP_CHECK_SIZE) & 1)
  368.     {
  369.       gtk_preview_draw_row (GTK_PREVIEW (preview), (guchar *)odd,  0, row, width); 
  370.     }
  371.   else
  372.     {
  373.       gtk_preview_draw_row (GTK_PREVIEW (preview), (guchar *)even, 0, row, width); 
  374.     }
  375. }
  376.  
  377. static void
  378. filter_preview (void)
  379. {
  380.   guchar  **pixels;
  381.   guchar  **destpixels;
  382.   guchar  *even, *odd;
  383.   
  384.   gint      image_width;
  385.   gint      image_height;
  386.   gint      image_bpp;
  387.   gdouble   center_x;
  388.   gdouble   center_y;
  389.  
  390.   gint      x, y, b;
  391.   gint      xx = 0;
  392.   gint      yy = 0;
  393.   gdouble   scale, radius, cx, cy, angle, offset;
  394.  
  395.   image_width  = GTK_PREVIEW (preview)->buffer_width;
  396.   image_height = GTK_PREVIEW (preview)->buffer_height;
  397.   image_bpp    = preview_cache_bpp;
  398.   center_x     = (gdouble)image_width  / 2;
  399.   center_y     = (gdouble)image_height / 2;
  400.     
  401.   pixels     = g_new (guchar *, image_height);
  402.   destpixels = g_new (guchar *, image_height);
  403.  
  404.   even = g_malloc (image_width * 3);
  405.   odd  = g_malloc (image_width * 3);
  406.  
  407.   for (y = 0; y < image_height; y++)
  408.     {
  409.       pixels[y]     = g_new (guchar, preview_cache_rowstride);
  410.       destpixels[y] = g_new (guchar, preview_cache_rowstride);
  411.       memcpy (pixels[y], 
  412.           preview_cache + preview_cache_rowstride * y, 
  413.           preview_cache_rowstride);
  414.     }
  415.  
  416.   scale  = sqrt (image_width * image_width + image_height * image_height) / 2;
  417.   offset = (gint) (scale / 2);
  418.  
  419.   for (y = 0; y < image_height; y++)
  420.     {
  421.       cy = ((gdouble)y - center_y) / scale; 
  422.       for (x = 0; x < image_width; x++)
  423.     {
  424.       cx = ((gdouble)x - center_x) / scale;
  425.       angle = floor (atan2 (cy, cx) * parameters.division / G_PI_2)
  426.         * G_PI_2 / parameters.division + (G_PI / parameters.division);
  427.       radius = sqrt ((gdouble) (cx * cx + cy * cy));
  428.  
  429.       if (parameters.type1) 
  430.         {
  431.           xx = x - offset * cos (angle);
  432.           yy = y - offset * sin (angle);
  433.         }
  434.  
  435.       if (parameters.type2) 
  436.         {
  437.           xx = x - offset * sin (angle);
  438.           yy = y - offset * cos (angle);
  439.         }
  440.  
  441.       if (xx < 0) 
  442.         xx = 0;
  443.       else if (image_width <= xx) 
  444.         xx = image_width - 1;
  445.  
  446.       if (yy < 0) 
  447.         yy = 0;
  448.       else if (image_height <= yy) 
  449.         yy = image_height - 1;
  450.  
  451.       for (b = 0; b < image_bpp; b++)
  452.         destpixels[y][x*image_bpp+b] =
  453.           (1-radius) * pixels[y][x * image_bpp + b] 
  454.           + radius * pixels[yy][xx * image_bpp + b];
  455.     }
  456.  
  457.       preview_do_row(y,
  458.              image_width,
  459.              even,
  460.              odd,
  461.              destpixels[y]);
  462.     }
  463.  
  464.   for (y = 0; y < image_height; y++) 
  465.     g_free (pixels[y]);
  466.   g_free (pixels);
  467.  
  468.   for (y = 0; y < image_height; y++) 
  469.     g_free (destpixels[y]);
  470.   g_free (destpixels);
  471.  
  472.   g_free (even);
  473.   g_free (odd);
  474.  
  475.   gtk_widget_queue_draw (preview);
  476. }
  477.  
  478. static GtkWidget *
  479. preview_widget (GimpDrawable *drawable)
  480. {
  481.   preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  482.   fill_preview_with_thumb (preview, drawable->id);
  483.  
  484.   return preview;
  485. }
  486.  
  487. static void
  488. fill_preview_with_thumb (GtkWidget *widget, 
  489.              gint32     drawable_ID)
  490. {
  491.   guchar  *drawable_data;
  492.   gint     bpp;
  493.   gint     y;
  494.   gint     width  = PREVIEW_SIZE;
  495.   gint     height = PREVIEW_SIZE;
  496.   guchar  *src;
  497.   guchar  *even, *odd;
  498.  
  499.   bpp = 0; /* Only returned */
  500.   
  501.   drawable_data = 
  502.     gimp_drawable_get_thumbnail_data (drawable_ID, &width, &height, &bpp);
  503.  
  504.   if (width < 1 || height < 1)
  505.     return;
  506.  
  507.   preview_cache = drawable_data;
  508.   preview_cache_rowstride = width * bpp;
  509.   preview_cache_bpp = bpp;
  510.  
  511.   gtk_preview_size (GTK_PREVIEW (widget), width, height);
  512.  
  513.   even = g_malloc (width * 3);
  514.   odd  = g_malloc (width * 3);
  515.   src = drawable_data;
  516.  
  517.   for (y = 0; y < height; y++)
  518.     {
  519.       preview_do_row(y,width,even,odd,preview_cache + (y*width*bpp));
  520.     }
  521.  
  522.   g_free (even);
  523.   g_free (odd);
  524. }
  525.  
  526. /******************************************************************************/
  527.  
  528. static gboolean dialog_status = FALSE;
  529.  
  530. static void
  531. dialog_ok_handler (GtkWidget *widget,
  532.            gpointer   data)
  533. {
  534.   dialog_status = TRUE;
  535.  
  536.   gtk_widget_destroy (GTK_WIDGET (data));
  537. }
  538.  
  539. /******************************************************************************/
  540.  
  541. static gboolean
  542. dialog (GimpDrawable *mangle)
  543. {
  544.   GtkWidget *dlg;  
  545.   GtkWidget *main_vbox;
  546.   GtkWidget *abox;
  547.   GtkWidget *frame;
  548.   GtkWidget *table;
  549.   GtkWidget *spinbutton;
  550.   GtkObject *adj;
  551.   GtkWidget *radio;
  552.   GSList    *group = NULL;
  553.  
  554.   gimp_ui_init ("illusion", TRUE);
  555.  
  556.   dlg = gimp_dialog_new (_("Illusion"), "illusion",
  557.              gimp_standard_help_func, "filters/illusion.html",
  558.              GTK_WIN_POS_MOUSE,
  559.              FALSE, TRUE, FALSE,
  560.              
  561.              _("OK"), dialog_ok_handler,
  562.              NULL, NULL, NULL, TRUE, FALSE,
  563.              _("Cancel"), gtk_widget_destroy,
  564.              NULL, 1, NULL, FALSE, TRUE,
  565.              
  566.              NULL);
  567.  
  568.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  569.               GTK_SIGNAL_FUNC (gtk_main_quit),
  570.               NULL);
  571.  
  572.   /* Initialize Tooltips */
  573.   gimp_help_init ();
  574.   
  575.   main_vbox = gtk_vbox_new (FALSE, 3);
  576.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
  577.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), main_vbox, TRUE, TRUE, 0);
  578.   gtk_widget_show (main_vbox);
  579.  
  580.   frame = gtk_frame_new (_("Preview"));
  581.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  582.   gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  583.   gtk_widget_show (frame);
  584.   abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
  585.   gtk_container_set_border_width (GTK_CONTAINER (abox), 4);
  586.   gtk_container_add (GTK_CONTAINER (frame), abox);
  587.   gtk_widget_show (abox);
  588.   frame = gtk_frame_new (NULL);
  589.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  590.   gtk_container_add (GTK_CONTAINER (abox), frame);
  591.   gtk_widget_show (frame);
  592.   preview = preview_widget (mangle);
  593.   gtk_container_add (GTK_CONTAINER (frame), preview);
  594.   filter_preview();
  595.   gtk_widget_show (preview);
  596.   
  597.   frame = gtk_frame_new (_("Parameter Settings"));
  598.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  599.   gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0 );
  600.   gtk_widget_show (frame);
  601.  
  602.   table = gtk_table_new (3, 2, FALSE);
  603.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  604.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  605.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  606.   gtk_container_add (GTK_CONTAINER (frame), table);
  607.   gtk_widget_show (table);
  608.  
  609.   spinbutton = gimp_spin_button_new (&adj, parameters.division,
  610.                      -32, 64, 1, 10, 0, 1, 0);
  611.   gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
  612.                  _("Division:"), 1.0, 0.5,
  613.                  spinbutton, 1, TRUE);
  614.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  615.               GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
  616.               ¶meters.division);
  617.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  618.               GTK_SIGNAL_FUNC (filter_preview),
  619.               NULL);
  620.  
  621.   radio = gtk_radio_button_new_with_label (group, "Mode 1");
  622.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
  623.   gtk_signal_connect (GTK_OBJECT (radio), "toggled",
  624.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  625.               ¶meters.type1);
  626.   gtk_signal_connect (GTK_OBJECT (radio), "toggled",
  627.               GTK_SIGNAL_FUNC (filter_preview),
  628.               NULL);
  629.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), parameters.type1);
  630.   gtk_table_attach (GTK_TABLE (table), radio, 0, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
  631.   gtk_widget_show (radio);
  632.  
  633.   radio = gtk_radio_button_new_with_label (group, "Mode 2");
  634.   group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
  635.   gtk_signal_connect (GTK_OBJECT (radio), "toggled",
  636.               GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  637.               ¶meters.type2);
  638.   gtk_signal_connect (GTK_OBJECT (radio), "toggled",
  639.               GTK_SIGNAL_FUNC (filter_preview),
  640.               NULL);
  641.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), parameters.type2);
  642.   gtk_table_attach (GTK_TABLE (table), radio, 0, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
  643.   gtk_widget_show (radio);
  644.  
  645.   gtk_widget_show (dlg);
  646.  
  647.   gtk_main ();
  648.   gdk_flush ();
  649.  
  650.   return dialog_status;
  651. }
  652.