From c7281b52271db2744f609bb01e48c1383f05c233 Mon Sep 17 00:00:00 2001
From: Sven Neumann <sven@gimp.org>
Date: Fri, 28 Mar 2003 14:13:54 +0000
Subject: [PATCH] app/gui/Makefile.am added font selection GUI to be used
 through the PDB.

2003-03-28  Sven Neumann  <sven@gimp.org>

	* app/gui/Makefile.am
	* app/gui/font-select.[ch]: added font selection GUI to be used
	through the PDB.

	* app/gui/brush-select.c
	* app/gui/gradient-select.c
	* app/gui/palette-select.c
	* app/gui/pattern-select.c: unified preview and dialog sizes.

	* tools/pdbgen/Makefile.am
	* tools/pdbgen/pdb/font_select.pdb: added new file that provides
	PDB accessors to the font selection GUI.

	* app/pdb/font_select_cmds.c
	* app/pdb/internal_procs.c
	* libgimp/gimp_pdb.h
	* libgimp/gimpfontselect_pdb.[ch]
	* tools/pdbgen/groups.pl: regenerated.

	* libgimp/Makefile.am
	* libgimp/gimpfontmenu.c
	* libgimp/gimpmenu.[ch]: added a simple font selection widget to
	be used by plug-ins and scripts.

	* plug-ins/script-fu/script-fu-scripts.c: use the new font
	selection widget. Fixes bug #105610.
---
 ChangeLog                                |  29 +++
 app/gui/Makefile.am                      |   2 +
 app/gui/brush-select.c                   |  17 +-
 app/gui/font-select.c                    | 252 ++++++++++++++++++
 app/gui/font-select.h                    |  45 ++++
 app/gui/gradient-select.c                |   2 +-
 app/gui/palette-select.c                 |   4 +-
 app/gui/pattern-select.c                 |   4 +-
 app/pdb/Makefile.am                      |   3 +-
 app/pdb/font_select_cmds.c               | 244 ++++++++++++++++++
 app/pdb/internal_procs.c                 |  66 ++---
 devel-docs/ChangeLog                     |   7 +
 devel-docs/libgimp/libgimp-docs.sgml     |   2 +
 devel-docs/libgimp/libgimp-sections.txt  |  27 +-
 devel-docs/libgimp/tmpl/gimpfonts.sgml   |  48 ++++
 devel-docs/libgimp/tmpl/gimpmenu.sgml    | 107 ++++++--
 libgimp/Makefile.am                      |   3 +
 libgimp/gimp_pdb.h                       |   1 +
 libgimp/gimpfontmenu.c                   | 179 +++++++++++++
 libgimp/gimpfontselect_pdb.c             | 122 +++++++++
 libgimp/gimpfontselect_pdb.h             |  42 +++
 libgimp/gimpfontselectbutton.c           | 179 +++++++++++++
 libgimp/gimpmenu.c                       | 309 ++++++++++++++++-------
 libgimp/gimpmenu.h                       |  58 +++--
 plug-ins/script-fu/script-fu-interface.c | 206 +++------------
 plug-ins/script-fu/script-fu-scripts.c   | 206 +++------------
 tools/pdbgen/Makefile.am                 |   1 +
 tools/pdbgen/groups.pl                   |   1 +
 tools/pdbgen/pdb/font_select.pdb         | 141 +++++++++++
 29 files changed, 1775 insertions(+), 532 deletions(-)
 create mode 100644 app/gui/font-select.c
 create mode 100644 app/gui/font-select.h
 create mode 100644 app/pdb/font_select_cmds.c
 create mode 100644 devel-docs/libgimp/tmpl/gimpfonts.sgml
 create mode 100644 libgimp/gimpfontmenu.c
 create mode 100644 libgimp/gimpfontselect_pdb.c
 create mode 100644 libgimp/gimpfontselect_pdb.h
 create mode 100644 libgimp/gimpfontselectbutton.c
 create mode 100644 tools/pdbgen/pdb/font_select.pdb

diff --git a/ChangeLog b/ChangeLog
index 40abecfae0..da45a81a09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2003-03-28  Sven Neumann  <sven@gimp.org>
+
+	* app/gui/Makefile.am
+	* app/gui/font-select.[ch]: added font selection GUI to be used
+	through the PDB.
+
+	* app/gui/brush-select.c
+	* app/gui/gradient-select.c
+	* app/gui/palette-select.c
+	* app/gui/pattern-select.c: unified preview and dialog sizes.
+
+	* tools/pdbgen/Makefile.am
+	* tools/pdbgen/pdb/font_select.pdb: added new file that provides
+	PDB accessors to the font selection GUI.
+
+	* app/pdb/font_select_cmds.c
+	* app/pdb/internal_procs.c
+	* libgimp/gimp_pdb.h
+	* libgimp/gimpfontselect_pdb.[ch]
+	* tools/pdbgen/groups.pl: regenerated.
+	
+	* libgimp/Makefile.am
+	* libgimp/gimpfontmenu.c
+	* libgimp/gimpmenu.[ch]: added a simple font selection widget to
+	be used by plug-ins and scripts.
+
+	* plug-ins/script-fu/script-fu-scripts.c: use the new font
+	selection widget. Fixes bug #105610.
+
 2003-03-28  Michael Natterer  <mitch@gimp.org>
 
 	* app/core/gimpimage-guides.[ch]: added "position" and "push_undo"
diff --git a/app/gui/Makefile.am b/app/gui/Makefile.am
index db235cceee..ff413fe612 100644
--- a/app/gui/Makefile.am
+++ b/app/gui/Makefile.am
@@ -27,6 +27,8 @@ dialogs_sources = \
 	file-open-dialog.h		\
 	file-save-dialog.c		\
 	file-save-dialog.h		\
+	font-select.c			\
+	font-select.h			\
 	gradient-select.c		\
 	gradient-select.h		\
 	info-dialog.c			\
diff --git a/app/gui/brush-select.c b/app/gui/brush-select.c
index 9f5bfc4912..7593b048d9 100644
--- a/app/gui/brush-select.c
+++ b/app/gui/brush-select.c
@@ -154,15 +154,14 @@ brush_select_new (Gimp                 *gimp,
 				NULL);
 
   /*  The Brush Grid  */
-  bsp->view =
-    gimp_brush_factory_view_new (GIMP_VIEW_TYPE_GRID,
-                                 gimp->brush_factory,
-                                 dialogs_edit_brush_func,
-                                 bsp->context,
-                                 FALSE,
-                                 GIMP_PREVIEW_SIZE_EXTRA_SMALL,
-                                 5, 5,
-                                 global_menu_factory);
+  bsp->view = gimp_brush_factory_view_new (GIMP_VIEW_TYPE_GRID,
+                                           gimp->brush_factory,
+                                           dialogs_edit_brush_func,
+                                           bsp->context,
+                                           FALSE,
+                                           GIMP_PREVIEW_SIZE_MEDIUM,
+                                           5, 5,
+                                           global_menu_factory);
 
   gtk_container_set_border_width (GTK_CONTAINER (bsp->view), 4);
   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bsp->shell)->vbox), bsp->view);
diff --git a/app/gui/font-select.c b/app/gui/font-select.c
new file mode 100644
index 0000000000..667fdfd924
--- /dev/null
+++ b/app/gui/font-select.c
@@ -0,0 +1,252 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ * Copyright (C) 1998 Andy Thomas (alt@picnic.demon.co.uk)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "gui-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpcontainer.h"
+#include "core/gimpcontext.h"
+#include "text/gimpfont.h"
+
+#include "pdb/procedural_db.h"
+
+#include "widgets/gimpcontainertreeview.h"
+
+#include "dialogs-constructors.h"
+#include "menus.h"
+#include "font-select.h"
+
+#include "gimp-intl.h"
+
+
+/*  local function prototypes  */
+
+static void   font_select_change_callbacks (FontSelect  *font_select,
+                                            gboolean     closing);
+static void   font_select_font_changed     (GimpContext *context,
+                                            GimpFont    *font,
+                                            FontSelect  *font_select);
+static void   font_select_close_callback   (GtkWidget   *widget,
+                                            FontSelect  *font_select);
+
+
+/*  list of active dialogs  */
+static GSList *font_active_dialogs = NULL;
+
+
+/*  public functions  */
+
+FontSelect *
+font_select_new (Gimp        *gimp,
+                 const gchar *title,
+                 const gchar *initial_font,
+                 const gchar *callback_name)
+{
+  FontSelect *font_select;
+  GimpFont   *active = NULL;
+
+  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
+  g_return_val_if_fail (title != NULL, NULL);
+
+  if (initial_font && strlen (initial_font))
+    {
+      active = (GimpFont *)
+	gimp_container_get_child_by_name (gimp->fonts, initial_font);
+    }
+
+  if (! active)
+    active = gimp_context_get_font (gimp_get_current_context (gimp));
+
+  if (! active)
+    return NULL;
+
+  font_select = g_new0 (FontSelect, 1);
+
+  /*  Add to active font dialogs list  */
+  font_active_dialogs = g_slist_append (font_active_dialogs, font_select);
+
+  font_select->context       = gimp_context_new (gimp, title, NULL);
+  font_select->callback_name = g_strdup (callback_name);
+
+  gimp_context_set_font (font_select->context, active);
+
+  g_signal_connect (font_select->context, "font_changed",
+                    G_CALLBACK (font_select_font_changed),
+                    font_select);
+
+  /*  the shell  */
+  font_select->shell = gimp_dialog_new (title, "font_selection",
+                                        gimp_standard_help_func,
+                                        "dialogs/font_selection.html",
+                                        GTK_WIN_POS_MOUSE,
+                                        FALSE, TRUE, FALSE,
+
+                                        GTK_STOCK_CLOSE, font_select_close_callback,
+                                        font_select, NULL, NULL, TRUE, TRUE,
+
+                                        NULL);
+
+  /*  The Font List  */
+  font_select->view = gimp_container_tree_view_new (gimp->fonts,
+                                                    font_select->context,
+                                                    GIMP_PREVIEW_SIZE_MEDIUM,
+                                                    FALSE,
+                                                    5, 8);
+
+  gtk_container_set_border_width (GTK_CONTAINER (font_select->view), 4);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (font_select->shell)->vbox),
+                     font_select->view);
+  gtk_widget_show (font_select->view);
+
+  gtk_widget_show (font_select->shell);
+
+  return font_select;
+}
+
+void
+font_select_free (FontSelect *font_select)
+{
+  g_return_if_fail (font_select != NULL);
+
+  gtk_widget_destroy (font_select->shell); 
+
+  /* remove from active list */
+  font_active_dialogs = g_slist_remove (font_active_dialogs, font_select);
+
+  if (font_select->callback_name)
+    g_free (font_select->callback_name);
+
+  if (font_select->context)
+    g_object_unref (font_select->context);
+
+  g_free (font_select);
+}
+
+FontSelect *
+font_select_get_by_callback (const gchar *callback_name)
+{
+  GSList        *list;
+  FontSelect *font_select;
+
+  for (list = font_active_dialogs; list; list = g_slist_next (list))
+    {
+      font_select = (FontSelect *) list->data;
+
+      if (font_select->callback_name && !
+          strcmp (callback_name, font_select->callback_name))
+	return font_select;
+    }
+
+  return NULL;
+}
+
+void
+font_select_dialogs_check (void)
+{
+  FontSelect *font_select;
+  GSList        *list;
+
+  list = font_active_dialogs;
+
+  while (list)
+    {
+      font_select = (FontSelect *) list->data;
+
+      list = g_slist_next (list);
+
+      if (font_select->callback_name)
+        {
+          if (!  procedural_db_lookup (font_select->context->gimp,
+                                       font_select->callback_name))
+            font_select_close_callback (NULL, font_select); 
+        }
+    }
+}
+
+
+/*  private functions  */
+
+static void
+font_select_change_callbacks (FontSelect *font_select,
+                              gboolean    closing)
+{
+  ProcRecord *proc;
+  GimpFont   *font;
+
+  static gboolean busy = FALSE;
+
+  if (! (font_select && font_select->callback_name) || busy)
+    return;
+
+  busy = TRUE;
+
+  font = gimp_context_get_font (font_select->context);
+
+  /* If its still registered run it */
+  proc = procedural_db_lookup (font_select->context->gimp,
+                               font_select->callback_name);
+
+  if (proc && font)
+    {
+      Argument *return_vals; 
+      gint      nreturn_vals;
+
+      return_vals =
+	procedural_db_run_proc (font_select->context->gimp,
+				font_select->callback_name,
+				&nreturn_vals,
+				GIMP_PDB_STRING, GIMP_OBJECT (font)->name,
+				GIMP_PDB_INT32,  closing,
+				GIMP_PDB_END);
+ 
+      if (!return_vals || return_vals[0].value.pdb_int != GIMP_PDB_SUCCESS)
+	g_message (_("Unable to run font callback.\n"
+                     "The corresponding plug-in may have crashed."));
+
+      if (return_vals)
+        procedural_db_destroy_args (return_vals, nreturn_vals);
+    }
+
+  busy = FALSE;
+}
+
+static void
+font_select_font_changed (GimpContext *context,
+                          GimpFont    *font,
+                          FontSelect  *font_select)
+{
+  if (font)
+    font_select_change_callbacks (font_select, FALSE);
+}
+
+static void
+font_select_close_callback (GtkWidget  *widget,
+                            FontSelect *font_select)
+{
+  font_select_change_callbacks (font_select, TRUE);
+  font_select_free (font_select); 
+}
diff --git a/app/gui/font-select.h b/app/gui/font-select.h
new file mode 100644
index 0000000000..96a730b0d3
--- /dev/null
+++ b/app/gui/font-select.h
@@ -0,0 +1,45 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __FONT_SELECT_H__
+#define __FONT_SELECT_H__
+
+
+typedef struct _FontSelect FontSelect;
+
+struct _FontSelect
+{
+  GimpContext *context;
+  gchar       *callback_name;
+
+  GtkWidget   *shell;
+  GtkWidget   *view;
+};
+
+
+FontSelect * font_select_new             (Gimp        *gimp,
+                                          const gchar *title,
+                                          const gchar *initial_font,
+                                          const gchar *callback_name);
+void         font_select_free            (FontSelect  *font_select);
+
+FontSelect * font_select_get_by_callback (const gchar *callback_name);
+void         font_select_dialogs_check   (void);
+
+
+#endif  /* __FONT_SELECT_H__ */
diff --git a/app/gui/gradient-select.c b/app/gui/gradient-select.c
index cdb466dffd..54c3882396 100644
--- a/app/gui/gradient-select.c
+++ b/app/gui/gradient-select.c
@@ -129,7 +129,7 @@ gradient_select_new (Gimp        *gimp,
                                           gimp->gradient_factory,
                                           dialogs_edit_gradient_func,
                                           gsp->context,
-                                          GIMP_PREVIEW_SIZE_EXTRA_SMALL,
+                                          GIMP_PREVIEW_SIZE_MEDIUM,
                                           6, 6,
                                           global_menu_factory, "<Gradients>");
 
