changeset 502:54d86ee98b98

Alpha/preliminary curve widget code merged.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 27 Jan 2007 02:52:02 +0000
parents d753e545f9fa
children 070516a21ef4
files src/xs_curve.c src/xs_curve.h
diffstat 2 files changed, 348 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/src/xs_curve.c	Sat Jan 27 02:51:02 2007 +0000
+++ b/src/xs_curve.c	Sat Jan 27 02:52:02 2007 +0000
@@ -2,25 +2,32 @@
 #include <string.h>
 #include <math.h>
 
+#include <stdio.h>
+
 #include "xs_curve.h"
 #include <gtk/gtkdrawingarea.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtksignal.h>
 
 
+#define GET_X(i)	curve->ctlpoints[i].x
+#define GET_Y(i)	curve->ctlpoints[i].y
+
+
 #define RADIUS		3	/* radius of the control points */
+#define RADIUS2		(RADIUS * 2)
+
 #define MIN_DISTANCE	8	/* min distance between control points */
 
 #define GRAPH_MASK	(GDK_EXPOSURE_MASK |		\
-			 GDK_POINTER_MOTION_MASK |	\
-			 GDK_POINTER_MOTION_HINT_MASK |	\
-			 GDK_ENTER_NOTIFY_MASK |	\
-			 GDK_BUTTON_PRESS_MASK |	\
-			 GDK_BUTTON_RELEASE_MASK |	\
-			 GDK_BUTTON1_MOTION_MASK)
+			GDK_POINTER_MOTION_MASK |	\
+			GDK_POINTER_MOTION_HINT_MASK |	\
+			GDK_ENTER_NOTIFY_MASK |		\
+			GDK_BUTTON_PRESS_MASK |		\
+			GDK_BUTTON_RELEASE_MASK |	\
+			GDK_BUTTON1_MOTION_MASK)
 
-enum
-{
+enum {
 	ARG_0,
 	ARG_CURVE_TYPE,
 	ARG_MIN_X,
@@ -31,8 +38,6 @@
 
 static GtkDrawingAreaClass *parent_class = NULL;
 
-
-/* forward declarations: */
 static void xs_curve_class_init(XSCurveClass * class);
 static void xs_curve_init(XSCurve * curve);
 static void xs_curve_set_arg(GtkObject * object, GtkArg * arg, guint arg_id);
@@ -41,6 +46,7 @@
 static gint xs_curve_graph_events(GtkWidget * widget, GdkEvent * event, XSCurve * c);
 static void xs_curve_size_graph(XSCurve * curve);
 
+
 GtkType xs_curve_get_type(void)
 {
 	static GtkType curve_type = 0;
@@ -62,7 +68,8 @@
 	return curve_type;
 }
 
-static void xs_curve_class_init(XSCurveClass * class)
+
+static void xs_curve_class_init(XSCurveClass *class)
 {
 	GtkObjectClass *object_class;
 
@@ -80,7 +87,8 @@
 	gtk_object_add_arg_type("XSCurve::max_y", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_MAX_Y);
 }
 
-static void xs_curve_init(XSCurve * curve)
+
+static void xs_curve_init(XSCurve *curve)
 {
 	gint old_mask;
 
@@ -88,16 +96,13 @@
 	curve->height = 0;
 	curve->grab_point = -1;
 
-	curve->num_points = 0;
-	curve->point = 0;
-
 	curve->num_ctlpoints = 0;
-	curve->ctlpoint = NULL;
+	curve->ctlpoints = NULL;
 
 	curve->min_x = 0.0;
-	curve->max_x = 1.0;
+	curve->max_x = 2048.0;
 	curve->min_y = 0.0;
-	curve->max_y = 1.0;
+	curve->max_y = 22000.0;
 
 	old_mask = gtk_widget_get_events(GTK_WIDGET(curve));
 	gtk_widget_set_events(GTK_WIDGET(curve), old_mask | GRAPH_MASK);
@@ -105,7 +110,8 @@
 	xs_curve_size_graph(curve);
 }
 
-static void xs_curve_set_arg(GtkObject * object, GtkArg * arg, guint arg_id)
+
+static void xs_curve_set_arg(GtkObject *object, GtkArg *arg, guint arg_id)
 {
 	XSCurve *curve = XS_CURVE(object);
 
@@ -125,7 +131,8 @@
 	}
 }
 
-static void xs_curve_get_arg(GtkObject * object, GtkArg * arg, guint arg_id)
+
+static void xs_curve_get_arg(GtkObject *object, GtkArg *arg, guint arg_id)
 {
 	XSCurve *curve = XS_CURVE(object);
 
@@ -148,158 +155,327 @@
 	}
 }
 
