[gimp] app: simplify symmetry GUI generation
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: simplify symmetry GUI generation
- Date: Sat, 6 Feb 2016 22:21:02 +0000 (UTC)
commit 8bb00c639a53b114eb4bd55f9a6ff0d1da9bfd04
Author: Michael Natterer <mitch gimp org>
Date: Sat Feb 6 23:08:18 2016 +0100
app: simplify symmetry GUI generation
Remove GimpSymmetry::get_settings() and instead tag the properties that
should have a GUI with the GIMP_SYMMETRY_PARAM_GUI flag. Also use plain
g_object_class_install_property() because that allows for separate nick
and blurb. Finally, use gimp_prop_gui_new() to generate the GUI,
app/core/gimpsymmetry-mandala.c | 52 ++++++++------------
app/core/gimpsymmetry-mirror.c | 80 ++++++++++++++-----------------
app/core/gimpsymmetry-tiling.c | 96 ++++++++++++++++++-------------------
app/core/gimpsymmetry.c | 67 +++++++-------------------
app/core/gimpsymmetry.h | 9 ++--
app/widgets/gimpsymmetryeditor.c | 97 +++++--------------------------------
6 files changed, 135 insertions(+), 266 deletions(-)
---
diff --git a/app/core/gimpsymmetry-mandala.c b/app/core/gimpsymmetry-mandala.c
index 8ad97f1..de221f2 100644
--- a/app/core/gimpsymmetry-mandala.c
+++ b/app/core/gimpsymmetry-mandala.c
@@ -85,10 +85,7 @@ static GeglNode * gimp_mandala_get_operation (GimpSymmetry *mandala,
gint stroke,
gint paint_width,
gint paint_height);
-static GParamSpec ** gimp_mandala_get_settings (GimpSymmetry *sym,
- gint *n_settings);
-static void
- gimp_mandala_image_size_changed_cb (GimpImage *image ,
+static void gimp_mandala_image_size_changed_cb (GimpImage *image ,
gint previous_origin_x,
gint previous_origin_y,
gint previous_width,
@@ -115,26 +112,35 @@ gimp_mandala_class_init (GimpMandalaClass *klass)
symmetry_class->label = _("Mandala");
symmetry_class->update_strokes = gimp_mandala_update_strokes;
symmetry_class->get_operation = gimp_mandala_get_operation;
- symmetry_class->get_settings = gimp_mandala_get_settings;
symmetry_class->active_changed = gimp_mandala_active_changed;
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CENTER_X,
"center-x", _("Center abscisse"),
0.0, 10000.0, 0.0,
GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CENTER_Y,
"center-y", _("Center ordinate"),
0.0, 10000.0, 0.0,
GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_SIZE,
- "size", _("Number of points"),
- 1, 100, 6.0,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_DISABLE_TRANSFORMATION,
- "disable-transformation",
- _("Disable Brush Transformation (faster)"),
- FALSE,
- GIMP_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_property (object_class, PROP_SIZE,
+ g_param_spec_int ("size",
+ _("Number of points"),
+ _("Number of points"),
+ 1, 100, 6.0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_DISABLE_TRANSFORMATION,
+ g_param_spec_boolean ("disable-transformation",
+ _("Disable brush transform"),
+ _("Disable brush transformation (faster)"),
+ FALSE,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
}
static void
@@ -506,24 +512,6 @@ gimp_mandala_get_operation (GimpSymmetry *sym,
return op;
}
-static GParamSpec **
-gimp_mandala_get_settings (GimpSymmetry *sym,
- gint *n_settings)
-{
- GParamSpec **pspecs;
-
- *n_settings = 3;
- pspecs = g_new (GParamSpec*, 3);
-
- pspecs[0] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "size");
- pspecs[1] = NULL;
- pspecs[2] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "disable-transformation");
-
- return pspecs;
-}
-
static void
gimp_mandala_image_size_changed_cb (GimpImage *image,
gint previous_origin_x,
diff --git a/app/core/gimpsymmetry-mirror.c b/app/core/gimpsymmetry-mirror.c
index a31a3a6..11954b7 100644
--- a/app/core/gimpsymmetry-mirror.c
+++ b/app/core/gimpsymmetry-mirror.c
@@ -87,8 +87,6 @@ static void gimp_mirror_guide_removed_cb (GObject *obje
static void gimp_mirror_guide_position_cb (GObject *object,
GParamSpec *pspec,
GimpMirror *mirror);
-static GParamSpec ** gimp_mirror_get_settings (GimpSymmetry *sym,
- gint *n_settings);
static void gimp_mirror_active_changed (GimpSymmetry *sym);
static void gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
gboolean active);
@@ -116,30 +114,44 @@ gimp_mirror_class_init (GimpMirrorClass *klass)
symmetry_class->label = _("Mirror");
symmetry_class->update_strokes = gimp_mirror_update_strokes;
symmetry_class->get_operation = gimp_mirror_get_operation;
- symmetry_class->get_settings = gimp_mirror_get_settings;
symmetry_class->active_changed = gimp_mirror_active_changed;
/* Properties for user settings */
- GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HORIZONTAL_SYMMETRY,
- "horizontal-symmetry",
- _("Horizontal Mirror"),
- FALSE,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_VERTICAL_SYMMETRY,
- "vertical-symmetry",
- _("Vertical Mirror"),
- FALSE,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_POINT_SYMMETRY,
- "point-symmetry",
- _("Central Symmetry"),
- FALSE,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_DISABLE_TRANSFORMATION,
- "disable-transformation",
- _("Disable Brush Transformation (faster)"),
- FALSE,
- GIMP_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_HORIZONTAL_SYMMETRY,
+ g_param_spec_boolean ("horizontal-symmetry",
+ _("Horizontal Mirror"),
+ NULL,
+ FALSE,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_VERTICAL_SYMMETRY,
+ g_param_spec_boolean ("vertical-symmetry",
+ _("Vertical Mirror"),
+ NULL,
+ FALSE,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_POINT_SYMMETRY,
+ g_param_spec_boolean ("point-symmetry",
+ _("Central Symmetry"),
+ NULL,
+ FALSE,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_DISABLE_TRANSFORMATION,
+ g_param_spec_boolean ("disable-transformation",
+ _("Disable brush transform"),
+ _("Disable brush transformation (faster)"),
+ FALSE,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
/* Properties for XCF serialization only */
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_HORIZONTAL_POSITION,
@@ -557,28 +569,6 @@ gimp_mirror_guide_position_cb (GObject *object,
}
}
-static GParamSpec **
-gimp_mirror_get_settings (GimpSymmetry *sym,
- gint *n_settings)
-{
- GParamSpec **pspecs;
-
- *n_settings = 5;
- pspecs = g_new (GParamSpec*, 5);
-
- pspecs[0] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "horizontal-symmetry");
- pspecs[1] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "vertical-symmetry");
- pspecs[2] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "point-symmetry");
- pspecs[3] = NULL;
- pspecs[4] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "disable-transformation");
-
- return pspecs;
-}
-
static void
gimp_mirror_active_changed (GimpSymmetry *sym)
{
diff --git a/app/core/gimpsymmetry-tiling.c b/app/core/gimpsymmetry-tiling.c
index 6fd5adc..44d490b 100644
--- a/app/core/gimpsymmetry-tiling.c
+++ b/app/core/gimpsymmetry-tiling.c
@@ -73,10 +73,7 @@ static GeglNode * gimp_tiling_get_operation (GimpSymmetry *tiling,
gint stroke,
gint paint_width,
gint paint_height);
-static GParamSpec ** gimp_tiling_get_settings (GimpSymmetry *sym,
- gint *n_settings);
-static void
- gimp_tiling_image_size_changed_cb (GimpImage *image ,
+static void gimp_tiling_image_size_changed_cb (GimpImage *image,
gint previous_origin_x,
gint previous_origin_y,
gint previous_width,
@@ -103,28 +100,51 @@ gimp_tiling_class_init (GimpTilingClass *klass)
symmetry_class->label = _("Tiling");
symmetry_class->update_strokes = gimp_tiling_update_strokes;
symmetry_class->get_operation = gimp_tiling_get_operation;
- symmetry_class->get_settings = gimp_tiling_get_settings;
-
- GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_X_INTERVAL,
- "x-interval", _("Intervals on x-axis (pixels)"),
- 0.0, 10000.0, 0.0,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_Y_INTERVAL,
- "y-interval", _("Intervals on y-axis (pixels)"),
- 0.0, 10000.0, 0.0,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SHIFT,
- "shift", _("X-shift between lines (pixels)"),
- 0.0, 10000.0, 0.0,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_X_MAX,
- "x-max", _("Max strokes on x-axis"),
- 0, 100, 0,
- GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_Y_MAX,
- "y-max", _("Max strokes on y-axis"),
- 0, 100, 0,
- GIMP_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_property (object_class, PROP_X_INTERVAL,
+ g_param_spec_double ("x-interval",
+ _("Interval X"),
+ _("Interval on the X axis (pixels)"),
+ 0.0, 10000.0, 0.0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_Y_INTERVAL,
+ g_param_spec_double ("y-interval",
+ _("Interval Y"),
+ _("Interval on the Y axis (pixels)"),
+ 0.0, 10000.0, 0.0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_SHIFT,
+ g_param_spec_double ("shift",
+ _("Shift"),
+ _("X-shift between lines (pixels)"),
+ 0.0, 10000.0, 0.0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_X_MAX,
+ g_param_spec_int ("x-max",
+ _("Max strokes X"),
+ _("Maximum number of strokes on the X axis"),
+ 0, 100, 0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
+
+ g_object_class_install_property (object_class, PROP_Y_MAX,
+ g_param_spec_int ("y-max",
+ _("Max strokes Y"),
+ _("Maximum number of strokes on the Y axis"),
+ 0, 100, 0,
+ GIMP_CONFIG_PARAM_FLAGS |
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_SYMMETRY_PARAM_GUI));
}
static void
@@ -349,30 +369,6 @@ gimp_tiling_get_operation (GimpSymmetry *sym,
return NULL;
}
-static GParamSpec **
-gimp_tiling_get_settings (GimpSymmetry *sym,
- gint *n_settings)
-{
- GParamSpec **pspecs;
-
- *n_settings = 6;
- pspecs = g_new (GParamSpec*, 6);
-
- pspecs[0] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "x-interval");
- pspecs[1] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "y-interval");
- pspecs[2] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "shift");
- pspecs[3] = NULL;
- pspecs[4] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "x-max");
- pspecs[5] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
- "y-max");
-
- return pspecs;
-}
-
static void
gimp_tiling_image_size_changed_cb (GimpImage *image,
gint previous_origin_x,
diff --git a/app/core/gimpsymmetry.c b/app/core/gimpsymmetry.c
index 077bd63..04addd7 100644
--- a/app/core/gimpsymmetry.c
+++ b/app/core/gimpsymmetry.c
@@ -57,28 +57,23 @@ enum
/* Local function prototypes */
-static void gimp_symmetry_finalize (GObject *object);
-static void gimp_symmetry_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_symmetry_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void
- gimp_symmetry_real_update_strokes (GimpSymmetry *sym,
- GimpDrawable *drawable,
- GimpCoords *origin);
-static GeglNode *
- gimp_symmetry_real_get_op (GimpSymmetry *sym,
- gint stroke,
- gint paint_width,
- gint paint_height);
-static GParamSpec **
- gimp_symmetry_real_get_settings (GimpSymmetry *sym,
- gint *n_properties);
+static void gimp_symmetry_finalize (GObject *object);
+static void gimp_symmetry_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_symmetry_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_symmetry_real_update_strokes (GimpSymmetry *sym,
+ GimpDrawable *drawable,
+ GimpCoords *origin);
+static GeglNode * gimp_symmetry_real_get_op (GimpSymmetry *sym,
+ gint stroke,
+ gint paint_width,
+ gint paint_height);
G_DEFINE_TYPE_WITH_CODE (GimpSymmetry, gimp_symmetry, GIMP_TYPE_OBJECT,
@@ -137,7 +132,6 @@ gimp_symmetry_class_init (GimpSymmetryClass *klass)
klass->label = _("None");
klass->update_strokes = gimp_symmetry_real_update_strokes;
klass->get_operation = gimp_symmetry_real_get_op;
- klass->get_settings = gimp_symmetry_real_get_settings;
klass->active_changed = NULL;
g_object_class_install_property (object_class, PROP_IMAGE,
@@ -242,14 +236,6 @@ gimp_symmetry_real_get_op (GimpSymmetry *sym,
return NULL;
}
-static GParamSpec **
-gimp_symmetry_real_get_settings (GimpSymmetry *sym,
- gint *n_properties)
-{
- *n_properties = 0;
-
- return NULL;
-}
/***** Public Functions *****/
@@ -359,25 +345,6 @@ gimp_symmetry_get_operation (GimpSymmetry *sym,
paint_height);
}
-/**
- * gimp_symmetry_get_settings:
- * @sym: the #GimpSymmetry
- * @n_properties: the number of properties in the returned array
- *
- * Returns: an array of the symmetry properties which are supposed to
- * be settable by the user.
- * The returned array must be freed by the caller.
- **/
-GParamSpec **
-gimp_symmetry_get_settings (GimpSymmetry *sym,
- gint *n_properties)
-{
- g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);
-
- return GIMP_SYMMETRY_GET_CLASS (sym)->get_settings (sym,
- n_properties);
-}
-
/*
* gimp_symmetry_parasite_name:
* @type: the #GimpSymmetry's #GType
diff --git a/app/core/gimpsymmetry.h b/app/core/gimpsymmetry.h
index f9277d7..52a9bc7 100644
--- a/app/core/gimpsymmetry.h
+++ b/app/core/gimpsymmetry.h
@@ -25,6 +25,10 @@
#include "gimpobject.h"
+/* shift one more than GIMP_CONFIG_PARAM_IGNORE */
+#define GIMP_SYMMETRY_PARAM_GUI (1 << (6 + G_PARAM_USER_SHIFT))
+
+
#define GIMP_TYPE_SYMMETRY (gimp_symmetry_get_type ())
#define GIMP_SYMMETRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SYMMETRY, GimpSymmetry))
#define GIMP_SYMMETRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SYMMETRY,
GimpSymmetryClass))
@@ -61,9 +65,6 @@ struct _GimpSymmetryClass
gint stroke,
gint paint_width,
gint paint_height);
- GParamSpec **
- (* get_settings) (GimpSymmetry *symmetry,
- gint *n_properties);
void (* active_changed) (GimpSymmetry *symmetry);
};
@@ -82,8 +83,6 @@ GeglNode * gimp_symmetry_get_operation (GimpSymmetry *symmetry,
gint stroke,
gint paint_width,
gint paint_height);
-GParamSpec ** gimp_symmetry_get_settings (GimpSymmetry *symmetry,
- gint *n_properties);
gchar * gimp_symmetry_parasite_name (GType type);
GimpParasite * gimp_symmetry_to_parasite (const GimpSymmetry *symmetry);
diff --git a/app/widgets/gimpsymmetryeditor.c b/app/widgets/gimpsymmetryeditor.c
index 9ce5d9e..c41d341 100644
--- a/app/widgets/gimpsymmetryeditor.c
+++ b/app/widgets/gimpsymmetryeditor.c
@@ -36,7 +36,7 @@
#include "core/gimpsymmetry.h"
#include "gimpmenufactory.h"
-#include "gimppropwidgets.h"
+#include "gimppropgui.h"
#include "gimpspinscale.h"
#include "gimpsymmetryeditor.h"
@@ -257,93 +257,22 @@ static void
gimp_symmetry_editor_set_options (GimpSymmetryEditor *editor,
GimpSymmetry *symmetry)
{
- GtkWidget *vbox = editor->p->options_vbox;
- GParamSpec **specs;
- gint n_properties;
- gint i;
-
- gtk_container_foreach (GTK_CONTAINER (vbox),
+ gtk_container_foreach (GTK_CONTAINER (editor->p->options_vbox),
(GtkCallback) gtk_widget_destroy, NULL);
- if (! symmetry || G_TYPE_FROM_INSTANCE (symmetry) == GIMP_TYPE_SYMMETRY)
- return;
-
- specs = gimp_symmetry_get_settings (symmetry, &n_properties);
-
- for (i = 0; i < n_properties; i++)
+ if (symmetry && G_TYPE_FROM_INSTANCE (symmetry) != GIMP_TYPE_SYMMETRY)
{
- GParamSpec *spec = G_PARAM_SPEC (specs[i]);
- const gchar *name;
- const gchar *blurb;
-
- if (spec == NULL)
- {
- GtkWidget *separator;
-
- separator = gtk_hseparator_new ();
- gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
- gtk_widget_show (separator);
- continue;
- }
-
- name = g_param_spec_get_name (spec);
- blurb = g_param_spec_get_blurb (spec);
-
- switch (spec->value_type)
- {
- case G_TYPE_BOOLEAN:
- {
- GtkWidget *checkbox;
-
- checkbox = gimp_prop_check_button_new (G_OBJECT (symmetry),
- name, blurb);
- gtk_box_pack_start (GTK_BOX (vbox), checkbox, FALSE, FALSE, 0);
- gtk_widget_show (checkbox);
- }
- break;
-
- case G_TYPE_DOUBLE:
- case G_TYPE_INT:
- case G_TYPE_UINT:
- {
- GtkWidget *scale;
- gdouble minimum;
- gdouble maximum;
-
- if (spec->value_type == G_TYPE_DOUBLE)
- {
- minimum = G_PARAM_SPEC_DOUBLE (spec)->minimum;
- maximum = G_PARAM_SPEC_DOUBLE (spec)->maximum;
- }
- else if (spec->value_type == G_TYPE_INT)
- {
- minimum = G_PARAM_SPEC_INT (spec)->minimum;
- maximum = G_PARAM_SPEC_INT (spec)->maximum;
- }
- else
- {
- minimum = G_PARAM_SPEC_UINT (spec)->minimum;
- maximum = G_PARAM_SPEC_UINT (spec)->maximum;
- }
-
- scale = gimp_prop_spin_scale_new (G_OBJECT (symmetry),
- name, blurb,
- 1.0, 10.0, 1);
- gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale),
- minimum,
- maximum);
- gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
- gtk_widget_show (scale);
- }
- break;
-
- default:
- /* Type of parameter we haven't handled yet. */
- continue;
- }
+ GtkWidget *gui;
+
+ gui = gimp_prop_gui_new (G_OBJECT (symmetry),
+ GIMP_TYPE_SYMMETRY,
+ GIMP_SYMMETRY_PARAM_GUI,
+ GIMP_IMAGE_EDITOR (editor)->context,
+ NULL, NULL);
+ gtk_box_pack_start (GTK_BOX (editor->p->options_vbox), gui,
+ FALSE, FALSE, 0);
+ gtk_widget_show (gui);
}
-
- g_free (specs);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]