diff --git a/app/gui/palette-select.c b/app/gui/palette-select.c
index 751e8e02ac..5303a946c1 100644
--- a/app/gui/palette-select.c
+++ b/app/gui/palette-select.c
@@ -131,8 +131,8 @@ palette_select_new (Gimp        *gimp,
                                           gimp->palette_factory,
                                           dialogs_edit_palette_func,
                                           psp->context,
-                                          32,
-                                          5, 3,
+                                          GIMP_PREVIEW_SIZE_MEDIUM,
+                                          5, 8,
                                           global_menu_factory, "<Palettes>");
 
   gtk_container_set_border_width (GTK_CONTAINER (psp->view), 4);
diff --git a/app/gui/pattern-select.c b/app/gui/pattern-select.c
index d0749885d7..3081cc0404 100644
--- a/app/gui/pattern-select.c
+++ b/app/gui/pattern-select.c
@@ -127,8 +127,8 @@ pattern_select_new (Gimp        *gimp,
                                           gimp->pattern_factory,
                                           NULL,
                                           psp->context,
-                                          GIMP_PREVIEW_SIZE_SMALL,
-                                          5, 5,
+                                          GIMP_PREVIEW_SIZE_MEDIUM,
+                                          6, 6,
                                           global_menu_factory, "<Patterns>");
 
   gtk_container_set_border_width (GTK_CONTAINER (psp->view), 4);
diff --git a/app/pdb/Makefile.am b/app/pdb/Makefile.am
index 440e899220..146fd4992e 100644
--- a/app/pdb/Makefile.am
+++ b/app/pdb/Makefile.am
@@ -17,6 +17,7 @@ libapppdb_a_SOURCES = \
 	edit_cmds.c		\
 	fileops_cmds.c		\
 	floating_sel_cmds.c	\
+	font_select_cmds.c	\
 	gimprc_cmds.c		\
 	gradient_select_cmds.c	\
 	gradients_cmds.c	\
@@ -47,7 +48,7 @@ libapppdb_a_SOURCES = \
 	unit_cmds.c
 
 ## This is a truly ugly hack
-libapppdb_a_LIBADD = ../gui/pattern-select.o ../gui/brush-select.o
+libapppdb_a_LIBADD = ../gui/pattern-select.o ../gui/brush-select.o ../gui/font-select.o
 
 AM_CPPFLAGS = \
 	-DG_LOG_DOMAIN=\"Gimp-PDB\"	\
diff --git a/app/pdb/font_select_cmds.c b/app/pdb/font_select_cmds.c
new file mode 100644
index 0000000000..191af35226
--- /dev/null
+++ b/app/pdb/font_select_cmds.c
@@ -0,0 +1,244 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995-2000 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* NOTE: This file is autogenerated by pdbgen.pl. */
+
+#include "config.h"
+
+
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbasetypes.h"
+
+#include "pdb-types.h"
+#include "gui/gui-types.h"
+#include "procedural_db.h"
+
+#include "core/gimp.h"
+#include "core/gimpcontainer.h"
+#include "core/gimpcontext.h"
+#include "gui/font-select.h"
+
+static ProcRecord fonts_popup_proc;
+static ProcRecord fonts_close_popup_proc;
+static ProcRecord fonts_set_popup_proc;
+
+void
+register_font_select_procs (Gimp *gimp)
+{
+  procedural_db_register (gimp, &fonts_popup_proc);
+  procedural_db_register (gimp, &fonts_close_popup_proc);
+  procedural_db_register (gimp, &fonts_set_popup_proc);
+}
+
+static Argument *
+fonts_popup_invoker (Gimp     *gimp,
+                     Argument *args)
+{
+  gboolean success = TRUE;
+  gchar *font_callback;
+  gchar *popup_title;
+  gchar *initial_font;
+  ProcRecord *proc;
+
+  font_callback = (gchar *) args[0].value.pdb_pointer;
+  if (font_callback == NULL)
+    success = FALSE;
+
+  popup_title = (gchar *) args[1].value.pdb_pointer;
+  if (popup_title == NULL)
+    success = FALSE;
+
+  initial_font = (gchar *) args[2].value.pdb_pointer;
+
+  if (success)
+    {
+      if (! gimp->no_interface &&
+	  (proc = procedural_db_lookup (gimp, font_callback)))
+	{
+	  font_select_new (gimp, popup_title, initial_font, font_callback);
+	}
+      else
+	{
+	  success = FALSE;
+	}
+    }
+
+  return procedural_db_return_args (&fonts_popup_proc, success);
+}
+
+static ProcArg fonts_popup_inargs[] =
+{
+  {
+    GIMP_PDB_STRING,
+    "font_callback",
+    "The callback PDB proc to call when font selection is made"
+  },
+  {
+    GIMP_PDB_STRING,
+    "popup_title",
+    "Title to give the font popup window"
+  },
+  {
+    GIMP_PDB_STRING,
+    "initial_font",
+    "The name of the font to set as the first selected"
+  }
+};
+
+static ProcRecord fonts_popup_proc =
+{
+  "gimp_fonts_popup",
+  "Invokes the Gimp font selection.",
+  "This procedure popups the font selection dialog.",
+  "Sven Neumann <sven@gimp.org>",
+  "Sven Neumann",
+  "2003",
+  GIMP_INTERNAL,
+  3,
+  fonts_popup_inargs,
+  0,
+  NULL,
+  { { fonts_popup_invoker } }
+};
+
+static Argument *
+fonts_close_popup_invoker (Gimp     *gimp,
+                           Argument *args)
+{
+  gboolean success = TRUE;
+  gchar *font_callback;
+  ProcRecord *proc;
+  FontSelect *font_select;
+
+  font_callback = (gchar *) args[0].value.pdb_pointer;
+  if (font_callback == NULL)
+    success = FALSE;
+
+  if (success)
+    {
+      if (! gimp->no_interface &&
+	  (proc = procedural_db_lookup (gimp, font_callback)) &&
+	  (font_select = font_select_get_by_callback (font_callback)))
+	{
+	  font_select_free (font_select);
+	}
+      else
+	{
+	  success = FALSE;
+	}
+    }
+
+  return procedural_db_return_args (&fonts_close_popup_proc, success);
+}
+
+static ProcArg fonts_close_popup_inargs[] =
+{
+  {
+    GIMP_PDB_STRING,
+    "font_callback",
+    "The name of the callback registered for this popup"
+  }
+};
+
+static ProcRecord fonts_close_popup_proc =
+{
+  "gimp_fonts_close_popup",
+  "Popdown the Gimp font selection.",
+  "This procedure closes an opened font selection dialog.",
+  "Sven Neumann <sven@gimp.org>",
+  "Sven Neumann",
+  "2003",
+  GIMP_INTERNAL,
+  1,
+  fonts_close_popup_inargs,
+  0,
+  NULL,
+  { { fonts_close_popup_invoker } }
+};
+
+static Argument *
+fonts_set_popup_invoker (Gimp     *gimp,
+                         Argument *args)
+{
+  gboolean success = TRUE;
+  gchar *font_callback;
+  gchar *font_name;
+  ProcRecord *proc;
+  FontSelect *font_select;
+
+  font_callback = (gchar *) args[0].value.pdb_pointer;
+  if (font_callback == NULL)
+    success = FALSE;
+
+  font_name = (gchar *) args[1].value.pdb_pointer;
+  if (font_name == NULL)
+    success = FALSE;
+
+  if (success)
+    {
+      if (! gimp->no_interface &&
+	  (proc = procedural_db_lookup (gimp, font_callback)) &&
+	  (font_select = font_select_get_by_callback (font_callback)))
+	{
+	  GimpFont *active = (GimpFont *)
+	    gimp_container_get_child_by_name (gimp->fonts, font_name);
+    
+	  success = (active != NULL);
+    
+	  if (success)
+	    {
+	      gimp_context_set_font (font_select->context, active);
+	    }
+	}
+      else
+	success = FALSE;
+    }
+
+  return procedural_db_return_args (&fonts_set_popup_proc, success);
+}
+
+static ProcArg fonts_set_popup_inargs[] =
+{
+  {
+    GIMP_PDB_STRING,
+    "font_callback",
+    "The name of the callback registered for this popup"
+  },
+  {
+    GIMP_PDB_STRING,
+    "font_name",
+    "The name of the font to set as selected"
+  }
+};
+
+static ProcRecord fonts_set_popup_proc =
+{
+  "gimp_fonts_set_popup",
+  "Sets the current font selection in a popup.",
+  "Sets the current font selection in a popup.",
+  "Sven Neumann <sven@gimp.org>",
+  "Sven Neumann",
+  "2003",
+  GIMP_INTERNAL,
+  2,
+  fonts_set_popup_inargs,
+  0,
+  NULL,
+  { { fonts_set_popup_invoker } }
+};
diff --git a/app/pdb/internal_procs.c b/app/pdb/internal_procs.c
index c08da69e1a..c57d211e6c 100644
--- a/app/pdb/internal_procs.c
+++ b/app/pdb/internal_procs.c
@@ -40,6 +40,7 @@ void register_drawable_procs        (Gimp *gimp);
 void register_edit_procs            (Gimp *gimp);
 void register_fileops_procs         (Gimp *gimp);
 void register_floating_sel_procs    (Gimp *gimp);
+void register_font_select_procs     (Gimp *gimp);
 void register_gimprc_procs          (Gimp *gimp);
 void register_gradient_select_procs (Gimp *gimp);
 void register_gradients_procs       (Gimp *gimp);
@@ -67,7 +68,7 @@ void register_transform_tools_procs (Gimp *gimp);
 void register_undo_procs            (Gimp *gimp);
 void register_unit_procs            (Gimp *gimp);
 