+
 static int xs_project(gfloat value, gfloat min, gfloat max, int norm)
 {
 	return (norm - 1) * ((value - min) / (max - min)) + 0.5;
 }
 
+
 static gfloat xs_unproject(gint value, gfloat min, gfloat max, int norm)
 {
 	return value / (gfloat) (norm - 1) * (max - min) + min;
 }
 
-/* Solve the tridiagonal equation system that determines the second
-   derivatives for the interpolation points.  (Based on Numerical
-   Recipies 2nd Edition.) */
-static void spline_solve(int n, gfloat x[], gfloat y[], gfloat y2[])
-{
-	gfloat p, sig, *u;
-	gint i, k;
-
-	u = g_malloc((n - 1) * sizeof(u[0]));
-
-	y2[0] = u[0] = 0.0;	/* set lower boundary condition to "natural" */
 
-	for (i = 1; i < n - 1; ++i) {
-		sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);
-		p = sig * y2[i - 1] + 2.0;
-		y2[i] = (sig - 1.0) / p;
-		u[i] = ((y[i + 1] - y[i])
-			/ (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]));
-		u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
-	}
+static inline void xs_cubic_coeff(gfloat x1, gfloat y1,
+			gfloat x2, gfloat y2,
+			gfloat k1, gfloat k2,
+			gfloat *a, gfloat *b,
+			gfloat *c, gfloat *d)
+{
+	gfloat dx = x2 - x1, dy = y2 - y1;
 
-	y2[n - 1] = 0.0;
-	for (k = n - 2; k >= 0; --k)
-		y2[k] = y2[k] * y2[k + 1] + u[k];
-
-	g_free(u);
+	*a = ((k1 + k2) - 2 * dy / dx) / (dx * dx);
+	*b = ((k2 - k1) / dx - 3 * (x1 + x2) * (*a)) / 2;
+	*c = k1 - (3 * x1 * (*a) + 2 * (*b)) * x1;
+	*d = y1 - ((x1 * (*a) + (*b)) * x1 + (*c)) * x1;
 }
 
-static gfloat spline_eval(int n, gfloat x[], gfloat y[], gfloat y2[], gfloat val)
-{
-	gint k_lo, k_hi, k;
-	gfloat h, b, a;
+#define x(val) val->x
+#define y(val) val->y
 
-	/* do a binary search for the right interval: */
-	k_lo = 0;
-	k_hi = n - 1;
-	while (k_hi - k_lo > 1) {
-		k = (k_hi + k_lo) / 2;
-		if (x[k] > val)
-			k_hi = k;
-		else
-			k_lo = k;
-	}
-
-	h = x[k_hi] - x[k_lo];
-	g_assert(h > 0.0);
-
-	a = (x[k_hi] - val) / h;
-	b = (val - x[k_lo]) / h;
-	return a * y[k_lo] + b * y[k_hi] + ((a * a * a - a) * y2[k_lo] + (b * b * b - b) * y2[k_hi]) * (h * h) / 6.0;
-}
-
-static void xs_curve_interpolate(XSCurve * c, gint width, gint height)
+static void xs_curve_draw(XSCurve *curve, gint width, gint height)
 {
-	gfloat *vector;
-	gint i;
-
-	vector = g_malloc(width * sizeof(vector[0]));
-
-	xs_curve_get_vector(c, width, vector);
-
-	c->height = height;
-	if (c->num_points != width) {
-		c->num_points = width;
-		if (c->point)
-			g_free(c->point);
-		c->point = g_malloc(c->num_points * sizeof(c->point[0]));
-	}
-
-	for (i = 0; i < width; ++i) {
-		c->point[i].x = RADIUS + i;
-		c->point[i].y = RADIUS + height - project(vector[i], c->min_y, c->max_y, height);
-	}
-
-	g_free(vector);
-}
-
-static void xs_curve_draw(XSCurve * c, gint width, gint height)
-{
+	gfloat res = 10.0f;
 	GtkStateType state;
 	GtkStyle *style;
 	gint i;
+	t_xs_point *p0, *p1, *p2, *p3;
 
-	if (!c->pixmap)
+	if (!curve->pixmap)
 		return;
 
-	if (c->height != height || c->num_points != width)
-		xs_curve_interpolate(c, width, height);
-
 	state = GTK_STATE_NORMAL;
-	if (!GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(c)))
+	if (!GTK_WIDGET_IS_SENSITIVE(GTK_WIDGET(curve)))
 		state = GTK_STATE_INSENSITIVE;
 
