--- gimp-2.0.1.orig/plug-ins/common/snoise.c	2004-02-01 14:22:06.000000000 +0100
+++ gimp-2.0.1/plug-ins/common/snoise.c	2004-05-15 19:40:38.000000000 +0200
@@ -19,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/* Solid Noise plug-in version 1.03, Apr 1998
+/* Solid Noise plug-in version 1.04, May 2004
  *
  * This plug-in generates solid noise textures based on the
  * `Noise' and `Turbulence' functions described in the paper
@@ -37,7 +37,11 @@
  * which is Copyright (C) 1997 Federico Mena Quintero
  */
 
-/* Version 1.03:
+/* Version 1.04:
+ *
+ *  Dynamic preview added (Yeti <yeti@physics.muni.cz>).
+ *
+ * Version 1.03:
  *
  *  Added patch from Kevin Turner <kevint@poboxes.com> to use the
  *  current time as the random seed. Thank you!
@@ -81,6 +85,8 @@
 #define SIZE_MIN     0.1
 #define SIZE_MAX     16.0
 
+#define PREVIEW_SIZE    128
+#define BITS_PER_SAMPLE 8
 
 /*---- Typedefs ----*/
 
@@ -113,7 +119,15 @@ static gdouble plain_noise        (gdoub
 static gdouble noise              (gdouble       x,
                                    gdouble       y);
 
-static gint    solid_noise_dialog (void);
+static gint       solid_noise_dialog              (void);
+static GtkWidget* snoise_preview_frame_new_in_box (GtkWidget *hbox);
+static void       solid_noise_draw_one_tile       (GimpPixelRgn *rgn,
+                                                   gdouble width,
+                                                   gdouble height,
+                                                   gint xoffset,
+                                                   gint yoffset,
+                                                   gint chns,
+                                                   gboolean has_alpha);
 
 
 /*---- Variables ----*/
@@ -143,6 +157,8 @@ static gdouble     xsize, ysize;
 static gint        perm_tab[TABLE_SIZE];
 static GimpVector2 grad_tab[TABLE_SIZE];
 
+static GtkWidget  *preview_image = NULL;
+static GdkPixbuf  *preview = NULL;
 
 /*---- Functions ----*/
 
@@ -169,7 +185,7 @@ query (void)
 			  "Generates 2D textures using Perlin's classic solid noise function.",
 			  "Marcelo de Gomensoro Malheiros",
 			  "Marcelo de Gomensoro Malheiros",
-			  "Apr 1998, v1.03",
+			  "May 2004, v1.04",
 			  N_("<Image>/Filters/Render/Clouds/_Solid Noise..."),
 			  "RGB*, GRAY*",
 			  GIMP_PLUGIN,
@@ -286,75 +302,126 @@ static void
 solid_noise (GimpDrawable *drawable)
 {
   GimpPixelRgn dest_rgn;
-  gint      chns, i, has_alpha, row, col;
+  gint      chns, has_alpha;
   gint      sel_x1, sel_y1, sel_x2, sel_y2;
   gint      sel_width, sel_height;
   gint      progress, max_progress;
   gpointer  pr;
-  guchar   *dest, *dest_row;
-  guchar    val;
+  gboolean  preview_mode;
+
+  preview_mode = !drawable;
 
   /*  Get selection area  */
-  gimp_drawable_mask_bounds (drawable->drawable_id,
-			     &sel_x1, &sel_y1, &sel_x2, &sel_y2);
-  sel_width = sel_x2 - sel_x1;
-  sel_height = sel_y2 - sel_y1;
+  if (preview_mode)
+    {
+      sel_x1 = sel_y1 = 0;
+      sel_x2 = sel_y2 = sel_width = sel_height = PREVIEW_SIZE;
+    }
+  else
+    {
+      gimp_drawable_mask_bounds (drawable->drawable_id,
+                                 &sel_x1, &sel_y1, &sel_x2, &sel_y2);
+      sel_width = sel_x2 - sel_x1;
+      sel_height = sel_y2 - sel_y1;
+    }
 
   /*  Initialization  */
   solid_noise_init ();
-  gimp_progress_init (_("Solid Noise..."));
+  if (!preview_mode)
+      gimp_progress_init (_("Solid Noise..."));
+
   progress = 0;
   max_progress = sel_width * sel_height;
-  chns = gimp_drawable_bpp (drawable->drawable_id);
   has_alpha = 0;
-  if (gimp_drawable_has_alpha (drawable->drawable_id))
+  if (preview_mode)
+    {
+      dest_rgn.x = dest_rgn.y = 0;
+      dest_rgn.w = dest_rgn.h = PREVIEW_SIZE;
+      dest_rgn.bpp = chns = gdk_pixbuf_get_n_channels(preview);
+      dest_rgn.rowstride = gdk_pixbuf_get_rowstride(preview);
+      dest_rgn.data = gdk_pixbuf_get_pixels(preview);
+    }
+  else
     {
-      chns--;
-      has_alpha = 1;
+      chns = gimp_drawable_bpp (drawable->drawable_id);
+      if (gimp_drawable_has_alpha (drawable->drawable_id))
+        {
+          chns--;
+          has_alpha = 1;
+        }
+      gimp_pixel_rgn_init (&dest_rgn, drawable, sel_x1, sel_y1, sel_width,
+                           sel_height, TRUE, TRUE);
     }
-  gimp_pixel_rgn_init (&dest_rgn, drawable, sel_x1, sel_y1, sel_width,
-                       sel_height, TRUE, TRUE);
 
   /*  One, two, three, go!  */
-  for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
-       pr != NULL;
-       pr = gimp_pixel_rgns_process (pr))
+  if (preview_mode)
     {
-      dest_row = dest_rgn.data;
-
-      for (row = dest_rgn.y; row < (dest_rgn.y + dest_rgn.h); row++)
+      solid_noise_draw_one_tile (&dest_rgn, sel_width, sel_height,
+                                 sel_x1, sel_y1, chns, has_alpha);
+    }
+  else
+    {
+      for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
+          pr != NULL;
+          pr = gimp_pixel_rgns_process (pr))
         {
-          dest = dest_row;
-
-          for (col = dest_rgn.x; col < (dest_rgn.x + dest_rgn.w); col++)
-            {
-              val =
-                (guchar) floor (255.0 *
-                                noise ((double) (col - sel_x1) / sel_width,
-                                       (double) (row - sel_y1) / sel_height));
-
-              for (i = 0; i < chns; i++)
-                *dest++ = val;
-
-              if (has_alpha)
-                *dest++ = 255;
-            }
+          solid_noise_draw_one_tile (&dest_rgn, sel_width, sel_height,
+                                     sel_x1, sel_y1, chns, has_alpha);
 
-          dest_row += dest_rgn.rowstride;
+          /*  Update progress  */
+          progress += dest_rgn.w * dest_rgn.h;
+          gimp_progress_update ((double) progress / (double) max_progress);
         }
-
-      /*  Update progress  */
-      progress += dest_rgn.w * dest_rgn.h;
-      gimp_progress_update ((double) progress / (double) max_progress);
     }
 
   /*  Update the drawable  */