-/* 339 procedures registered total */
+/* 342 procedures registered total */
 
 void
 internal_procs_init (Gimp               *gimp,
@@ -88,94 +89,97 @@ internal_procs_init (Gimp               *gimp,
   (* status_callback) (NULL, _("Color"), 0.088);
   register_color_procs (gimp);
 
-  (* status_callback) (NULL, _("Convert"), 0.124);
+  (* status_callback) (NULL, _("Convert"), 0.123);
   register_convert_procs (gimp);
 
-  (* status_callback) (NULL, _("Display procedures"), 0.133);
+  (* status_callback) (NULL, _("Display procedures"), 0.132);
   register_display_procs (gimp);
 
-  (* status_callback) (NULL, _("Drawable procedures"), 0.145);
+  (* status_callback) (NULL, _("Drawable procedures"), 0.143);
   register_drawable_procs (gimp);
 
-  (* status_callback) (NULL, _("Edit procedures"), 0.212);
+  (* status_callback) (NULL, _("Edit procedures"), 0.211);
   register_edit_procs (gimp);
 
-  (* status_callback) (NULL, _("File Operations"), 0.23);
+  (* status_callback) (NULL, _("File Operations"), 0.228);
   register_fileops_procs (gimp);
 
-  (* status_callback) (NULL, _("Floating selections"), 0.254);
+  (* status_callback) (NULL, _("Floating selections"), 0.251);
   register_floating_sel_procs (gimp);
 
-  (* status_callback) (NULL, _("Gimprc procedures"), 0.271);
+  (* status_callback) (NULL, _("Font UI"), 0.269);
+  register_font_select_procs (gimp);
+
+  (* status_callback) (NULL, _("Gimprc procedures"), 0.278);
   register_gimprc_procs (gimp);
 
-  (* status_callback) (NULL, _("Gradient UI"), 0.283);
+  (* status_callback) (NULL, _("Gradient UI"), 0.289);
   register_gradient_select_procs (gimp);
 
-  (* status_callback) (NULL, _("Gradients"), 0.292);
+  (* status_callback) (NULL, _("Gradients"), 0.298);
   register_gradients_procs (gimp);
 
-  (* status_callback) (NULL, _("Guide procedures"), 0.313);
+  (* status_callback) (NULL, _("Guide procedures"), 0.319);
   register_guides_procs (gimp);
 
-  (* status_callback) (NULL, _("Help procedures"), 0.33);
+  (* status_callback) (NULL, _("Help procedures"), 0.336);
   register_help_procs (gimp);
 
-  (* status_callback) (NULL, _("Image"), 0.333);
+  (* status_callback) (NULL, _("Image"), 0.339);
   register_image_procs (gimp);
 
-  (* status_callback) (NULL, _("Layer"), 0.519);
+  (* status_callback) (NULL, _("Layer"), 0.523);
   register_layer_procs (gimp);
 
-  (* status_callback) (NULL, _("Message procedures"), 0.614);
+  (* status_callback) (NULL, _("Message procedures"), 0.617);
   register_message_procs (gimp);
 
-  (* status_callback) (NULL, _("Miscellaneous"), 0.622);
+  (* status_callback) (NULL, _("Miscellaneous"), 0.626);
   register_misc_procs (gimp);
 
-  (* status_callback) (NULL, _("Misc Tool procedures"), 0.628);
+  (* status_callback) (NULL, _("Misc Tool procedures"), 0.632);
   register_misc_tools_procs (gimp);
 
-  (* status_callback) (NULL, _("Paint Tool procedures"), 0.637);
+  (* status_callback) (NULL, _("Paint Tool procedures"), 0.64);
   register_paint_tools_procs (gimp);
 
-  (* status_callback) (NULL, _("Palette"), 0.681);
+  (* status_callback) (NULL, _("Palette"), 0.684);
   register_palette_procs (gimp);
 
-  (* status_callback) (NULL, _("Palette UI"), 0.699);
+  (* status_callback) (NULL, _("Palette UI"), 0.702);
   register_palette_select_procs (gimp);
 
-  (* status_callback) (NULL, _("Palettes"), 0.708);
+  (* status_callback) (NULL, _("Palettes"), 0.711);
   register_palettes_procs (gimp);
 
-  (* status_callback) (NULL, _("Parasite procedures"), 0.723);
+  (* status_callback) (NULL, _("Parasite procedures"), 0.725);
   register_parasite_procs (gimp);
 
-  (* status_callback) (NULL, _("Paths"), 0.758);
+  (* status_callback) (NULL, _("Paths"), 0.76);
   register_paths_procs (gimp);
 
-  (* status_callback) (NULL, _("Pattern UI"), 0.796);
+  (* status_callback) (NULL, _("Pattern UI"), 0.798);
   register_pattern_select_procs (gimp);
 
-  (* status_callback) (NULL, _("Patterns"), 0.805);
+  (* status_callback) (NULL, _("Patterns"), 0.807);
   register_patterns_procs (gimp);
 
-  (* status_callback) (NULL, _("Plug-in"), 0.82);
+  (* status_callback) (NULL, _("Plug-in"), 0.822);
   register_plug_in_procs (gimp);
 
-  (* status_callback) (NULL, _("Procedural database"), 0.838);
+  (* status_callback) (NULL, _("Procedural database"), 0.839);
   register_procedural_db_procs (gimp);
 
-  (* status_callback) (NULL, _("Image mask"), 0.861);
+  (* status_callback) (NULL, _("Image mask"), 0.863);
   register_selection_procs (gimp);
 
-  (* status_callback) (NULL, _("Selection Tool procedures"), 0.914);
+  (* status_callback) (NULL, _("Selection Tool procedures"), 0.915);
   register_selection_tools_procs (gimp);
 
-  (* status_callback) (NULL, _("Text procedures"), 0.929);
+  (* status_callback) (NULL, _("Text procedures"), 0.93);
   register_text_tool_procs (gimp);
 
-  (* status_callback) (NULL, _("Transform Tool procedures"), 0.941);
+  (* status_callback) (NULL, _("Transform Tool procedures"), 0.942);
   register_transform_tools_procs (gimp);
 
   (* status_callback) (NULL, _("Undo"), 0.959);
diff --git a/devel-docs/ChangeLog b/devel-docs/ChangeLog
index 1b1611986b..eed87146dd 100644
--- a/devel-docs/ChangeLog
+++ b/devel-docs/ChangeLog
@@ -1,3 +1,10 @@
+2003-03-28  Sven Neumann  <sven@gimp.org>
+
+	* libgimp/libgimp-docs.sgml
+	* libgimp/libgimp-sections.txt
+	* libgimp/tmpl/gimpfonts.sgml
+	* libgimp/tmpl/gimpmenu.sgml: updated for new font selection API.
+
 2003-03-27  Sven Neumann  <sven@gimp.org>
 
 	* libgimpwidgets/libgimpwidgets-sections.txt
diff --git a/devel-docs/libgimp/libgimp-docs.sgml b/devel-docs/libgimp/libgimp-docs.sgml
index 424f248f11..7257b9a74e 100644
--- a/devel-docs/libgimp/libgimp-docs.sgml
+++ b/devel-docs/libgimp/libgimp-docs.sgml
@@ -11,6 +11,7 @@
 <!ENTITY GimpEdit SYSTEM "xml/gimpedit.xml">
 <!ENTITY GimpFileops SYSTEM "xml/gimpfileops.xml">
 <!ENTITY GimpFloatingsel SYSTEM "xml/gimpfloatingsel.xml">
+<!ENTITY GimpFonts SYSTEM "xml/gimpfonts.xml">
 <!ENTITY GimpGimprc SYSTEM "xml/gimpgimprc.xml">
 <!ENTITY GimpGradients SYSTEM "xml/gimpgradients.xml">
 <!ENTITY GimpGuides SYSTEM "xml/gimpguides.xml">
@@ -67,6 +68,7 @@
     &GimpEdit;
     &GimpFileops;
     &GimpFloatingsel;
+    &GimpFonts;
     &GimpGimprc;
     &GimpGradients;
     &GimpGuides;
diff --git a/devel-docs/libgimp/libgimp-sections.txt b/devel-docs/libgimp/libgimp-sections.txt
index 72769e6019..068f543257 100644
--- a/devel-docs/libgimp/libgimp-sections.txt
+++ b/devel-docs/libgimp/libgimp-sections.txt
@@ -228,6 +228,13 @@ gimp_floating_sel_rigor
 gimp_floating_sel_relax
 </SECTION>
 
+<SECTION>
+<FILE>gimpfonts</FILE>
+gimp_fonts_popup
+gimp_fonts_close_popup
+gimp_fonts_set_popup
+</SECTION>
+
 <SECTION>
 <FILE>gimpgimprc</FILE>
 gimp_gimprc_query
@@ -568,25 +575,29 @@ gimp_image_menu_new
 gimp_layer_menu_new
 gimp_channel_menu_new
 gimp_drawable_menu_new
-gimp_interactive_selection_brush
 <SUBSECTION>
+gimp_interactive_selection_brush
 gimp_brush_select_widget
 GimpRunBrushCallback
 gimp_brush_select_widget_set_popup
 gimp_brush_select_widget_close_popup
 <SUBSECTION>
-gimp_interactive_selection_pattern
-<SUBSECTION>
-gimp_pattern_select_widget
-GimpRunPatternCallback
-gimp_pattern_select_widget_close_popup
-gimp_pattern_select_widget_set_popup
+gimp_interactive_selection_font
+gimp_font_select_widget
+GimpRunFontCallback
+gimp_font_select_widget_set_popup
+gimp_font_select_widget_close_popup
 <SUBSECTION>
 gimp_interactive_selection_gradient
-<SUBSECTION>
 gimp_gradient_select_widget
 GimpRunGradientCallback
 gimp_gradient_select_widget_close_popup
 gimp_gradient_select_widget_set_popup
+<SUBSECTION>
+gimp_interactive_selection_pattern
+gimp_pattern_select_widget
+GimpRunPatternCallback
+gimp_pattern_select_widget_close_popup
+gimp_pattern_select_widget_set_popup
 </SECTION>
 
diff --git a/devel-docs/libgimp/tmpl/gimpfonts.sgml b/devel-docs/libgimp/tmpl/gimpfonts.sgml
new file mode 100644
index 0000000000..69a1afce82
--- /dev/null
+++ b/devel-docs/libgimp/tmpl/gimpfonts.sgml
@@ -0,0 +1,48 @@
+<!-- ##### SECTION Title ##### -->
+gimpfonts
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION gimp_fonts_popup ##### -->
+<para>
+
+</para>
+
+@font_callback: 
+@popup_title: 
+@initial_font: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gimp_fonts_close_popup ##### -->
+<para>
+
+</para>
+
+@font_callback: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gimp_fonts_set_popup ##### -->
+<para>
+
+</para>
+
+@font_callback: 
+@font_name: 
+@Returns: 
+
+
diff --git a/devel-docs/libgimp/tmpl/gimpmenu.sgml b/devel-docs/libgimp/tmpl/gimpmenu.sgml
index 3bac18244c..291f3b21b2 100644
--- a/devel-docs/libgimp/tmpl/gimpmenu.sgml
+++ b/devel-docs/libgimp/tmpl/gimpmenu.sgml
@@ -161,69 +161,55 @@ Widgets and functions for selecting images, layers, brushes, patterns etc.
 @w: 
 
 
-<!-- ##### FUNCTION gimp_interactive_selection_pattern ##### -->
+<!-- ##### FUNCTION gimp_interactive_selection_font ##### -->
 <para>
 
 </para>
 
 @dialogtitle: 
-@pattern_name: 
+@font_name: 
 @callback: 
 @data: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@udata: 
 
 
-<!-- ##### FUNCTION gimp_pattern_select_widget ##### -->
+<!-- ##### FUNCTION gimp_font_select_widget ##### -->
 <para>
 
 </para>
 
 @dname: 
-@ipattern: 
+@ifont: 
 @cback: 
 @data: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@Param4: 
 
 
-<!-- ##### USER_FUNCTION GimpRunPatternCallback ##### -->
+<!-- ##### USER_FUNCTION GimpRunFontCallback ##### -->
 <para>
 
 </para>
 
 @name: 
-@width: 
-@height: 
-@bpp: 
-@mask_data: 
 @dialog_closing: 
 @user_data: 
 
 
-<!-- ##### FUNCTION gimp_pattern_select_widget_close_popup ##### -->
-<para>
-
-</para>
-
-@widget: 
-<!-- # Unused Parameters # -->
-@Returns: 
-@w: 
-
-
-<!-- ##### FUNCTION gimp_pattern_select_widget_set_popup ##### -->
+<!-- ##### FUNCTION gimp_font_select_widget_set_popup ##### -->
 <para>
 
 </para>
 
 @widget: 
 @pname: 
-<!-- # Unused Parameters # -->
-@Returns: 
-@w: 
+
+
+<!-- ##### FUNCTION gimp_font_select_widget_close_popup ##### -->
+<para>
+
+</para>
+
+@widget: 
 
 
 <!-- ##### FUNCTION gimp_interactive_selection_gradient ##### -->
@@ -291,3 +277,68 @@ Widgets and functions for selecting images, layers, brushes, patterns etc.
 @w: 
 
 
+<!-- ##### FUNCTION gimp_interactive_selection_pattern ##### -->
+<para>
+
+</para>
+
+@dialogtitle: 
+@pattern_name: 
+@callback: 
+@data: 
+@Returns: 
+<!-- # Unused Parameters # -->
+@udata: 
+
+
+<!-- ##### FUNCTION gimp_pattern_select_widget ##### -->
+<para>
+
+</para>
+
+@dname: 
+@ipattern: 
+@cback: 
+@data: 
+@Returns: 
+<!-- # Unused Parameters # -->
+@Param4: 
+
+
+<!-- ##### USER_FUNCTION GimpRunPatternCallback ##### -->
+<para>
+
+</para>
+
+@name: 
+@width: 
+@height: 
+@bpp: 
+@mask_data: 
+@dialog_closing: 
+@user_data: 
+
+
+<!-- ##### FUNCTION gimp_pattern_select_widget_close_popup ##### -->
+<para>
+
+</para>
+
+@widget: 
+<!-- # Unused Parameters # -->
+@Returns: 
+@w: 
+
+
+<!-- ##### FUNCTION gimp_pattern_select_widget_set_popup ##### -->
+<para>
+
+</para>
+
+@widget: 
+@pname: 
+<!-- # Unused Parameters # -->
+@Returns: 
+@w: 
+
+
diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am
index 114541dfe2..bcee57d810 100644
--- a/libgimp/Makefile.am
+++ b/libgimp/Makefile.am
@@ -77,6 +77,7 @@ PDB_WRAPPERS_C = \
 	gimpedit_pdb.c			\
 	gimpfileops_pdb.c		\
 	gimpfloatingsel_pdb.c		\
+	gimpfontselect_pdb.c		\
 	gimpgimprc_pdb.c		\
 	gimpgradients_pdb.c		\
 	gimpgradientselect_pdb.c	\
@@ -116,6 +117,7 @@ PDB_WRAPPERS_H = \
 	gimpedit_pdb.h			\
 	gimpfileops_pdb.h		\
 	gimpfloatingsel_pdb.h		\
+	gimpfontselect_pdb.h		\
 	gimpgimprc_pdb.h		\
 	gimpgradients_pdb.h		\
 	gimpgradientselect_pdb.h	\
@@ -182,6 +184,7 @@ libgimpui_1_3_la_SOURCES = \
 	gimpmiscui.c		\
 	gimpmiscui.h		\
 	gimpbrushmenu.c		\
+	gimpfontmenu.c		\
 	gimpgradientmenu.c 	\
 	gimppatternmenu.c	\
 	gimpexport.c		\
diff --git a/libgimp/gimp_pdb.h b/libgimp/gimp_pdb.h
index 13b435e89a..09b5a75bc4 100644
--- a/libgimp/gimp_pdb.h
+++ b/libgimp/gimp_pdb.h
@@ -34,6 +34,7 @@
 #include <libgimp/gimpedit_pdb.h>
 #include <libgimp/gimpfileops_pdb.h>
 #include <libgimp/gimpfloatingsel_pdb.h>
+#include <libgimp/gimpfontselect_pdb.h>
 #include <libgimp/gimpgimprc_pdb.h>
 #include <libgimp/gimpgradients_pdb.h>
 #include <libgimp/gimpgradientselect_pdb.h>
diff --git a/libgimp/gimpfontmenu.c b/libgimp/gimpfontmenu.c
new file mode 100644
index 0000000000..c2e753b00f
--- /dev/null
+++ b/libgimp/gimpfontmenu.c
@@ -0,0 +1,179 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpfontmenu.c
+ * Copyright (C) 2003  Sven Neumann  <sven@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gimp.h"
+#include "gimpui.h"
+
+
+#define FSEL_DATA_KEY  "__fsel_data"
+
+typedef struct
+{
+  gchar               *dname;
+  GimpRunFontCallback  cback;
+  GtkWidget           *button;
+  GtkWidget           *label;
+  gchar               *font_name;      /* Local copy */
+  gchar               *font_popup_pnt; /* Pointer use to control the popup */
+  gpointer             data;
+} FSelect;
+
+
+static void
+font_select_invoker (gchar    *name,
+                     gint      closing,
+                     gpointer  data)
+{
+  FSelect *fsel = (FSelect*) data;
+
+  gtk_label_set_text (GTK_LABEL (fsel->label), name);
+
+  if (fsel->cback != NULL)
+    (fsel->cback) (name, closing, fsel->data);
+
+  if (closing)
+    {
+      gtk_widget_set_sensitive (fsel->button, TRUE);
+      fsel->font_popup_pnt = NULL;
+    }
+}
+
+
+static void
+fonts_select_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  FSelect *fsel = (FSelect*)data;
+
+  gtk_widget_set_sensitive (fsel->button, FALSE);
+  fsel->font_popup_pnt = 
+    gimp_interactive_selection_font ((fsel->dname) ? fsel->dname : 
+                                     "Font Selection",
+                                     fsel->font_name,
+                                     font_select_invoker, fsel);
+}
+
+/**
+ * gimp_font_select_widget:
+ * @dname: Title of the dialog to use.  NULL means to use the default title.
+ * @ifont: Initial font name. NULL means to use current selection. 
+ * @cback: a function to call when the selected font changes.
+ * @data: a pointer to arbitary data to be used in the call to @cback.
+ *
+ * Creates a new #GtkWidget that completely controls the selection of a 
+ * font.  This widget is suitable for placement in a table in a
+ * plug-in dialog.
+ *
+ * Returns:A #GtkWidget that you can use in your UI.
+ */
+GtkWidget * 
+gimp_font_select_widget (gchar               *dname,
+                         gchar               *ifont, 
+                         GimpRunFontCallback  cback,
+                         gpointer             data)
+{
+  GtkWidget *hbox;
+  GtkWidget *image;
+  FSelect   *fsel;
+  
+  fsel = g_new (FSelect, 1);
+  
+  fsel->cback          = cback;
+  fsel->data           = data;
+  fsel->font_name      = ifont;
+  fsel->dname          = dname;
+  fsel->font_popup_pnt = NULL;
+
+  fsel->button = gtk_button_new ();
+  
+  hbox = gtk_hbox_new (FALSE, 4);
+  gtk_container_add (GTK_CONTAINER (fsel->button), hbox);
+  gtk_widget_show (hbox);
+  
+  fsel->label = gtk_label_new (ifont);
+  gtk_box_pack_start (GTK_BOX (hbox), fsel->label, TRUE, TRUE, 4);
+  gtk_widget_show (fsel->label);
+
+  image = gtk_image_new_from_stock (GTK_STOCK_SELECT_FONT,
+                                    GTK_ICON_SIZE_BUTTON);
+  gtk_box_pack_end (GTK_BOX (hbox), image, FALSE, FALSE, 4);
+  gtk_widget_show (image);
+
+  g_signal_connect (fsel->button, "clicked",
+                    G_CALLBACK (fonts_select_callback),
+                    fsel);
+
+  g_object_set_data (G_OBJECT (fsel->button), FSEL_DATA_KEY, fsel);
+
+  return fsel->button;
+}
+
+/**
+ * gimp_font_select_widget_close_popup:
+ * @widget: A font select widget.
+ *
+ * Closes the popup window associated with @widget.
+ */
+void
+gimp_font_select_widget_close_popup (GtkWidget *widget)
+{
+  FSelect *fsel;
+
+  fsel = (FSelect *) g_object_get_data (G_OBJECT (widget), FSEL_DATA_KEY);
+
+  if (fsel && fsel->font_popup_pnt)
+    {
+      gimp_fonts_close_popup (fsel->font_popup_pnt);
+      fsel->font_popup_pnt = NULL;
+    }
+}
+
+/**
+ * gimp_font_select_widget_set_popup:
+ * @widget: A font select widget.
+ * @fname: Font name to set. NULL means no change. 
+ *
+ * Sets the current font for the font
+ * select widget.  Calls the callback function if one was
+ * supplied in the call to gimp_font_select_widget().
+ */
+void
+gimp_font_select_widget_set_popup (GtkWidget *widget,
+                                   gchar     *fname)
+{
+  FSelect  *fsel;
+  
+  fsel = (FSelect*) g_object_get_data (G_OBJECT (widget), FSEL_DATA_KEY);
+
+  if (fsel)
+    {
+      font_select_invoker (fname, FALSE, fsel);
+      
+      if (fsel->font_popup_pnt)
+	gimp_fonts_set_popup (fsel->font_popup_pnt, fname);
+    }
+}
+
diff --git a/libgimp/gimpfontselect_pdb.c b/libgimp/gimpfontselect_pdb.c
new file mode 100644
index 0000000000..246e175253
--- /dev/null
+++ b/libgimp/gimpfontselect_pdb.c
@@ -0,0 +1,122 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpfontselect_pdb.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* NOTE: This file is autogenerated by pdbgen.pl */
+
+#include "config.h"
+
+#include "gimp.h"
+
+/**
+ * gimp_fonts_popup:
+ * @font_callback: The callback PDB proc to call when font selection is made.
+ * @popup_title: Title to give the font popup window.
+ * @initial_font: The name of the font to set as the first selected.
+ *
+ * Invokes the Gimp font selection.
+ *
+ * This procedure popups the font selection dialog.
+ *
+ * Returns: TRUE on success.
+ */
+gboolean
+gimp_fonts_popup (gchar *font_callback,
+		  gchar *popup_title,
+		  gchar *initial_font)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gboolean success = TRUE;
+
+  return_vals = gimp_run_procedure ("gimp_fonts_popup",
+				    &nreturn_vals,
+				    GIMP_PDB_STRING, font_callback,
+				    GIMP_PDB_STRING, popup_title,
+				    GIMP_PDB_STRING, initial_font,
+				    GIMP_PDB_END);
+
+  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return success;
+}
+
+/**
+ * gimp_fonts_close_popup:
+ * @font_callback: The name of the callback registered for this popup.
+ *
+ * Popdown the Gimp font selection.
+ *
+ * This procedure closes an opened font selection dialog.
+ *
+ * Returns: TRUE on success.
+ */
+gboolean
+gimp_fonts_close_popup (gchar *font_callback)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gboolean success = TRUE;
+
+  return_vals = gimp_run_procedure ("gimp_fonts_close_popup",
+				    &nreturn_vals,
+				    GIMP_PDB_STRING, font_callback,
+				    GIMP_PDB_END);
+
+  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return success;
+}
+
+/**
+ * gimp_fonts_set_popup:
+ * @font_callback: The name of the callback registered for this popup.
+ * @font_name: The name of the font to set as selected.
+ *
+ * Sets the current font selection in a popup.
+ *
+ * Sets the current font selection in a popup.
+ *
+ * Returns: TRUE on success.
+ */
+gboolean
+gimp_fonts_set_popup (gchar *font_callback,
+		      gchar *font_name)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gboolean success = TRUE;
+
+  return_vals = gimp_run_procedure ("gimp_fonts_set_popup",
+				    &nreturn_vals,
+				    GIMP_PDB_STRING, font_callback,
+				    GIMP_PDB_STRING, font_name,
+				    GIMP_PDB_END);
+
+  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return success;
+}
diff --git a/libgimp/gimpfontselect_pdb.h b/libgimp/gimpfontselect_pdb.h
new file mode 100644
index 0000000000..f5c19b5ac2
--- /dev/null
+++ b/libgimp/gimpfontselect_pdb.h
@@ -0,0 +1,42 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpfontselect_pdb.h
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* NOTE: This file is autogenerated by pdbgen.pl */
+
+#ifndef __GIMP_FONT_SELECT_PDB_H__
+#define __GIMP_FONT_SELECT_PDB_H__
+
+G_BEGIN_DECLS
+
+/* For information look into the C source or the html documentation */
+
+
+gboolean gimp_fonts_popup       (gchar *font_callback,
+				 gchar *popup_title,
+				 gchar *initial_font);
+gboolean gimp_fonts_close_popup (gchar *font_callback);
+gboolean gimp_fonts_set_popup   (gchar *font_callback,
+				 gchar *font_name);
+
+
+G_END_DECLS
+
+#endif /* __GIMP_FONT_SELECT_PDB_H__ */
diff --git a/libgimp/gimpfontselectbutton.c b/libgimp/gimpfontselectbutton.c
new file mode 100644
index 0000000000..c2e753b00f
--- /dev/null
+++ b/libgimp/gimpfontselectbutton.c
@@ -0,0 +1,179 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpfontmenu.c
+ * Copyright (C) 2003  Sven Neumann  <sven@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gimp.h"
+#include "gimpui.h"
+
+
+#define FSEL_DATA_KEY  "__fsel_data"
+
+typedef struct
+{
+  gchar               *dname;
+  GimpRunFontCallback  cback;
+  GtkWidget           *button;
+  GtkWidget           *label;
+  gchar               *font_name;      /* Local copy */
+  gchar               *font_popup_pnt; /* Pointer use to control the popup */
+  gpointer             data;
+} FSelect;
+
+
+static void
+font_select_invoker (gchar    *name,
+                     gint      closing,
+                     gpointer  data)
+{
+  FSelect *fsel = (FSelect*) data;
+
+  gtk_label_set_text (GTK_LABEL (fsel->label), name);
+
+  if (fsel->cback != NULL)
+    (fsel->cback) (name, closing, fsel->data);
+
+  if (closing)
+    {
+      gtk_widget_set_sensitive (fsel->button, TRUE);
+      fsel->font_popup_pnt = NULL;
+    }
+}
+
+
+static void
+fonts_select_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  FSelect *fsel = (FSelect*)data;
+
+  gtk_widget_set_sensitive (fsel->button, FALSE);
+  fsel->font_popup_pnt = 
+    gimp_interactive_selection_font ((fsel->dname) ? fsel->dname : 
+                                     "Font Selection",
+                                     fsel->font_name,
+                                     font_select_invoker, fsel);
+}
+
+/**
+ * gimp_font_select_widget:
+ * @dname: Title of the dialog to use.  NULL means to use the default title.
+ * @ifont: Initial font name. NULL means to use current selection. 
+ * @cback: a function to call when the selected font changes.
+ * @data: a pointer to arbitary data to be used in the call to @cback.
+ *
+ * Creates a new #GtkWidget that completely controls the selection of a 
+ * font.  This widget is suitable for placement in a table in a
+ * plug-in dialog.
+ *
+ * Returns:A #GtkWidget that you can use in your UI.
+ */
+GtkWidget * 
+gimp_font_select_widget (gchar               *dname,
+                         gchar               *ifont, 
+                         GimpRunFontCallback  cback,
+                         gpointer             data)
+{
+  GtkWidget *hbox;
+  GtkWidget *image;
+  FSelect   *fsel;
+  
+  fsel = g_new (FSelect, 1);
+  
+  fsel->cback          = cback;
+  fsel->data           = data;
+  fsel->font_name      = ifont;
+  fsel->dname          = dname;
+  fsel->font_popup_pnt = NULL;
+
+  fsel->button = gtk_button_new ();
+  
+  hbox = gtk_hbox_new (FALSE, 4);
+  gtk_container_add (GTK_CONTAINER (fsel->button), hbox);
+  gtk_widget_show (hbox);
+  
+  fsel->label = gtk_label_new (ifont);
+  gtk_box_pack_start (GTK_BOX (hbox), fsel->label, TRUE, TRUE, 4);
+  gtk_widget_show (fsel->label);
+
+  image = gtk_image_new_from_stock (GTK_STOCK_SELECT_FONT,
+                                    GTK_ICON_SIZE_BUTTON);
+  gtk_box_pack_end (GTK_BOX (hbox), image, FALSE, FALSE, 4);
+  gtk_widget_show (image);
+
+  g_signal_connect (fsel->button, "clicked",
+                    G_CALLBACK (fonts_select_callback),
+                    fsel);
+
+  g_object_set_data (G_OBJECT (fsel->button), FSEL_DATA_KEY, fsel);
+
+  return fsel->button;
+}
+
+/**
+ * gimp_font_select_widget_close_popup:
+ * @widget: A font select widget.
+ *
+ * Closes the popup window associated with @widget.
+ */
+void
+gimp_font_select_widget_close_popup (GtkWidget *widget)
+{
+  FSelect *fsel;
+
+  fsel = (FSelect *) g_object_get_data (G_OBJECT (widget), FSEL_DATA_KEY);
+
+  if (fsel && fsel->font_popup_pnt)
+    {
+      gimp_fonts_close_popup (fsel->font_popup_pnt);
+      fsel->font_popup_pnt = NULL;
+    }
+}
+
+/**
+ * gimp_font_select_widget_set_popup:
+ * @widget: A font select widget.
+ * @fname: Font name to set. NULL means no change. 
+ *
+ * Sets the current font for the font
+ * select widget.  Calls the callback function if one was
+ * supplied in the call to gimp_font_select_widget().
+ */
+void
+gimp_font_select_widget_set_popup (GtkWidget *widget,
+                                   gchar     *fname)
+{
+  FSelect  *fsel;
+  
+  fsel = (FSelect*) g_object_get_data (G_OBJECT (widget), FSEL_DATA_KEY);
+
+  if (fsel)
+    {
+      font_select_invoker (fname, FALSE, fsel);
+      
+      if (fsel->font_popup_pnt)
+	gimp_fonts_set_popup (fsel->font_popup_pnt, fname);
+    }
+}
+
diff --git a/libgimp/gimpmenu.c b/libgimp/gimpmenu.c
index 6956c20097..5a60f1efbb 100644
--- a/libgimp/gimpmenu.c
+++ b/libgimp/gimpmenu.c
@@ -54,6 +54,35 @@ struct _GimpBrushData
 
 typedef struct _GimpBrushData GimpBrushData;
 