-	style = GTK_WIDGET(c)->style;
+	style = GTK_WIDGET(curve)->style;
 
-	/* clear the pixmap: */
-	gtk_paint_flat_box(style, c->pixmap,
+	/* Clear the pixmap */
+	gtk_paint_flat_box(style, curve->pixmap,
 		GTK_STATE_NORMAL, GTK_SHADOW_NONE,
-		NULL, GTK_WIDGET(c), "curve_bg",
-		0, 0, width + RADIUS * 2, height + RADIUS * 2);
+		NULL, GTK_WIDGET(curve), "curve_bg",
+		0, 0,
+		width + RADIUS2,
+		height + RADIUS2);
 
-	/* draw the grid lines: (XXX make more meaningful) */
+	
+	/* Draw the grid */
 	for (i = 0; i < 5; i++) {
-		gdk_draw_line(c->pixmap, style->dark_gc[state],
+		gdk_draw_line(curve->pixmap, style->dark_gc[state],
 			RADIUS,		i * (height / 4.0) + RADIUS,
 			width + RADIUS,	i * (height / 4.0) + RADIUS);
 
-		gdk_draw_line(c->pixmap, style->dark_gc[state],
+		gdk_draw_line(curve->pixmap, style->dark_gc[state],
 			i * (width / 4.0) + RADIUS, RADIUS,
 			i * (width / 4.0) + RADIUS, height + RADIUS);
 	}
 
-	gdk_draw_points(c->pixmap, style->fg_gc[state], c->point, c->num_points);
+	
+	/* Draw the spline/curve itself */
+	p0 = curve->ctlpoints;
+	p1 = p0; p1++;
+	p2 = p1; p2++;
+	p3 = p2; p3++;
+
+	/* Draw each curve segment */
+	fprintf(stderr, "npoints = %d\n", curve->num_ctlpoints);
+	for (i = 0; i < curve->num_ctlpoints; i++, ++p0, ++p1, ++p2, ++p3) {
+		gfloat k1, k2, a, b, c, d, x;
+		
+		/* p1 and p2 equal; single point */
+		if (x(p1) == x(p2))
+			continue;
+		
+		/* Both end points repeated; straight line */
+		if (x(p0) == x(p1) && x(p2) == x(p3)) {
+			k1 = k2 = (y(p2) - y(p1)) / (x(p2) - x(p1));
+		}
+		/* p0 and p1 equal; use f''(x1) = 0 */
+		else if (x(p0) == x(p1)) {
+			k2 = (y(p3) - y(p1)) / (x(p3) - x(p1));
+			k1 = (3 * (y(p2) - y(p1)) / (x(p2) - x(p1)) - k2) / 2;
+		}
+		/* p2 and p3 equal; use f''(x2) = 0 */
+		else if (x(p2) == x(p3)) {
+			k1 = (y(p2) - y(p0)) / (x(p2) - x(p0));
+			k2 = (3 * (y(p2) - y(p1)) / (x(p2) - x(p1)) - k1) / 2;
+		}
+		/* Normal curve */
+		else {
+			k1 = (y(p2) - y(p0)) / (x(p2) - x(p0));
+			k2 = (y(p3) - y(p1)) / (x(p3) - x(p1));
+		}
 
-	gdk_draw_pixmap(GTK_WIDGET(c)->window, style->fg_gc[state], c->pixmap,
-			0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2);
+		xs_cubic_coeff(x(p1), y(p1), x(p2), y(p2), k1, k2, &a, &b, &c, &d);
+		
+		fprintf(stderr, "--seg[%1.3f, %1.3f]=>[%1.3f, %1.3f]--\n",
+			x(p1), y(p1), x(p2), y(p2));
+		
+		for (x = x(p1); x <= x(p2); x += res) {
+			gfloat y = ((a * x + b) * x + c) * x + d;
+			gint qx, qy;
+			qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width);
+			qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height);
+
+			fprintf(stderr, "[%1.3f, %1.3f] -> %d, %d\n", x, y, qx, qy);
+			
+			gdk_draw_point(curve->pixmap, style->fg_gc[state],
+				RADIUS + xs_project(x, curve->min_x, curve->max_x, width),
+				RADIUS + xs_project(y, curve->min_y, curve->max_y, height)
+				);
+
+		}
+		
+		fprintf(stderr, "-------\n");
+	}
+	
+	/* Draw control points */
+	for (i = 0; i < curve->num_ctlpoints; ++i) {
+		gint x, y;
+
+		if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y ||
+			GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y)
+			continue;
+
+		x = xs_project(GET_X(i), curve->min_x, curve->max_x, width);
+		y = xs_project(GET_Y(i), curve->min_y, curve->max_y, height);
+
+		gdk_draw_arc(curve->pixmap, style->fg_gc[state], TRUE,
+			x, y, RADIUS2, RADIUS2, 0, 360 * 64);
+	}
+	
+	/* Draw pixmap in the widget */
+	gdk_draw_pixmap(GTK_WIDGET(curve)->window,
+			style->fg_gc[state], curve->pixmap,
+			0, 0, 0, 0,
+			width + RADIUS2,
+			height + RADIUS2);
 }
 