-  gimp_drawable_flush (drawable);
-  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
-  gimp_drawable_update (drawable->drawable_id,
-			sel_x1, sel_y1, sel_width, sel_height);
+  if (preview_mode)
+    {
+      gtk_widget_queue_draw (preview_image);
+    }
+  else
+    {
+      gimp_drawable_flush (drawable);
+      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
+      gimp_drawable_update (drawable->drawable_id,
+                            sel_x1, sel_y1, sel_width, sel_height);
+    }
 }
 
+static void
+solid_noise_draw_one_tile (GimpPixelRgn *dest_rgn,
+                           gdouble width,
+                           gdouble height,
+                           gint xoffset,
+                           gint yoffset,
+                           gint chns,
+                           gboolean has_alpha)
+{
+  guchar   *dest, *dest_row;
+  gint      row, col, i;
+  guchar    val;
+
+  dest_row = dest_rgn->data;
+
+  for (row = dest_rgn->y; row < (dest_rgn->y + dest_rgn->h); row++)
+    {
+      dest = dest_row;
+
+      for (col = dest_rgn->x; col < (dest_rgn->x + dest_rgn->w); col++)
+        {
+          val = (guchar) floor (255.0 * noise ((col - xoffset) / width,
+                                               (row - yoffset) / height));
+
+          for (i = 0; i < chns; i++)
+              *dest++ = val;
+
+          if (has_alpha)
+              *dest++ = 255;
+        }
+
+      dest_row += dest_rgn->rowstride;
+    }
+}
 
 static void
 solid_noise_init (void)