+
+/* Copy data from temp_PDB call */
+struct _GimpFontData 
+{
+  gboolean  busy;
+  gchar    *fname;
+  GimpRunFontCallback  callback;
+  gboolean  closing;
+  gpointer  data;
+};
+
+typedef struct _GimpFontData GimpFontData;
+
+
+/* Copy data from temp_PDB call */
+struct _GimpGradientData 
+{
+  gboolean  busy;
+  gchar    *gname;
+  gint      width;
+  gdouble  *gradient_data;
+  GimpRunGradientCallback  callback;
+  gboolean  closing;
+  gpointer  data;
+};
+
+typedef struct _GimpGradientData GimpGradientData;
+
+
 /* Copy data from temp_PDB call */
 struct _GimpPatternData 
 {
@@ -70,19 +99,6 @@ struct _GimpPatternData
 
 typedef struct _GimpPatternData GimpPatternData;
 
-/* Copy data from temp_PDB call */
-struct _GimpGradientData 
-{
-  gboolean  busy;
-  gchar    *gname;
-  gint      width;
-  gdouble  *gradient_data;
-  GimpRunGradientCallback  callback;
-  gboolean  closing;
-  gpointer  data;
-};
-
-typedef struct _GimpGradientData GimpGradientData;
 
 static void     gimp_menu_callback      (GtkWidget         *widget,
 					 gint32            *id);
@@ -109,11 +125,13 @@ static void     fill_preview_with_thumb (GtkWidget         *widget,
 void gimp_run_temp (void);
 
 static GHashTable       *gbrush_ht           = NULL;
-static GHashTable       *gpattern_ht         = NULL;
+static GHashTable       *gfont_ht            = NULL;
 static GHashTable       *ggradient_ht        = NULL;
+static GHashTable       *gpattern_ht         = NULL;
 static GimpBrushData    *active_brush_pdb    = NULL;
-static GimpPatternData  *active_pattern_pdb  = NULL;
+static GimpFontData     *active_font_pdb     = NULL;
 static GimpGradientData *active_gradient_pdb = NULL;
+static GimpPatternData  *active_pattern_pdb  = NULL;
 
 GtkWidget *
 gimp_image_menu_new (GimpConstraintFunc constraint,
@@ -732,29 +750,21 @@ do_brush_callback (GimpBrushData *bdata)
 }
 
 static void 
-do_pattern_callback (GimpPatternData *pdata)
+do_font_callback (GimpFontData *fdata)
 {
-  if (!pdata->busy)
+  if (!fdata->busy)
     return;
 
-  if (pdata->callback)
-    pdata->callback (pdata->pname,
-		     pdata->width,
-		     pdata->height,
-		     pdata->bytes,
-		     pdata->pattern_mask_data,
-		     pdata->closing,
-		     pdata->data);
+  if (fdata->callback)
+    fdata->callback (fdata->fname,
+		     fdata->closing,
+		     fdata->data);
   
-  if (pdata->pname)
-    g_free (pdata->pname);  
-  
-  if (pdata->pattern_mask_data)
-    g_free (pdata->pattern_mask_data); 
+  if (fdata->fname)
+    g_free (fdata->fname);  
 
-  pdata->busy = FALSE;
-  pdata->pname = NULL;
-  pdata->pattern_mask_data = NULL;
+  fdata->busy = FALSE;
+  fdata->fname = NULL;
 }
 
 static void 
@@ -781,6 +791,33 @@ do_gradient_callback (GimpGradientData *gdata)
   gdata->gradient_data = NULL;
 }
 
+static void 
+do_pattern_callback (GimpPatternData *pdata)
+{
+  if (!pdata->busy)
+    return;
+
+  if (pdata->callback)
+    pdata->callback (pdata->pname,
+		     pdata->width,
+		     pdata->height,
+		     pdata->bytes,
+		     pdata->pattern_mask_data,
+		     pdata->closing,
+		     pdata->data);
+  
+  if (pdata->pname)
+    g_free (pdata->pname);  
+  
+  if (pdata->pattern_mask_data)
+    g_free (pdata->pattern_mask_data); 
+
+  pdata->busy = FALSE;
+  pdata->pname = NULL;
+  pdata->pattern_mask_data = NULL;
+}
+
+
 static gint
 idle_test_brush (gpointer bdata)
 {
@@ -789,11 +826,10 @@ idle_test_brush (gpointer bdata)
   return FALSE;
 }
 
-
 static gint
-idle_test_pattern (gpointer pdata)
+idle_test_font (gpointer gdata)
 {
-  do_pattern_callback (pdata);
+  do_font_callback (gdata);
 
   return FALSE;
 }
@@ -806,6 +842,14 @@ idle_test_gradient (gpointer gdata)
   return FALSE;
 }
 
