[Rawstudio-commit] r2054 - trunk/src

Anders Brander anders at brander.dk
Tue Sep 30 21:12:16 CEST 2008


Author: abrander
Date: 2008-09-30 21:12:16 +0200 (Tue, 30 Sep 2008)
New Revision: 2054

Added:
   trunk/src/rs-settings.c
   trunk/src/rs-settings.h
Log:
Actually add the new files.

Added: trunk/src/rs-settings.c
===================================================================
--- trunk/src/rs-settings.c	                        (rev 0)
+++ trunk/src/rs-settings.c	2008-09-30 19:12:16 UTC (rev 2054)
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2006-2008 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "rs-settings.h"
+#include <string.h> /* memcmp() */
+
+G_DEFINE_TYPE (RSSettings, rs_settings, G_TYPE_OBJECT)
+
+enum {
+	SETTINGS_CHANGED,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+rs_settings_finalize (GObject *object)
+{
+	if (G_OBJECT_CLASS (rs_settings_parent_class)->finalize)
+		G_OBJECT_CLASS (rs_settings_parent_class)->finalize (object);
+}
+
+static void
+rs_settings_class_init (RSSettingsClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = rs_settings_finalize;
+
+	signals[SETTINGS_CHANGED] = g_signal_new ("settings-changed",
+		G_TYPE_FROM_CLASS (klass),
+		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+		0, /* Is this right? */
+		NULL,
+		NULL,
+		g_cclosure_marshal_VOID__INT,
+		G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+static void
+rs_settings_init (RSSettings *self)
+{
+	self->commit = 0;
+	self->commit_todo = 0;
+	self->curve_knots = NULL;
+	rs_settings_reset(self, MASK_ALL);
+}
+
+RSSettings *
+rs_settings_new (void)
+{
+	return g_object_new (RS_TYPE_SETTINGS, NULL);
+}
+
+/**
+ * Reset a RSSettings
+ * @param settings A RSSettings
+ * @param mask A mask for only resetting some values 
+ */
+void
+rs_settings_reset(RSSettings *settings, const RSSettingsMask mask)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+
+	if (mask & MASK_EXPOSURE)
+		settings->exposure = 0;
+
+	if (mask & MASK_SATURATION)
+		settings->saturation = 1.0;
+
+	if (mask & MASK_HUE)
+		settings->hue = 0.0;
+
+	if (mask & MASK_CONTRAST)
+		settings->contrast = 1.0;
+
+	if (mask & MASK_WARMTH)
+		settings->warmth = 0.0;
+
+	if (mask & MASK_TINT)
+		settings->tint = 0.0; 
+
+	if (mask & MASK_SHARPEN)
+		settings->sharpen = 0.0;
+
+	if (mask && MASK_CURVE)
+	{
+		if (settings->curve_knots)
+			g_free(settings->curve_knots);
+		settings->curve_knots = g_new(gfloat, 4);
+		settings->curve_knots[0] = 0.0;
+		settings->curve_knots[1] = 0.0;
+		settings->curve_knots[2] = 1.0;
+		settings->curve_knots[3] = 1.0;
+		settings->curve_nknots = 2;
+	}
+
+	if (mask > 0)
+		g_signal_emit(settings, signals[SETTINGS_CHANGED], 0, mask);
+}
+
+/**
+ * Stop signal emission from a RSSettings and queue up signals
+ * @param settings A RSSettings
+ */
+void
+rs_settings_commit_start(RSSettings *settings)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+	g_assert(settings->commit >= 0);
+
+	/* If we have no current commit running, reset todo */
+	if (settings->commit == 0)
+		settings->commit_todo = 0;
+
+	/* Increment commit */
+	settings->commit++;
+}
+
+/**
+ * Restart signal emission and process signal queue if any
+ * @param settings A RSSettings
+ * @return The mask of changes since rs_settings_commit_start()
+ */
+RSSettingsMask
+rs_settings_commit_stop(RSSettings *settings)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+	g_assert(settings->commit >= 0);
+
+	/* If this is the last nested commit, do the todo */
+	if ((settings->commit == 1) && (settings->commit_todo != 0))
+	{
+		g_signal_emit(settings, signals[SETTINGS_CHANGED], 0, settings->commit_todo);
+	}
+
+	/* Make sure we never go below 0 */
+	settings->commit = MAX(settings->commit-1, 0);
+
+	return settings->commit_todo;
+}
+
+/**
+ * Copy settings from one RSSettins to another
+ * @param source The source RSSettings
+ * @param mask A RSSettingsMask to do selective copying
+ * @param target The target RSSettings
+ */
+RSSettingsMask
+rs_settings_copy(RSSettings *source, RSSettingsMask mask, RSSettings *target)
+{
+	RSSettingsMask changed_mask = 0;
+
+	g_assert(RS_IS_SETTINGS(source));
+	g_assert(RS_IS_SETTINGS(target));
+
+	/* Convenience macro */
+#define SETTINGS_COPY(upper, lower) \
+do { \
+	if ((mask & MASK_##upper) && (target->lower != source->lower)) \
+	{ \
+		changed_mask |= MASK_ ##upper; \
+		target->lower = source->lower; \
+	} \
+} while(0)
+
+	SETTINGS_COPY(EXPOSURE, exposure);
+	SETTINGS_COPY(SATURATION, saturation);
+	SETTINGS_COPY(HUE, hue);
+	SETTINGS_COPY(CONTRAST, contrast);
+	SETTINGS_COPY(WARMTH, warmth);
+	SETTINGS_COPY(TINT, tint);
+	SETTINGS_COPY(SHARPEN, sharpen);
+#undef SETTINGS_COPY
+
+	if (mask & MASK_CURVE)
+	{
+		/* Check if we actually have changed */
+		if (target->curve_nknots != source->curve_nknots)
+			changed_mask |= MASK_CURVE;
+		else
+		{
+			if (memcmp(source->curve_knots, target->curve_knots, sizeof(gfloat)*2*source->curve_nknots)!=0)
+				changed_mask |= MASK_CURVE;
+		}
+
+		/* Copy the knots if needed */
+		if (changed_mask & MASK_CURVE)
+		{
+			g_free(target->curve_knots);
+			target->curve_knots = g_memdup(source->curve_knots, sizeof(gfloat)*2*source->curve_nknots);
+			target->curve_nknots = source->curve_nknots;
+		}
+	}
+
+	/* Emit seignal if needed */
+	if (changed_mask > 0)
+		g_signal_emit(target, signals[SETTINGS_CHANGED], 0, changed_mask);
+
+	return changed_mask;
+}
+
+/* Macro to create functions for changing single parameters, programmers are lazy */
+#define RS_SETTINGS_SET(upper, lower) \
+gfloat \
+rs_settings_set_##lower(RSSettings *settings, const gfloat lower) \
+{ \
+	gfloat previous; \
+	g_assert(RS_IS_SETTINGS(settings)); \
+\
+	previous = settings->lower; \
+\
+	if (settings->lower != lower) \
+	{ \
+		settings->lower = lower; \
+\
+		if (settings->commit > 0) \
+		{ \
+			settings->commit_todo |= MASK_##upper; \
+		} \
+		else \
+			g_signal_emit(settings, signals[SETTINGS_CHANGED], 0, MASK_##upper); \
+	} \
+	return previous; \
+}
+
+RS_SETTINGS_SET(EXPOSURE, exposure)
+RS_SETTINGS_SET(SATURATION, saturation)
+RS_SETTINGS_SET(HUE, hue)
+RS_SETTINGS_SET(CONTRAST, contrast)
+RS_SETTINGS_SET(WARMTH, warmth)
+RS_SETTINGS_SET(TINT, tint)
+RS_SETTINGS_SET(SHARPEN, sharpen)
+
+#undef RS_SETTINGS_SET
+
+/**
+ * Set curve knots
+ * @param settings A RSSettings
+ * @param knots Knots for curve
+ * @param nknots Number of knots
+ */
+void
+rs_settings_set_curve_knots(RSSettings *settings, const gfloat *knots, const gint nknots)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+	g_assert(nknots > 0);
+	g_assert(knots != NULL);
+
+	g_free(settings->curve_knots);
+
+	settings->curve_knots = g_memdup(knots, sizeof(gfloat)*2*nknots);
+	settings->curve_nknots = nknots;
+
+	g_signal_emit(settings, signals[SETTINGS_CHANGED], 0, MASK_CURVE);
+}
+
+/**
+ * Set the warmth and tint values of a RSSettings
+ * @param settings A RSSettings
+ * @param exposure New value
+ */
+void
+rs_settings_set_wb(RSSettings *settings, const gfloat warmth, const gfloat tint)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+
+	rs_settings_commit_start(settings);
+	rs_settings_set_warmth(settings, warmth);
+	rs_settings_set_tint(settings, tint);
+	rs_settings_commit_stop(settings);
+}
+
+/* Programmers write programs to write programs */
+#define RS_SETTINGS_GET(lower) \
+gfloat \
+rs_settings_get_##lower(RSSettings *settings) \
+{ \
+	g_assert(RS_IS_SETTINGS(settings)); \
+	return settings->lower; \
+}
+
+RS_SETTINGS_GET(exposure);
+RS_SETTINGS_GET(saturation);
+RS_SETTINGS_GET(hue);
+RS_SETTINGS_GET(contrast);
+RS_SETTINGS_GET(warmth);
+RS_SETTINGS_GET(tint);
+RS_SETTINGS_GET(sharpen);
+
+#undef RS_SETTINGS_GET
+
+/**
+ * Get the knots from the curve
+ * @param settings A RSSettings
+ * @return All knots as a newly allocated array
+ */
+gfloat *
+rs_settings_get_curve_knots(RSSettings *settings)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+
+	return g_memdup(settings->curve_knots, sizeof(gfloat)*2*settings->curve_nknots);
+}
+
+/**
+ * Get number of knots in curve in a RSSettings
+ * @param settings A RSSettings
+ * @return Number of knots
+ */
+gint
+rs_settings_get_curve_nknots(RSSettings *settings)
+{
+	g_assert(RS_IS_SETTINGS(settings));
+
+	return settings->curve_nknots;
+}
+
+/**
+ * Link two RSSettings together, if source gets updated, it will propagate to target
+ * @param source A RSSettings
+ * @param target A RSSettings
+ */
+void
+rs_settings_link(RSSettings *source, RSSettings *target)
+{
+	g_assert(RS_IS_SETTINGS(source));
+	g_assert(RS_IS_SETTINGS(target));
+
+	/* Add a weak reference to target, we would really like to know if it disappears */
+	g_object_weak_ref(G_OBJECT(target), (GWeakNotify) rs_settings_unlink, source);
+
+	/* Use glib signals to propagate changes */
+	g_signal_connect(source, "settings-changed", G_CALLBACK(rs_settings_copy), target);
+}
+
+/**
+ * Unlink two RSSettings - this will be done automaticly if target from a
+ * previous rs_settings_link() is finalized
+ * @param source A RSSettings
+ * @param target A RSSettings - can be destroyed, doesn't matter, we just need the pointer
+ */
+void
+rs_settings_unlink(RSSettings *source, RSSettings *target)
+{
+	gulong signal_id;
+
+	g_assert(RS_IS_SETTINGS(source));
+
+	/* If we can find a signal linking these two pointers, disconnect it */
+	signal_id = g_signal_handler_find(source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, target);
+	if (signal_id > 0)
+		g_signal_handler_disconnect(source, signal_id);
+}