@@ -484,6 +551,42 @@ noise (gdouble x,
   return (sum+offset)*factor;
 }
 
+static GtkWidget*
+snoise_preview_frame_new_in_box(GtkWidget *hbox)
+{
+  GtkWidget *outerframe, *frame;
+  GtkWidget *align;
+  GtkWidget *image;
+  GdkPixbuf *pixbuf;
+
+  outerframe = gtk_frame_new (_ ("Preview"));
+  gtk_container_set_border_width (GTK_CONTAINER (outerframe), 6);
+  gtk_frame_set_shadow_type (GTK_FRAME (outerframe), GTK_SHADOW_ETCHED_IN);
+  gtk_box_pack_start (GTK_BOX (hbox), outerframe, FALSE, FALSE, 0);
+
+  align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+  gtk_container_set_border_width (GTK_CONTAINER (align), 4);
+  gtk_container_add (GTK_CONTAINER (outerframe), align);
+
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+  gtk_container_add (GTK_CONTAINER (align), frame);
+
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                           FALSE,
+                           BITS_PER_SAMPLE,
+                           PREVIEW_SIZE,
+                           PREVIEW_SIZE);
+  gdk_pixbuf_fill (pixbuf, 0);
+  preview = pixbuf;
+
+  preview_image = image = gtk_image_new_from_pixbuf (pixbuf);
+  g_object_unref (pixbuf);
+  gtk_container_add (GTK_CONTAINER (frame), image);
+
+  return outerframe;
+}
+
 
 static gint
 solid_noise_dialog (void)
@@ -510,6 +613,9 @@ solid_noise_dialog (void)
 
                          NULL);
 
+  frame = snoise_preview_frame_new_in_box (GTK_DIALOG (dlg)->vbox);
+  gtk_widget_show_all (frame);
+
   frame = gtk_frame_new (_("Parameter Settings"));
   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, FALSE, FALSE, 0);
@@ -530,6 +636,10 @@ solid_noise_dialog (void)
 				     seed_hbox, 1, TRUE);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label),
 				 GIMP_RANDOM_SEED_SPINBUTTON (seed_hbox));
+  g_signal_connect_swapped (GIMP_RANDOM_SEED_SPINBUTTON_ADJ (seed_hbox),
+                           "value_changed",
+                            G_CALLBACK (solid_noise),
+                            NULL);
 
   /*  Detail  */
   spinbutton = gimp_spin_button_new (&adj, snvals.detail,
@@ -540,6 +650,8 @@ solid_noise_dialog (void)
   g_signal_connect (adj, "value_changed",
                     G_CALLBACK (gimp_int_adjustment_update),
                     &snvals.detail);
+  g_signal_connect_swapped (adj, "value_changed",
+                            G_CALLBACK (solid_noise), NULL);
 
   /*  Turbulent  */
   toggle = gtk_check_button_new_with_mnemonic ( _("T_urbulent"));
@@ -551,6 +663,8 @@ solid_noise_dialog (void)
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
                     &snvals.turbulent);
+  g_signal_connect_swapped (toggle, "toggled",
+                            G_CALLBACK (solid_noise), NULL);
 
   /*  Tilable  */
   toggle = gtk_check_button_new_with_mnemonic ( _("T_ilable"));
@@ -562,6 +676,8 @@ solid_noise_dialog (void)
   g_signal_connect (toggle, "toggled",
                     G_CALLBACK (gimp_toggle_button_update),
                     &snvals.tilable);
+  g_signal_connect_swapped (toggle, "toggled",
+                            G_CALLBACK (solid_noise), NULL);
 
   /*  X Size  */
   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 2,
@@ -572,6 +688,8 @@ solid_noise_dialog (void)
   g_signal_connect (adj, "value_changed",
                     G_CALLBACK (gimp_double_adjustment_update),
                     &snvals.xsize);
+  g_signal_connect_swapped (adj, "value_changed",
+                            G_CALLBACK (solid_noise), NULL);
 
   /*  Y Size  */
   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 3,
@@ -582,7 +700,10 @@ solid_noise_dialog (void)
   g_signal_connect (adj, "value_changed",
                     G_CALLBACK (gimp_double_adjustment_update),
                     &snvals.ysize);
+  g_signal_connect_swapped (adj, "value_changed",
+                            G_CALLBACK (solid_noise), NULL);
 
+  solid_noise (NULL);
   gtk_widget_show (dlg);
 
   run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