-static gint xs_curve_graph_events(GtkWidget * widget, GdkEvent * event, XSCurve * c)
+#undef x
+#undef y
+
+
+static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve)
 {
-	gint i, src, dst, leftbound, rightbound;
+	GdkCursorType new_type = curve->cursor_type;
 	GdkEventButton *bevent;
 	GdkEventMotion *mevent;
 	GtkWidget *w;
-	gint tx, ty;
-	gint cx, x, y, width, height;
-	gint closest_point = 0;
-	gfloat rx, ry, min_x;
+	gint i, width, height, x, y, tx, ty, cx, closest_point = 0, min_x;
 	guint distance;
-	gint x1, x2, y1, y2;
 
-	w = GTK_WIDGET(c);
-	width = w->allocation.width - RADIUS * 2;
-	height = w->allocation.height - RADIUS * 2;
+	w = GTK_WIDGET(curve);
+	width = w->allocation.width - RADIUS2;
+	height = w->allocation.height - RADIUS2;
 
 	if ((width < 0) || (height < 0))
 		return FALSE;
+
+	/* get the pointer position */
+	gdk_window_get_pointer(w->window, &tx, &ty, NULL);
+	x = CLAMP((tx - RADIUS), 0, width - 1);
+	y = CLAMP((ty - RADIUS), 0, height - 1);
+
+	min_x = curve->min_x;
+
+	distance = ~0U;
+	for (i = 0; i < curve->num_ctlpoints; ++i) {
+		cx = xs_project(GET_X(i), min_x, curve->max_x, width);
+		if ((guint) abs(x - cx) < distance) {
+			distance = abs(x - cx);
+			closest_point = i;
+		}
+	}
+	
+	/* Act based on event type */
+	switch (event->type) {
+	case GDK_CONFIGURE:
+		if (curve->pixmap)
+			gdk_pixmap_unref(curve->pixmap);
+		curve->pixmap = 0;
+
+		/* fall through */
+
+	case GDK_EXPOSE:
+		if (!curve->pixmap) {
+			curve->pixmap = gdk_pixmap_new(w->window,
+			w->allocation.width, w->allocation.height, -1);
+		}
+		xs_curve_draw(curve, width, height);
+		break;
+
+	case GDK_BUTTON_PRESS:
+		gtk_grab_add(widget);
+
+		bevent = (GdkEventButton *) event;
+		new_type = GDK_TCROSS;
+
+		if (distance > MIN_DISTANCE) {
+			/* insert a new control point */
+			if (curve->num_ctlpoints > 0) {
+				cx = xs_project(GET_X(closest_point), min_x, curve->max_x, width);
+				if (x > cx) closest_point++;
+			}
+			
+			curve->num_ctlpoints++;
+			
+			curve->ctlpoints = g_realloc(curve->ctlpoints, curve->num_ctlpoints * sizeof(*curve->ctlpoints));
+			for (i = curve->num_ctlpoints - 1; i > closest_point; --i) {
+				memcpy(curve->ctlpoints + i, curve->ctlpoints + i - 1, sizeof(*curve->ctlpoints));
+			}
+		}
+		
+		curve->grab_point = closest_point;
+		GET_X(curve->grab_point) = xs_unproject(x, min_x, curve->max_x, width);
+		GET_Y(curve->grab_point) = xs_unproject(y, curve->min_y, curve->max_y, height);
+
+		xs_curve_draw(curve, width, height);
+		break;
+
+	case GDK_BUTTON_RELEASE:
+		{
+		gint src, dst;
+		
+		gtk_grab_remove(widget);
+
+		/* delete inactive points: */
+		for (src = dst = 0; src < curve->num_ctlpoints; ++src)
+		if (GET_X(src) >= min_x) {
+			memcpy(curve->ctlpoints + dst, curve->ctlpoints + src, sizeof(*curve->ctlpoints));
+			dst++;
+		}
+
+		if (dst < src) {
+			curve->num_ctlpoints -= (src - dst);
+			if (curve->num_ctlpoints <= 0) {
+				curve->num_ctlpoints = 1;
+				GET_X(0) = min_x;
+				GET_Y(0) = curve->min_y;
+				xs_curve_draw(curve, width, height);
+			}
+			curve->ctlpoints = g_realloc(curve->ctlpoints, curve->num_ctlpoints * sizeof(*curve->ctlpoints));
+		}
+
+		new_type = GDK_FLEUR;
+		curve->grab_point = -1;
+		}
+		break;
+
+	case GDK_MOTION_NOTIFY:
+		mevent = (GdkEventMotion *) event;
+
+		if (curve->grab_point == -1) {
+			/* if no point is grabbed...  */
+			if (distance <= MIN_DISTANCE)
+				new_type = GDK_FLEUR;
+			else
+				new_type = GDK_TCROSS;
+		} else {
+			gint leftbound, rightbound;
+			
+			/* drag the grabbed point  */
+			new_type = GDK_TCROSS;
+			
+			leftbound = -MIN_DISTANCE;
+			if (curve->grab_point > 0) {
+				leftbound = xs_project(
+					GET_X(curve->grab_point-1),
+					min_x, curve->max_x, width);
+			}
+
+			rightbound = width + RADIUS2 + MIN_DISTANCE;
+			if (curve->grab_point + 1 < curve->num_ctlpoints) {
+				rightbound = xs_project(
+					GET_X(curve->grab_point+1),
+					min_x, curve->max_x, width);
+			}
+
+			if ((tx <= leftbound) || (tx >= rightbound) ||
+				(ty > height + RADIUS2 + MIN_DISTANCE) || (ty < -MIN_DISTANCE)) {
+				GET_X(curve->grab_point) = min_x - 1.0;
+			} else {
+				GET_X(curve->grab_point) =
+					xs_unproject(x, min_x, curve->max_x, width);
+				GET_Y(curve->grab_point) =
+					xs_unproject(y, curve->min_y, curve->max_y, height);
+			}
+			
+			xs_curve_draw(curve, width, height);
+		}
+
+		if (new_type != (GdkCursorType) curve->cursor_type) {
+			GdkCursor *cursor;
+
+			curve->cursor_type = new_type;
+
+			cursor = gdk_cursor_new(curve->cursor_type);
+			gdk_window_set_cursor(w->window, cursor);
+			gdk_cursor_destroy(cursor);
+		}
+		break;
+
+	default:
+		break;
+	}
 	
 	return FALSE;
 }
 