Added: trunk/src/rs-settings.h
===================================================================
--- trunk/src/rs-settings.h	                        (rev 0)
+++ trunk/src/rs-settings.h	2008-09-30 19:12:16 UTC (rev 2054)
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2006-2008 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef RS_SETTINGS_H
+#define RS_SETTINGS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define RS_TYPE_SETTINGS rs_settings_get_type()
+
+#define RS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_SETTINGS, RSSettings))
+#define RS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_SETTINGS, RSSettingsClass))
+#define RS_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_SETTINGS))
+#define RS_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RS_TYPE_SETTINGS))
+#define RS_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_SETTINGS, RSSettingsClass))
+
+typedef enum {
+	MASK_EXPOSURE   = (1<<0),
+	MASK_SATURATION = (1<<1),
+	MASK_HUE        = (1<<2),
+	MASK_CONTRAST   = (1<<3),
+	MASK_WARMTH     = (1<<4),
+	MASK_TINT       = (1<<5),
+	MASK_WB         = MASK_WARMTH | MASK_TINT,
+	MASK_CURVE      = (1<<6),
+	MASK_SHARPEN    = (1<<7),
+	MASK_ALL        = 0x00ffffff,
+} RSSettingsMask;
+
+typedef struct _RSsettings {
+	GObject parent;
+	gint commit;
+	RSSettingsMask commit_todo;
+	gfloat exposure;
+	gfloat saturation;
+	gfloat hue;
+	gfloat contrast;
+	gfloat warmth;
+	gfloat tint;
+	gfloat sharpen;
+	gint curve_nknots;
+	gfloat *curve_knots;
+} RSSettings;
+
+typedef struct {
+  GObjectClass parent_class;
+} RSSettingsClass;
+
+GType rs_settings_get_type (void);
+
+RSSettings *rs_settings_new (void);
+
+/**
+ * Reset a RSSettings
+ * @param settings A RSSettings
+ * @param mask A mask for only resetting some values 
+ */
+extern void rs_settings_reset(RSSettings *settings, const RSSettingsMask mask);
+
+/**
+ * Stop signal emission from a RSSettings and queue up signals
+ * @param settings A RSSettings
+ */
+extern void rs_settings_commit_start(RSSettings *settings);
+
+/**
+ * Restart signal emission and process signal queue if any
+ * @param settings A RSSettings
+ * @return The mask of changes since rs_settings_commit_start()
+ */
+extern RSSettingsMask rs_settings_commit_stop(RSSettings *settings);
+
+/**
+ * Copy settings from one RSSettins to another
+ * @param source The source RSSettings
+ * @param mask A RSSettingsMask to do selective copying
+ * @param target The target RSSettings
+ */
+extern RSSettingsMask rs_settings_copy(RSSettings *source, const RSSettingsMask mask, RSSettings *target);
+
+/**
+ * Set the exposure value of a RSSettings
+ * @param settings A RSSettings
+ * @param exposure New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_exposure(RSSettings *settings, const gfloat exposure);
+
+/**
+ * Set the saturation value of a RSSettings
+ * @param settings A RSSettings
+ * @param saturation New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_saturation(RSSettings *settings, const gfloat saturation);
+
+/**
+ * Set the hue value of a RSSettings
+ * @param settings A RSSettings
+ * @param hue New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_hue(RSSettings *settings, const gfloat hue);
+
+/**
+ * Set the contrast value of a RSSettings
+ * @param settings A RSSettings
+ * @param contrast New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_contrast(RSSettings *settings, const gfloat contrast);
+
+/**
+ * Set the warmth value of a RSSettings
+ * @param settings A RSSettings
+ * @param warmth New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_warmth(RSSettings *settings, const gfloat warmth);
+
+/**
+ * Set the tint value of a RSSettings
+ * @param settings A RSSettings
+ * @param tint New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_tint(RSSettings *settings, const gfloat tint);
+
+/**
+ * Set the sharpen value of a RSSettings
+ * @param settings A RSSettings
+ * @param sharpen New value
+ * @return Old value
+ */
+extern gfloat rs_settings_set_sharpen(RSSettings *settings, const gfloat sharpen);
+
+/**
+ * Set curve knots
+ * @param settings A RSSettings
+ * @param knots Knots for curve
+ * @param nknots Number of knots
+ */
+extern void rs_settings_set_curve_knots(RSSettings *settings, const gfloat *knots, const gint nknots);
+
+/**
+ * Set the warmth and tint values of a RSSettings
+ * @param settings A RSSettings
+ * @param exposure New value
+ */
+extern void rs_settings_set_wb(RSSettings *settings, const gfloat warmth, const gfloat tint);
+
+extern gfloat rs_settings_get_exposure(RSSettings *settings);
+extern gfloat rs_settings_get_saturation(RSSettings *settings);
+extern gfloat rs_settings_get_hue(RSSettings *settings);
+extern gfloat rs_settings_get_contrast(RSSettings *settings);
+extern gfloat rs_settings_get_warmth(RSSettings *settings);
+extern gfloat rs_settings_get_tint(RSSettings *settings);
+extern gfloat rs_settings_get_sharpen(RSSettings *settings);
+
+/**
+ * Get the knots from the curve
+ * @param settings A RSSettings
+ * @return All knots as a newly allocated array
+ */
+extern gfloat *
+rs_settings_get_curve_knots(RSSettings *settings);
+
+/**
+ * Get number of knots in curve in a RSSettings
+ * @param settings A RSSettings
+ * @return Number of knots
+ */
+extern gint
+rs_settings_get_curve_nknots(RSSettings *settings);
+
+/**
+ * Use like g_signal_connect(source, "settings-changed", G_CALLBACK(rs_settings_changed), target);
+ */
+extern void rs_settings_changed(RSSettings *source, const RSSettingsMask mask, RSSettings *target);
+
+/**
+ * Link two RSSettings together, if source gets updated, it will propagate to target
+ * @param source A RSSettings
+ * @param target A RSSettings
+ */
+extern void rs_settings_link(RSSettings *source, RSSettings *target);
+
+/**
+ * Unlink two RSSettings - this will be done automaticly if target from a previous rs_settings_link() is finalized
+ * @param source A RSSettings
+ * @param target A RSSettings - can be destroyed, doesn't matter, we just need the pointer
+ */
+extern void rs_settings_unlink(RSSettings *source, RSSettings *target);
+
+G_END_DECLS
+
+#endif /* RS_SETTINGS_H */




More information about the Rawstudio-commit mailing list