+static gint
+idle_test_pattern (gpointer pdata)
+{
+  do_pattern_callback (pdata);
+
+  return FALSE;
+}
+
 static void
 temp_brush_invoker (gchar      *name,
 		    gint        nparams,
@@ -848,35 +892,29 @@ temp_brush_invoker (gchar      *name,
 }
 
 static void
-temp_pattern_invoker (gchar      *name,
-		      gint        nparams,
-		      GimpParam  *param,
-		      gint       *nreturn_vals,
-		      GimpParam **return_vals)
+temp_font_invoker (gchar      *name,
+                   gint        nparams,
+                   GimpParam  *param,
+                   gint       *nreturn_vals,
+                   GimpParam **return_vals)
 {
   static GimpParam values[1];
   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
-  GimpPatternData *pdata;
+  GimpFontData *fdata;
 
-  pdata = (GimpPatternData *)g_hash_table_lookup (gpattern_ht, name);
+  fdata = (GimpFontData *)g_hash_table_lookup (gfont_ht, name);
 
-  if (!pdata)
-    g_warning ("Can't find internal pattern data");
+  if (!fdata)
+    g_warning ("Can't find internal font data");
   else
-    if (!pdata->busy)
+    if (!fdata->busy)
       {
-	pdata->pname             = g_strdup(param[0].data.d_string);
-	pdata->width             = param[1].data.d_int32;
-	pdata->height            = param[2].data.d_int32;
-	pdata->bytes             = param[3].data.d_int32;
-	pdata->pattern_mask_data = g_malloc(param[4].data.d_int32);
-	g_memmove (pdata->pattern_mask_data,
-		   param[5].data.d_int8array, param[4].data.d_int32);
-	pdata->closing           = param[6].data.d_int32;
-	active_pattern_pdb       = pdata;
-	pdata->busy              = TRUE;
+	fdata->fname    = g_strdup (param[0].data.d_string);
+	fdata->closing  = param[1].data.d_int32;
+	active_font_pdb = fdata;
+	fdata->busy     = TRUE;
 
-	g_idle_add (idle_test_pattern, active_pattern_pdb);
+	g_idle_add (idle_test_font, active_font_pdb);
       }
 
   *nreturn_vals = 1;
@@ -933,6 +971,46 @@ temp_gradient_invoker (gchar      *name,
   values[0].data.d_status = status;
 }
 
+static void
+temp_pattern_invoker (gchar      *name,
+		      gint        nparams,
+		      GimpParam  *param,
+		      gint       *nreturn_vals,
+		      GimpParam **return_vals)
+{
+  static GimpParam values[1];
+  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
+  GimpPatternData *pdata;
+
+  pdata = (GimpPatternData *)g_hash_table_lookup (gpattern_ht, name);
+
+  if (!pdata)
+    g_warning ("Can't find internal pattern data");
+  else
+    if (!pdata->busy)
+      {
+	pdata->pname             = g_strdup(param[0].data.d_string);
+	pdata->width             = param[1].data.d_int32;
+	pdata->height            = param[2].data.d_int32;
+	pdata->bytes             = param[3].data.d_int32;
+	pdata->pattern_mask_data = g_malloc(param[4].data.d_int32);
+	g_memmove (pdata->pattern_mask_data,
+		   param[5].data.d_int8array, param[4].data.d_int32);
+	pdata->closing           = param[6].data.d_int32;
+	active_pattern_pdb       = pdata;
+	pdata->busy              = TRUE;
+
+	g_idle_add (idle_test_pattern, active_pattern_pdb);
+      }
+
+  *nreturn_vals = 1;
+  *return_vals = values;
+  
+  values[0].type = GIMP_PDB_STATUS;
+  values[0].data.d_status = status;
+}
+
+
 static gboolean
 input_callback (GIOChannel  *channel,
 		GIOCondition condition,
@@ -1064,31 +1142,26 @@ gimp_interactive_selection_brush (gchar             *dialogname,
 }
 
 gchar *
-gimp_interactive_selection_pattern (gchar                  *dialogname, 
-				    gchar                  *pattern_name,
-				    GimpRunPatternCallback  callback,
-				    gpointer                data)
+gimp_interactive_selection_font (gchar               *dialogname, 
+                                 gchar               *font_name,
+                                 GimpRunFontCallback  callback,
+                                 gpointer             data)
 {
   static GimpParamDef args[] =
   {
-    { GIMP_PDB_STRING,   "str",           "String" },
-    { GIMP_PDB_INT32,    "mask width",    "Pattern width" },
-    { GIMP_PDB_INT32,    "mask height",   "Pattern heigth" },
-    { GIMP_PDB_INT32,    "mask bpp",      "Pattern bytes per pixel" },
-    { GIMP_PDB_INT32,    "mask len",      "Length of pattern mask data" },
-    { GIMP_PDB_INT8ARRAY,"mask data",     "The pattern mask data" },
-    { GIMP_PDB_INT32,    "dialog status", "Registers if the dialog was closing "
-                                       "[0 = No, 1 = Yes]" },
+    { GIMP_PDB_STRING, "str",           "String" },
+    { GIMP_PDB_INT32,  "dialog status", "Registers if the dialog was closing "
+                                        "[0 = No, 1 = Yes]" },
   };
   static GimpParamDef *return_vals = NULL;
   static gint nargs = sizeof (args) / sizeof (args[0]);
   static gint nreturn_vals = 0;
-  gint bnreturn_vals;
+  gint fnreturn_vals;
   GimpParam *pdbreturn_vals;
   gchar *pdbname = gen_temp_plugin_name ();
-  GimpPatternData *pdata;
+  GimpFontData *fdata;
 
-  pdata = g_new0 (GimpPatternData, 1);
+  fdata = g_new0 (GimpFontData, 1);
 
   gimp_install_temp_proc (pdbname,
 			  "Temp PDB for interactive popups",
@@ -1101,28 +1174,28 @@ gimp_interactive_selection_pattern (gchar                  *dialogname,
 			  GIMP_TEMPORARY,
 			  nargs, nreturn_vals,
 			  args, return_vals,
-			  temp_pattern_invoker);
+			  temp_font_invoker);
 
   pdbreturn_vals =
-    gimp_run_procedure("gimp_patterns_popup",
-		       &bnreturn_vals,
-		       GIMP_PDB_STRING,pdbname,
-		       GIMP_PDB_STRING,dialogname,
-		       GIMP_PDB_STRING,pattern_name,/*name*/
-		       GIMP_PDB_END);
+    gimp_run_procedure ("gimp_fonts_popup",
+                        &fnreturn_vals,
+                        GIMP_PDB_STRING, pdbname,
+                        GIMP_PDB_STRING, dialogname,
+                        GIMP_PDB_STRING, font_name, /*name*/
+                        GIMP_PDB_END);
 
   gimp_setup_callbacks (); /* New function to allow callbacks to be watched */
 
-  gimp_destroy_params (pdbreturn_vals, bnreturn_vals);
+  gimp_destroy_params (pdbreturn_vals, fnreturn_vals);
 
   /* Now add to hash table so we can find it again */
-  if (gpattern_ht == NULL)
-    gpattern_ht = g_hash_table_new (g_str_hash,
-				    g_str_equal);
+  if (gfont_ht == NULL)
+    gfont_ht = g_hash_table_new (g_str_hash,
+                                 g_str_equal);
 
-  pdata->callback = callback;
-  pdata->data = data;
-  g_hash_table_insert (gpattern_ht, pdbname,pdata);
+  fdata->callback = callback;
+  fdata->data = data;
+  g_hash_table_insert (gfont_ht, pdbname, fdata);
 
   return pdbname;
 }
@@ -1189,3 +1262,67 @@ gimp_interactive_selection_gradient (gchar                   *dialogname,
 
   return pdbname;
 }
+
+gchar *
+gimp_interactive_selection_pattern (gchar                  *dialogname, 
+				    gchar                  *pattern_name,
+				    GimpRunPatternCallback  callback,
+				    gpointer                data)
+{
+  static GimpParamDef args[] =
+  {
+    { GIMP_PDB_STRING,   "str",           "String" },
+    { GIMP_PDB_INT32,    "mask width",    "Pattern width" },
+    { GIMP_PDB_INT32,    "mask height",   "Pattern heigth" },
+    { GIMP_PDB_INT32,    "mask bpp",      "Pattern bytes per pixel" },
+    { GIMP_PDB_INT32,    "mask len",      "Length of pattern mask data" },
+    { GIMP_PDB_INT8ARRAY,"mask data",     "The pattern mask data" },
+    { GIMP_PDB_INT32,    "dialog status", "Registers if the dialog was closing "
+                                       "[0 = No, 1 = Yes]" },
+  };
+  static GimpParamDef *return_vals = NULL;
+  static gint nargs = sizeof (args) / sizeof (args[0]);
+  static gint nreturn_vals = 0;
+  gint bnreturn_vals;
+  GimpParam *pdbreturn_vals;
+  gchar *pdbname = gen_temp_plugin_name ();
+  GimpPatternData *pdata;
+
+  pdata = g_new0 (GimpPatternData, 1);
+
+  gimp_install_temp_proc (pdbname,
+			  "Temp PDB for interactive popups",
+			  "More here later",
+			  "Andy Thomas",
+			  "Andy Thomas",
+			  "1997",
+			  NULL,
+			  "RGB*, GRAY*",
+			  GIMP_TEMPORARY,
+			  nargs, nreturn_vals,
+			  args, return_vals,
+			  temp_pattern_invoker);
+
+  pdbreturn_vals =
+    gimp_run_procedure("gimp_patterns_popup",
+		       &bnreturn_vals,
+		       GIMP_PDB_STRING,pdbname,
+		       GIMP_PDB_STRING,dialogname,
+		       GIMP_PDB_STRING,pattern_name,/*name*/
+		       GIMP_PDB_END);
+
+  gimp_setup_callbacks (); /* New function to allow callbacks to be watched */
+
+  gimp_destroy_params (pdbreturn_vals, bnreturn_vals);
+
+  /* Now add to hash table so we can find it again */
+  if (gpattern_ht == NULL)
+    gpattern_ht = g_hash_table_new (g_str_hash,
+				    g_str_equal);
+
+  pdata->callback = callback;
+  pdata->data = data;
+  g_hash_table_insert (gpattern_ht, pdbname,pdata);
+
+  return pdbname;
+}
diff --git a/libgimp/gimpmenu.h b/libgimp/gimpmenu.h
index 0cc2b9f040..bb8f5bfe78 100644
--- a/libgimp/gimpmenu.h
+++ b/libgimp/gimpmenu.h
@@ -32,7 +32,6 @@ typedef void (* GimpMenuCallback)     (gint32    any_id,
 				       gpointer  data);
 
 
-/* Popup the brush dialog interactively */
 typedef void (* GimpRunBrushCallback)    (gchar    *name,
 					  gdouble   opacity,
 					  gint      spacing,
@@ -43,7 +42,16 @@ typedef void (* GimpRunBrushCallback)    (gchar    *name,
 					  gboolean  dialog_closing,
 					  gpointer  user_data);
 
-/* Popup the pattern dialog */
+typedef void (* GimpRunFontCallback)     (gchar    *name,
+					  gboolean  dialog_closing,
+					  gpointer  user_data);
+
+typedef void (* GimpRunGradientCallback) (gchar    *name,
+					  gint      width,
+					  gdouble  *grad_data,
+					  gboolean  dialog_closing,
+					  gpointer  user_data);
+
 typedef void (* GimpRunPatternCallback)  (gchar    *name,
 					  gint      width,
 					  gint      height,
@@ -52,13 +60,6 @@ typedef void (* GimpRunPatternCallback)  (gchar    *name,
 					  gboolean  dialog_closing,
 					  gpointer  user_data);
   
-/* Popup the gradient dialog */
-typedef void (* GimpRunGradientCallback) (gchar    *name,
-					  gint      width,
-					  gdouble  *grad_data,
-					  gboolean  dialog_closing,
-					  gpointer  user_data);
-
 
 GtkWidget * gimp_image_menu_new    (GimpConstraintFunc constraint,
 				    GimpMenuCallback   callback,
@@ -101,19 +102,21 @@ void      gimp_brush_select_widget_set_popup   (GtkWidget *widget,
 						gint       paint_mode);
 void      gimp_brush_select_widget_close_popup (GtkWidget *widget);
   
-gchar   * gimp_interactive_selection_pattern      (gchar     *dialogtitle,
-						   gchar     *pattern_name,
-						   GimpRunPatternCallback  callback,
-						   gpointer   data);
 
-GtkWidget * gimp_pattern_select_widget            (gchar     *dname,
-						   gchar     *ipattern, 
-						   GimpRunPatternCallback  cback,
-						   gpointer    data);
+gchar   * gimp_interactive_selection_font      (gchar     *dialogtitle,
+                                                gchar     *font_name,
+                                                GimpRunFontCallback  callback,
+                                                gpointer   data);
+
+GtkWidget * gimp_font_select_widget            (gchar     *dname,
+                                                gchar     *ifont, 
+                                                GimpRunFontCallback  cback,
+                                                gpointer    data);
   
-void      gimp_pattern_select_widget_close_popup  (GtkWidget *widget);
-void      gimp_pattern_select_widget_set_popup    (GtkWidget *widget,
-						   gchar     *pname);
+void      gimp_font_select_widget_close_popup  (GtkWidget *widget);
+void      gimp_font_select_widget_set_popup    (GtkWidget *widget,
+                                                gchar     *fname);
+
 
 gchar   * gimp_interactive_selection_gradient     (gchar      *dialogtitle,
 						   gchar      *gradient_name,
@@ -131,6 +134,21 @@ void      gimp_gradient_select_widget_set_popup   (GtkWidget  *widget,
 						   gchar      *gname);
 
 
+gchar   * gimp_interactive_selection_pattern      (gchar     *dialogtitle,
+						   gchar     *pattern_name,
+						   GimpRunPatternCallback  callback,
+						   gpointer   data);
+
+GtkWidget * gimp_pattern_select_widget            (gchar     *dname,
+						   gchar     *ipattern, 
+						   GimpRunPatternCallback  cback,
+						   gpointer    data);
+  
+void      gimp_pattern_select_widget_close_popup  (GtkWidget *widget);
+void      gimp_pattern_select_widget_set_popup    (GtkWidget *widget,
+						   gchar     *pname);
+
+
 G_END_DECLS
 
 #endif /* __GIMP_MENU_H__ */
diff --git a/plug-ins/script-fu/script-fu-interface.c b/plug-ins/script-fu/script-fu-interface.c
index 5f16aef8f5..e677236ca8 100644
--- a/plug-ins/script-fu/script-fu-interface.c
+++ b/plug-ins/script-fu/script-fu-interface.c
@@ -45,9 +45,6 @@
 #define COLOR_SAMPLE_WIDTH   100
 #define COLOR_SAMPLE_HEIGHT   15
 #define SLIDER_WIDTH         100
-#define FONT_PREVIEW_WIDTH   100
-
-#define DEFAULT_FONT_SIZE    240
 
 #define MAX_STRING_LENGTH   4096
 
@@ -64,13 +61,6 @@ typedef struct
   SFAdjustmentType  type;
 } SFAdjustment;
 
-typedef struct
-{
-  GtkWidget *preview;
-  GtkWidget *dialog;
-  gchar     *fontname;
-} SFFont;
-
 typedef struct
 {
   GtkWidget *fileselection;
@@ -101,10 +91,10 @@ typedef union
   gint32         sfa_toggle;
   gchar         *sfa_value;
   SFAdjustment   sfa_adjustment;
-  SFFont         sfa_font;
   SFFilename     sfa_file;
-  gchar         *sfa_pattern;
+  gchar         *sfa_font;
   gchar         *sfa_gradient;
+  gchar         *sfa_pattern;
   SFBrush        sfa_brush;
   SFOption       sfa_option;
 } SFArgValue;
@@ -179,19 +169,6 @@ static void       script_fu_menu_callback           (gint32     id,
 static void       script_fu_file_selection_callback (GtkWidget *widget,
 						     gpointer   data);
 
-static void       script_fu_font_preview_callback   (GtkWidget *widget,
-						     gpointer   data);
-
-static void       script_fu_font_dialog_ok          (GtkWidget *widget,
-						     gpointer   data);
-static void       script_fu_font_dialog_cancel      (GtkWidget *widget,
-						     gpointer   data);
-static gboolean   script_fu_font_dialog_delete      (GtkWidget *widget,
-						     GdkEvent  *event,
-						     gpointer   data);
-
-static void       script_fu_font_preview            (GtkWidget *preview,
-						     gchar     *fontname);
 static void       script_fu_pattern_preview         (gchar     *name,
 						     gint       width,
 						     gint       height,
@@ -204,6 +181,9 @@ static void       script_fu_gradient_preview        (gchar     *name,
 						     gdouble   *mask_data,
 						     gboolean   closing,
 						     gpointer   data);
+static void       script_fu_font_preview            (gchar     *name,
+                                                     gboolean   closing,
+                                                     gpointer   data);
 static void       script_fu_brush_preview           (gchar     *name,
 						     gdouble    opacity,
 						     gint       spacing,
@@ -629,12 +609,10 @@ script_fu_add_script (LISP a)
 		case SF_FONT:
 		  if (!TYPEP (car (a), tc_string))
 		    return my_err ("script-fu-register: font defaults must be string values", NIL);
-		  script->arg_defaults[i].sfa_font.fontname = 
-		    g_strdup (get_c_string (car (a)));
-		  script->arg_values[i].sfa_font.fontname =  
-		    g_strdup (script->arg_defaults[i].sfa_font.fontname);
-		  script->arg_values[i].sfa_font.preview = NULL;
-		  script->arg_values[i].sfa_font.dialog = NULL;
+		  script->arg_defaults[i].sfa_font =
+                    g_strdup (get_c_string (car (a)));
+		  script->arg_values[i].sfa_font =
+                    g_strdup (script->arg_defaults[i].sfa_font);
 		  
 		  args[i + 1].type = GIMP_PDB_STRING;
 		  args[i + 1].name = "font";
@@ -1104,8 +1082,8 @@ script_fu_free_script (SFScript *script)
 	      break;
 
 	    case SF_FONT:
-	      g_free (script->arg_defaults[i].sfa_font.fontname);
-	      g_free (script->arg_values[i].sfa_font.fontname);
+	      g_free (script->arg_defaults[i].sfa_font);
+	      g_free (script->arg_values[i].sfa_font);
 	      break;
 
 	    case SF_PATTERN:
@@ -1409,21 +1387,11 @@ script_fu_interface (SFScript *script)
 	case SF_FONT:
 	  widget_leftalign = FALSE;
 
-	  sf_interface->args_widgets[i] = gtk_button_new ();
-	  script->arg_values[i].sfa_font.preview = gtk_label_new ("");
-	  script->arg_values[i].sfa_font.dialog = NULL;
-	  gtk_widget_set_size_request (sf_interface->args_widgets[i], 
-                                       FONT_PREVIEW_WIDTH, -1);
-	  gtk_container_add (GTK_CONTAINER (sf_interface->args_widgets[i]),
-			     script->arg_values[i].sfa_font.preview);
-	  gtk_widget_show (script->arg_values[i].sfa_font.preview);
-
-	  script_fu_font_preview (script->arg_values[i].sfa_font.preview,
-				  script->arg_values[i].sfa_font.fontname);
-
-	  g_signal_connect (sf_interface->args_widgets[i], "clicked",
-			    G_CALLBACK (script_fu_font_preview_callback),
-			    &script->arg_values[i].sfa_font);	  
+	  sf_interface->args_widgets[i] = 
+	    gimp_font_select_widget (_("Script-Fu Font Selection"),
+                                     script->arg_values[i].sfa_font,
+                                     script_fu_font_preview,
+                                     &script->arg_values[i].sfa_font);
 	  break;
 
 	case SF_PATTERN:
@@ -1524,11 +1492,7 @@ script_fu_interface_quit (SFScript *script)
     switch (script->arg_types[i])
       {
       case SF_FONT:
-	if (script->arg_values[i].sfa_font.dialog != NULL)
-	  {
-	    gtk_widget_destroy (script->arg_values[i].sfa_font.dialog);
-	    script->arg_values[i].sfa_font.dialog = NULL;
-	  }
+  	gimp_font_select_widget_close_popup (sf_interface->args_widgets[i]);
 	break;
 
       case SF_PATTERN:
@@ -1594,6 +1558,19 @@ script_fu_gradient_preview (gchar    *name,
   *gname = g_strdup (name);
 }
 
+static void
+script_fu_font_preview (gchar    *name,
+                        gboolean  closing,
+                        gpointer  data)
+{
+  gchar **fname;
+
+  fname = (gchar **) data;
+
+  g_free (*fname);
+  *fname = g_strdup (name);
+}
+
 static void      
 script_fu_brush_preview (gchar    *name,
 			 gdouble   opacity,
@@ -1617,14 +1594,6 @@ script_fu_brush_preview (gchar    *name,
   brush->paint_mode = paint_mode;
 }
 
-static void
-script_fu_font_preview (GtkWidget *preview,
-			gchar     *data)
-{
-  /* FIXME: here should be a check if the fontname is valid and the font is present */
-  gtk_label_set_text (GTK_LABEL (preview), data);
-}
-
 static void
 script_fu_ok_callback (GtkWidget *widget,
 		       gpointer   data)
@@ -1641,25 +1610,6 @@ script_fu_ok_callback (GtkWidget *widget,
 
   SFScript  *script = (SFScript *) data;
   
-#if 0
-  GdkFont   *font;
-
-  /* Check if choosen fonts are there */
-  for (i = 0; i < script->num_args; i++)
-    if (script->arg_types[i] == SF_FONT)
-      {
-	font = gdk_font_load (script->arg_values[i].sfa_font.fontname);
-	if (font == NULL)
-	  {
-	    g_message (_("At least one font you've choosen is invalid.\n"
-			 "Please check your settings.\n"));
-	    return;
-	  }
-	else
-	  gdk_font_unref (font);
-      }
-#endif
-  
   length = strlen (script->script_name) + 3;
 
   for (i = 0; i < script->num_args; i++)
@@ -1702,7 +1652,7 @@ script_fu_ok_callback (GtkWidget *widget,
 	break;
 
       case SF_FONT:
-	length += strlen (script->arg_values[i].sfa_font.fontname) + 3;
+	length += strlen (script->arg_values[i].sfa_font) + 3;
 	break;
 
       case SF_PATTERN:
@@ -1807,7 +1757,7 @@ script_fu_ok_callback (GtkWidget *widget,
 
 	case SF_FONT:
 	  g_snprintf (buffer, sizeof (buffer), "\"%s\"",
-		      script->arg_values[i].sfa_font.fontname);
+		      script->arg_values[i].sfa_font);
 	  text = buffer;
 	  break;
 
@@ -2041,17 +1991,8 @@ script_fu_reset_callback (GtkWidget *widget,
 	break;
 
       case SF_FONT:
-	g_free (script->arg_values[i].sfa_font.fontname);
-	script->arg_values[i].sfa_font.fontname =
-	  g_strdup (script->arg_defaults[i].sfa_font.fontname);
-	if (script->arg_values[i].sfa_font.dialog)
-	  {
-	    gtk_font_selection_dialog_set_font_name
-	      (GTK_FONT_SELECTION_DIALOG (script->arg_values[i].sfa_font.dialog),
-	       script->arg_values[i].sfa_font.fontname);
-	  }	
-	script_fu_font_preview (script->arg_values[i].sfa_font.preview,
-				script->arg_values[i].sfa_font.fontname);
+  	gimp_font_select_widget_set_popup
+	  (sf_interface->args_widgets[i], script->arg_defaults[i].sfa_font);  
 	break;
 
       case SF_PATTERN:
@@ -2106,85 +2047,6 @@ script_fu_file_selection_callback (GtkWidget *widget,
     gimp_file_selection_get_filename (GIMP_FILE_SELECTION (file->fileselection));
 }
 
-static void
-script_fu_font_preview_callback (GtkWidget *widget,
-				 gpointer   data)
-{
-  GtkFontSelectionDialog *fsd;
-  SFFont                 *font;
-
-  font = (SFFont *) data;
-
-  if (! font->dialog)
-    {
-      font->dialog =
-	gtk_font_selection_dialog_new (_("Script-Fu Font Selection"));
-      fsd = GTK_FONT_SELECTION_DIALOG (font->dialog);
-
-      g_signal_connect (fsd->ok_button, "clicked",
-			G_CALLBACK (script_fu_font_dialog_ok),
-			font);
-      g_signal_connect (fsd, "delete_event",
-			G_CALLBACK (script_fu_font_dialog_delete),
-			font);
-      g_signal_connect (fsd, "destroy",
-			G_CALLBACK (gtk_widget_destroyed),
-			&font->dialog);
-      g_signal_connect (fsd->cancel_button, "clicked",
-			G_CALLBACK (script_fu_font_dialog_cancel),
-			font);
-    }
-  else
-    {
-      fsd = GTK_FONT_SELECTION_DIALOG (font->dialog);
-    }
-
-  gtk_font_selection_dialog_set_font_name (fsd, font->fontname);
-  gtk_window_set_position (GTK_WINDOW (font->dialog), GTK_WIN_POS_MOUSE);
-  gtk_widget_show (font->dialog);
-}
-
-static void
-script_fu_font_dialog_ok (GtkWidget *widget,
-			  gpointer   data)
-{
-  SFFont *font;
-  gchar  *fontname;
-
-  font = (SFFont *) data;
-
-  fontname = 
-    gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font->dialog));
-  if (fontname != NULL)
-    {
-      g_free (font->fontname);
-      font->fontname = fontname;
-    }
-  gtk_widget_hide (font->dialog);
-
-  script_fu_font_preview (font->preview, font->fontname);
-}
-
-static void
-script_fu_font_dialog_cancel (GtkWidget *widget,
-			      gpointer   data)
-{
-  SFFont *font;
-
-  font = (SFFont *) data;
-
-  gtk_widget_hide (font->dialog);
-}
-
-static gboolean
-script_fu_font_dialog_delete (GtkWidget *widget,
-			      GdkEvent  *event,
-			      gpointer   data)
-{
-  script_fu_font_dialog_cancel (widget, data);
-  return TRUE;
-}
-
 static void
 script_fu_error_msg (gchar *command)
 {
diff --git a/plug-ins/script-fu/script-fu-scripts.c b/plug-ins/script-fu/script-fu-scripts.c
index 5f16aef8f5..e677236ca8 100644
--- a/plug-ins/script-fu/script-fu-scripts.c
+++ b/plug-ins/script-fu/script-fu-scripts.c
@@ -45,9 +45,6 @@
 #define COLOR_SAMPLE_WIDTH   100
 #define COLOR_SAMPLE_HEIGHT   15
 #define SLIDER_WIDTH         100
-#define FONT_PREVIEW_WIDTH   100
-
-#define DEFAULT_FONT_SIZE    240
 
 #define MAX_STRING_LENGTH   4096
 
@@ -64,13 +61,6 @@ typedef struct
   SFAdjustmentType  type;
 } SFAdjustment;
 
-typedef struct
-{
-  GtkWidget *preview;
-  GtkWidget *dialog;
-  gchar     *fontname;
-} SFFont;
-
 typedef struct
 {
   GtkWidget *fileselection;
@@ -101,10 +91,10 @@ typedef union
   gint32         sfa_toggle;
   gchar         *sfa_value;
   SFAdjustment   sfa_adjustment;
-  SFFont         sfa_font;
   SFFilename     sfa_file;
-  gchar         *sfa_pattern;
+  gchar         *sfa_font;
   gchar         *sfa_gradient;
+  gchar         *sfa_pattern;
   SFBrush        sfa_brush;
   SFOption       sfa_option;
 } SFArgValue;
@@ -179,19 +169,6 @@ static void       script_fu_menu_callback           (gint32     id,
 static void       script_fu_file_selection_callback (GtkWidget *widget,
 						     gpointer   data);
 
-static void       script_fu_font_preview_callback   (GtkWidget *widget,
-						     gpointer   data);
-
-static void       script_fu_font_dialog_ok          (GtkWidget *widget,
-						     gpointer   data);
-static void       script_fu_font_dialog_cancel      (GtkWidget *widget,
-						     gpointer   data);
-static gboolean   script_fu_font_dialog_delete      (GtkWidget *widget,
-						     GdkEvent  *event,
-						     gpointer   data);
-
-static void       script_fu_font_preview            (GtkWidget *preview,
-						     gchar     *fontname);
 static void       script_fu_pattern_preview         (gchar     *name,
 						     gint       width,
 						     gint       height,
@@ -204,6 +181,9 @@ static void       script_fu_gradient_preview        (gchar     *name,
 						     gdouble   *mask_data,
 						     gboolean   closing,
 						     gpointer   data);
+static void       script_fu_font_preview            (gchar     *name,
+                                                     gboolean   closing,
+                                                     gpointer   data);
 static void       script_fu_brush_preview           (gchar     *name,
 						     gdouble    opacity,
 						     gint       spacing,
@@ -629,12 +609,10 @@ script_fu_add_script (LISP a)
 		case SF_FONT:
 		  if (!TYPEP (car (a), tc_string))
 		    return my_err ("script-fu-register: font defaults must be string values", NIL);
-		  script->arg_defaults[i].sfa_font.fontname = 
-		    g_strdup (get_c_string (car (a)));
-		  script->arg_values[i].sfa_font.fontname =  
-		    g_strdup (script->arg_defaults[i].sfa_font.fontname);
-		  script->arg_values[i].sfa_font.preview = NULL;
-		  script->arg_values[i].sfa_font.dialog = NULL;
+		  script->arg_defaults[i].sfa_font =
+                    g_strdup (get_c_string (car (a)));
+		  script->arg_values[i].sfa_font =
+                    g_strdup (script->arg_defaults[i].sfa_font);
 		  
 		  args[i + 1].type = GIMP_PDB_STRING;
 		  args[i + 1].name = "font";
@@ -1104,8 +1082,8 @@ script_fu_free_script (SFScript *script)
 	      break;
 
 	    case SF_FONT:
-	      g_free (script->arg_defaults[i].sfa_font.fontname);
-	      g_free (script->arg_values[i].sfa_font.fontname);
+	      g_free (script->arg_defaults[i].sfa_font);
+	      g_free (script->arg_values[i].sfa_font);
 	      break;
 
 	    case SF_PATTERN:
@@ -1409,21 +1387,11 @@ script_fu_interface (SFScript *script)
 	case SF_FONT:
 	  widget_leftalign = FALSE;
 
-	  sf_interface->args_widgets[i] = gtk_button_new ();
-	  script->arg_values[i].sfa_font.preview = gtk_label_new ("");
-	  script->arg_values[i].sfa_font.dialog = NULL;
-	  gtk_widget_set_size_request (sf_interface->args_widgets[i], 
-                                       FONT_PREVIEW_WIDTH, -1);
-	  gtk_container_add (GTK_CONTAINER (sf_interface->args_widgets[i]),
-			     script->arg_values[i].sfa_font.preview);
-	  gtk_widget_show (script->arg_values[i].sfa_font.preview);
-
-	  script_fu_font_preview (script->arg_values[i].sfa_font.preview,
-				  script->arg_values[i].sfa_font.fontname);
-
-	  g_signal_connect (sf_interface->args_widgets[i], "clicked",
-			    G_CALLBACK (script_fu_font_preview_callback),
-			    &script->arg_values[i].sfa_font);	  
+	  sf_interface->args_widgets[i] = 
+	    gimp_font_select_widget (_("Script-Fu Font Selection"),
+                                     script->arg_values[i].sfa_font,
+                                     script_fu_font_preview,
+                                     &script->arg_values[i].sfa_font);
 	  break;
 
 	case SF_PATTERN:
@@ -1524,11 +1492,7 @@ script_fu_interface_quit (SFScript *script)
     switch (script->arg_types[i])
       {
       case SF_FONT:
-	if (script->arg_values[i].sfa_font.dialog != NULL)
-	  {
-	    gtk_widget_destroy (script->arg_values[i].sfa_font.dialog);
-	    script->arg_values[i].sfa_font.dialog = NULL;
-	  }
+  	gimp_font_select_widget_close_popup (sf_interface->args_widgets[i]);
 	break;
 
       case SF_PATTERN:
@@ -1594,6 +1558,19 @@ script_fu_gradient_preview (gchar    *name,
   *gname = g_strdup (name);
 }
 
+static void
+script_fu_font_preview (gchar    *name,
+                        gboolean  closing,
+                        gpointer  data)
+{
+  gchar **fname;
+
+  fname = (gchar **) data;
+
+  g_free (*fname);
+  *fname = g_strdup (name);
+}
+
 static void      
 script_fu_brush_preview (gchar    *name,
 			 gdouble   opacity,
@@ -1617,14 +1594,6 @@ script_fu_brush_preview (gchar    *name,
   brush->paint_mode = paint_mode;
 }
 
-static void
-script_fu_font_preview (GtkWidget *preview,
-			gchar     *data)
-{
-  /* FIXME: here should be a check if the fontname is valid and the font is present */
-  gtk_label_set_text (GTK_LABEL (preview), data);
-}
-
 static void
 script_fu_ok_callback (GtkWidget *widget,
 		       gpointer   data)
@@ -1641,25 +1610,6 @@ script_fu_ok_callback (GtkWidget *widget,
 
   SFScript  *script = (SFScript *) data;
   
-#if 0
-  GdkFont   *font;
-
-  /* Check if choosen fonts are there */
-  for (i = 0; i < script->num_args; i++)
-    if (script->arg_types[i] == SF_FONT)
-      {
-	font = gdk_font_load (script->arg_values[i].sfa_font.fontname);
-	if (font == NULL)
-	  {
-	    g_message (_("At least one font you've choosen is invalid.\n"
-			 "Please check your settings.\n"));
-	    return;
-	  }
-	else
-	  gdk_font_unref (font);
-      }
-#endif
-  
   length = strlen (script->script_name) + 3;
 
   for (i = 0; i < script->num_args; i++)
@@ -1702,7 +1652,7 @@ script_fu_ok_callback (GtkWidget *widget,
 	break;
 
       case SF_FONT:
-	length += strlen (script->arg_values[i].sfa_font.fontname) + 3;
+	length += strlen (script->arg_values[i].sfa_font) + 3;
 	break;
 
       case SF_PATTERN:
@@ -1807,7 +1757,7 @@ script_fu_ok_callback (GtkWidget *widget,
 
 	case SF_FONT:
 	  g_snprintf (buffer, sizeof (buffer), "\"%s\"",
-		      script->arg_values[i].sfa_font.fontname);
+		      script->arg_values[i].sfa_font);
 	  text = buffer;
 	  break;
 
@@ -2041,17 +1991,8 @@ script_fu_reset_callback (GtkWidget *widget,
 	break;
 
       case SF_FONT:
-	g_free (script->arg_values[i].sfa_font.fontname);
-	script->arg_values[i].sfa_font.fontname =
-	  g_strdup (script->arg_defaults[i].sfa_font.fontname);
-	if (script->arg_values[i].sfa_font.dialog)
-	  {
-	    gtk_font_selection_dialog_set_font_name
-	      (GTK_FONT_SELECTION_DIALOG (script->arg_values[i].sfa_font.dialog),
-	       script->arg_values[i].sfa_font.fontname);
-	  }	
-	script_fu_font_preview (script->arg_values[i].sfa_font.preview,
-				script->arg_values[i].sfa_font.fontname);
+  	gimp_font_select_widget_set_popup
+	  (sf_interface->args_widgets[i], script->arg_defaults[i].sfa_font);  
 	break;
 
       case SF_PATTERN:
@@ -2106,85 +2047,6 @@ script_fu_file_selection_callback (GtkWidget *widget,
     gimp_file_selection_get_filename (GIMP_FILE_SELECTION (file->fileselection));
 }
 
-static void
-script_fu_font_preview_callback (GtkWidget *widget,
-				 gpointer   data)
-{
-  GtkFontSelectionDialog *fsd;
-  SFFont                 *font;
-
-  font = (SFFont *) data;
-
-  if (! font->dialog)
-    {
-      font->dialog =
-	gtk_font_selection_dialog_new (_("Script-Fu Font Selection"));
-      fsd = GTK_FONT_SELECTION_DIALOG (font->dialog);
-
-      g_signal_connect (fsd->ok_button, "clicked",
-			G_CALLBACK (script_fu_font_dialog_ok),
-			font);
-      g_signal_connect (fsd, "delete_event",
-			G_CALLBACK (script_fu_font_dialog_delete),
-			font);
-      g_signal_connect (fsd, "destroy",
-			G_CALLBACK (gtk_widget_destroyed),
-			&font->dialog);
-      g_signal_connect (fsd->cancel_button, "clicked",
-			G_CALLBACK (script_fu_font_dialog_cancel),
-			font);
-    }
-  else
-    {
-      fsd = GTK_FONT_SELECTION_DIALOG (font->dialog);
-    }
-
-  gtk_font_selection_dialog_set_font_name (fsd, font->fontname);
-  gtk_window_set_position (GTK_WINDOW (font->dialog), GTK_WIN_POS_MOUSE);
-  gtk_widget_show (font->dialog);
-}
-
-static void
-script_fu_font_dialog_ok (GtkWidget *widget,
-			  gpointer   data)
-{
-  SFFont *font;
-  gchar  *fontname;
-
-  font = (SFFont *) data;
-
-  fontname = 
-    gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font->dialog));
-  if (fontname != NULL)
-    {
-      g_free (font->fontname);
-      font->fontname = fontname;
-    }
-  gtk_widget_hide (font->dialog);
-
-  script_fu_font_preview (font->preview, font->fontname);
-}
-
-static void
-script_fu_font_dialog_cancel (GtkWidget *widget,
-			      gpointer   data)
-{
-  SFFont *font;
-
-  font = (SFFont *) data;
-
-  gtk_widget_hide (font->dialog);
-}
-
-static gboolean
-script_fu_font_dialog_delete (GtkWidget *widget,
-			      GdkEvent  *event,
-			      gpointer   data)
-{
-  script_fu_font_dialog_cancel (widget, data);
-  return TRUE;
-}
-
 static void
 script_fu_error_msg (gchar *command)
 {
diff --git a/tools/pdbgen/Makefile.am b/tools/pdbgen/Makefile.am
index dfe98179ab..f6db2bb212 100644
--- a/tools/pdbgen/Makefile.am
+++ b/tools/pdbgen/Makefile.am
@@ -12,6 +12,7 @@ pdb_sources = \
 	pdb/edit.pdb		\
 	pdb/fileops.pdb		\
 	pdb/floating_sel.pdb	\
+	pdb/font_select.pdb	\
 	pdb/gimprc.pdb		\
 	pdb/gradient_select.pdb	\
 	pdb/gradients.pdb	\
diff --git a/tools/pdbgen/groups.pl b/tools/pdbgen/groups.pl
index 0315cf933c..7bf8f3c59e 100644
--- a/tools/pdbgen/groups.pl
+++ b/tools/pdbgen/groups.pl
@@ -10,6 +10,7 @@
     edit
     fileops
     floating_sel
+    font_select
     gimprc
     gradient_select
     gradients
diff --git a/tools/pdbgen/pdb/font_select.pdb b/tools/pdbgen/pdb/font_select.pdb
new file mode 100644
index 0000000000..43884e1249
--- /dev/null
+++ b/tools/pdbgen/pdb/font_select.pdb
@@ -0,0 +1,141 @@
+# The GIMP -- an image manipulation program
+# Copyright (C) 1995 Spencer Kimball and Peter Mattis
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# "Perlized" from C source by Manish Singh <yosh@gimp.org>
+
+sub pdb_misc {
+    $author = 'Sven Neumann  <sven@gimp.org>';
+    $copyright = 'Sven Neumann';
+    $date = '2003';
+}
+
+sub fonts_popup {
+    $blurb = 'Invokes the Gimp font selection.';
+
+    $help = 'This procedure popups the font selection dialog.';
+
+    &pdb_misc;
+
+    @inargs = (
+	{ name => 'font_callback', type => 'string',
+	  desc => 'The callback PDB proc to call when font selection is
+		   made' },
+	{ name => 'popup_title', type => 'string',
+	  desc => 'Title to give the font popup window' },
+	{ name => 'initial_font', type => 'string',
+	  desc => 'The name of the font to set as the first selected',
+	  no_success => 1 }
+    );
+
+    %invoke = (
+	vars => [ 'ProcRecord *proc' ],
+	code => <<'CODE'
+{
+  if (! gimp->no_interface &&
+      (proc = procedural_db_lookup (gimp, font_callback)))
+    {
+      font_select_new (gimp, popup_title, initial_font, font_callback);
+    }
+  else
+    {
+      success = FALSE;
+    }
+}
+CODE
+    );
+}
+
+sub fonts_close_popup {
+    $blurb = 'Popdown the Gimp font selection.';
+
+    $help = 'This procedure closes an opened font selection dialog.';
+
+    &pdb_misc;
+
+    @inargs = (
+	{ name => 'font_callback', type => 'string',
+	  desc => 'The name of the callback registered for this popup' }
+    );
+
+    %invoke = (
+	vars => [ 'ProcRecord *proc', 'FontSelect *font_select' ],
+	code => <<'CODE'
+{
+  if (! gimp->no_interface &&
+      (proc = procedural_db_lookup (gimp, font_callback)) &&
+      (font_select = font_select_get_by_callback (font_callback)))
+    {
+      font_select_free (font_select);
+    }
+  else
+    {
+      success = FALSE;
+    }
+}
+CODE
+    );
+}
+
+sub fonts_set_popup {
+    $blurb = 'Sets the current font selection in a popup.';
+
+    $help = $blurb;
+
+    &pdb_misc;
+
+    @inargs = (
+	{ name => 'font_callback', type => 'string',
+	  desc => 'The name of the callback registered for this popup' },
+	{ name => 'font_name', type => 'string',
+	  desc => 'The name of the font to set as selected' }
+    );
+
+    %invoke = (
+	vars => [ 'ProcRecord *proc', 'FontSelect *font_select' ],
+	code => <<'CODE'
+{
+  if (! gimp->no_interface &&
+      (proc = procedural_db_lookup (gimp, font_callback)) &&
+      (font_select = font_select_get_by_callback (font_callback)))
+    {
+      GimpFont *active = (GimpFont *)
+        gimp_container_get_child_by_name (gimp->fonts, font_name);
+
+      success = (active != NULL);
+
+      if (success)
+	{
+	  gimp_context_set_font (font_select->context, active);
+	}
+    }
+  else
+    success = FALSE;
+}
+CODE
+    );
+}
+
+@headers = qw("core/gimp.h" "core/gimpcontext.h"
+	      "core/gimpcontainer.h"
+              "gui/gui-types.h" "gui/font-select.h");
+
+@procs = qw(fonts_popup fonts_close_popup fonts_set_popup);
+%exports = (app => [@procs], lib => [@procs]);
+
+$desc = 'Font UI';
+
+1;