-static void xs_curve_size_graph(XSCurve * curve)
+
+static void xs_curve_size_graph(XSCurve *curve)
 {
 	gint width, height;
 	gfloat aspect;
@@ -307,8 +483,10 @@
 	width = (curve->max_x - curve->min_x) + 1;
 	height = (curve->max_y - curve->min_y) + 1;
 	aspect = width / (gfloat) height;
+
 	if (width > gdk_screen_width() / 4)
 		width = gdk_screen_width() / 4;
+
 	if (height > gdk_screen_height() / 4)
 		height = gdk_screen_height() / 4;
 
@@ -317,19 +495,41 @@
 	else
 		height = width / aspect;
 
-	gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + RADIUS * 2, height + RADIUS * 2);
-}
-
-static void xs_curve_reset_vector(XSCurve * curve)
-{
-}
-
-void xs_curve_reset(XSCurve * c)
-{
+	gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + RADIUS2, height + RADIUS2);
 }
 
 
-void xs_curve_set_range(XSCurve * curve, gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y)
+void xs_curve_reset(XSCurve *curve)
+{
+	if (curve->ctlpoints)
+		g_free(curve->ctlpoints);
+
+	curve->num_ctlpoints = 4;
+	curve->ctlpoints = g_malloc(curve->num_ctlpoints * sizeof(curve->ctlpoints[0]));
+
+	GET_X(0) = curve->min_x;
+	GET_Y(0) = curve->min_y;
+
+	GET_X(1) = curve->min_x;
+	GET_Y(1) = curve->min_y;
+
+	GET_X(2) = curve->max_x;
+	GET_Y(2) = curve->max_y;
+
+	GET_X(3) = curve->max_x;
+	GET_Y(3) = curve->max_y;
+
+	if (curve->pixmap) {
+		gint width, height;
+
+		width = GTK_WIDGET(curve)->allocation.width - RADIUS2;
+		height = GTK_WIDGET(curve)->allocation.height - RADIUS2;
+		xs_curve_draw(curve, width, height);
+	}
+}
+
+
+void xs_curve_set_range(XSCurve *curve, gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y)
 {
 	curve->min_x = min_x;
 	curve->max_x = max_x;
@@ -337,7 +537,7 @@
 	curve->max_y = max_y;
 
 	xs_curve_size_graph(curve);
-	xs_curve_reset_vector(curve);
+	xs_curve_reset(curve);
 }
 
 
@@ -347,7 +547,7 @@
 }
 
 
-static void xs_curve_finalize(GtkObject * object)
+static void xs_curve_finalize(GtkObject *object)
 {
 	XSCurve *curve;
 
@@ -355,22 +555,13 @@
 	g_return_if_fail(XS_IS_CURVE(object));
 
 	curve = XS_CURVE(object);
+
 	if (curve->pixmap)
 		gdk_pixmap_unref(curve->pixmap);
-	if (curve->point)
-		g_free(curve->point);
-	if (curve->ctlpoint)
-		g_free(curve->ctlpoint);
+
+	if (curve->ctlpoints)
+		g_free(curve->ctlpoints);
 
 	(*GTK_OBJECT_CLASS(parent_class)->finalize) (object);
 }
 
-
-void xs_curve_get_vector(XSCurve *curve, int veclen, gfloat vector[])
-{
-}
-
-void xs_curve_set_vector(XSCurve *curve, int veclen, gfloat vector[])
-{
-}
-
--- a/src/xs_curve.h	Sat Jan 27 02:51:02 2007 +0000
+++ b/src/xs_curve.h	Sat Jan 27 02:52:02 2007 +0000
@@ -19,31 +19,30 @@
 typedef struct _XSCurve	XSCurve;
 typedef struct _XSCurveClass	XSCurveClass;
 
+typedef struct {
+	gfloat x,y;
+} t_xs_point;
 
-struct _XSCurve
-{
+
+struct _XSCurve {
 	GtkDrawingArea graph;
 
+	gint cursor_type;
 	gfloat min_x;
 	gfloat max_x;
 	gfloat min_y;
 	gfloat max_y;
 	GdkPixmap *pixmap;
-	gint height;                  /* (cached) graph height in pixels */
-	gint grab_point;              /* point currently grabbed */
+	gint height;		/* (cached) graph height in pixels */
+	gint grab_point;	/* point currently grabbed */
 	gint last;
 
-	/* (cached) curve points: */
-	gint num_points;
-	GdkPoint *point;
-
-	/* control points: */
-	gint num_ctlpoints;           /* number of control points */
-	gfloat (*ctlpoint)[2];        /* array of control points */
+	/* control points */
+	gint num_ctlpoints;	/* number of control points */
+	t_xs_point *ctlpoints;	/* array of control points */
 };
 
-struct _XSCurveClass
-{
+struct _XSCurveClass {
 	GtkDrawingAreaClass parent_class;
 };
 
@@ -51,15 +50,9 @@
 GtkType		xs_curve_get_type	(void);
 GtkWidget*	xs_curve_new		(void);
 void		xs_curve_reset		(XSCurve *curve);
-void		xs_curve_set_gamma	(XSCurve *curve, gfloat gamma);
 void		xs_curve_set_range	(XSCurve *curve,
 					 gfloat min_x, gfloat max_x,
 					 gfloat min_y, gfloat max_y);
-void		xs_curve_get_vector	(XSCurve *curve,
-					 int veclen, gfloat vector[]);
-void		xs_curve_set_vector	(XSCurve *curve,
-					 int veclen, gfloat vector[]);
-
 
 #ifdef __cplusplus
 }