Improved the API and memory allocation, added documentation.
---
gschem/include/prototype.h | 8 +-
gschem/src/gschem.c | 18 ++---
gschem/src/x_event.c | 49 ++----------
gschem/src/x_stroke.c | 192 ++++++++++++++++++++++++--------------------
4 files changed, 123 insertions(+), 144 deletions(-)
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index a9628b8..e2d71c3 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -841,10 +841,10 @@ void x_print_setup(GSCHEM_TOPLEVEL *w_current, char
*filename);
/* x_script.c */
void setup_script_selector(GSCHEM_TOPLEVEL *w_current);
/* x_stroke.c */
-void x_stroke_add_point(GSCHEM_TOPLEVEL *w_current, int x, int y);
-void x_stroke_erase_all(GSCHEM_TOPLEVEL *w_current);
-void x_stroke_free_all(void);
-int x_stroke_search_execute(char *sequence);
+void x_stroke_init (void);
+void x_stroke_free (void);
+void x_stroke_record (GSCHEM_TOPLEVEL *w_current, gint x, gint y);
+gint x_stroke_translate_and_execute (GSCHEM_TOPLEVEL *w_current);
/* x_window.c */
void x_window_setup (GSCHEM_TOPLEVEL *w_current);
void x_window_setup_colors(void);
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index d350903..144d9d4 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -44,11 +44,6 @@
#include <locale.h>
#endif
-#ifdef HAS_LIBSTROKE
-/* libstroke prototype */
-void stroke_init(void);
-#endif
-
typedef struct {
gschem_atexit_func func;
gpointer arg;
@@ -103,7 +98,9 @@ void gschem_quit(void)
/* o_text_freeallfonts();*/
s_attrib_free();
s_papersizes_free();
- x_stroke_free_all();
+#ifdef HAS_LIBSTROKE
+ x_stroke_free ();
+#endif /* HAS_LIBSTROKE */
s_color_destroy_all();
o_undo_cleanup();
/* s_stroke_free(); no longer needed */
@@ -177,11 +174,6 @@ void main_prog(void *closure, int argc, char *argv[])
s_log_init (filename);
g_free (filename);
-#ifdef HAS_LIBSTROKE
- stroke_init(); /* libstroke function */
- /* s_stroke_init(); no longer needed libgeda function */
-#endif
-
s_log_message(
_("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING,
DOTTED_VERSION, DATE_VERSION);
@@ -268,6 +260,10 @@ void main_prog(void *closure, int argc, char *argv[])
x_repaint_background (w_current);
w_current->grid = save_grid;
+#ifdef HAS_LIBSTROKE
+ x_stroke_init ();
+#endif /* HAS_LIBSTROKE */
+
for (i = argv_index; i < argc; i++) {
if (g_path_is_absolute(argv[i]))
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index d087a57..a1015c7 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -42,16 +42,8 @@ int throttle = 0;
/* used for the stroke stuff */
#ifdef HAS_LIBSTROKE
-
-#define MAX_SEQUENCE 20
static int DOING_STROKE = FALSE;
-char sequence[MAX_SEQUENCE+1];
-
-/* libstroke prototypes */
-void stroke_init (void);
-void stroke_record (int x, int y);
-int stroke_trans (char *sequence);
-#endif
+#endif /* HAS_LIBSTROKE */
/*! \todo Finish function documentation!!!
* \brief
@@ -426,8 +418,8 @@ gint x_event_button_pressed(GtkWidget *widget,
GdkEventButton *event,
case(STROKE):
DOING_STROKE=TRUE;
break;
+#endif /* HAS_LIBSTROKE */
-#endif
case(MID_MOUSEPAN_ENABLED):
w_current->event_state = MOUSEPAN; /* start */
w_current->inside_action = 1;
@@ -717,37 +709,10 @@ gint x_event_button_released(GtkWidget *widget,
GdkEventButton *event,
#ifdef HAS_LIBSTROKE
case(STROKE):
-
DOING_STROKE = FALSE;
-
- if (stroke_trans (sequence) == TRUE) {
- if (stroke_info_mode) {
- printf ("LibStroke Translation"
- " succeeded: ");
- }
- } else {
- if (stroke_info_mode) {
- printf ("LibStroke Translation"
- " failed: ");
- }
- }
-
- if (stroke_info_mode) {
- printf ("Sequence=\"%s\"\n",sequence);
- }
-
- x_stroke_erase_all(w_current);
-
- /* new way written by Stefan Petersen */
- /* much better */
- if (x_stroke_search_execute(sequence)) {
-
- if (stroke_info_mode) {
- printf("Sequence understood\n");
- }
- }
+ x_stroke_translate_and_execute (w_current);
break;
-#endif
+#endif /* HAS_LIBSTROKE */
case(MID_MOUSEPAN_ENABLED):
w_current->doing_pan=FALSE;
@@ -811,12 +776,10 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion
*event,
#ifdef HAS_LIBSTROKE
if (DOING_STROKE == TRUE) {
- x_stroke_add_point(w_current, (int) event->x, (int) event->y);
-
- stroke_record ((int) event->x, (int) event->y);
+ x_stroke_record (w_current, event->x, event->y);
return(0);
}
-#endif
+#endif /* HAS_LIBSTROKE */
/* skip the moving event if there are other moving events in the
gdk event queue (Werner)
diff --git a/gschem/src/x_stroke.c b/gschem/src/x_stroke.c
index a557761..bc22ec0 100644
--- a/gschem/src/x_stroke.c
+++ b/gschem/src/x_stroke.c
@@ -19,8 +19,6 @@
*/
#include <config.h>
-#include <math.h>
-
#include <libgeda/libgeda.h>
#include "../include/gschem_struct.h"
@@ -31,118 +29,140 @@
#include <dmalloc.h>
#endif
-typedef struct st_stroke_point STROKE_POINT;
+#ifdef HAS_LIBSTROKE
+#include <stroke.h>
+
+/*
+ * <B>stroke_points</B> is an array of points for the stroke
+ * footprints. The points of the stroke are displayed over the display
+ * area of the main window. They have to be erased when the stroke is
+ * translated and the sequence evaluated.
+ *
+ * Its size will never exceed <B>STROKE_MAX_POINTS</B> (the limit in
+ * number of points of a stroke provided by libstroke).
+ */
+typedef struct {
+ gint x, y;
+} StrokePoint;
-struct st_stroke_point {
- int x, y;
- STROKE_POINT *next;
-};
+static GArray *stroke_points = NULL;
-static STROKE_POINT *stroke_points = NULL;
-/*! \todo Finish function documentation!!!
- * \brief
+/*! \brief Initializes the stroke interface.
* \par Function Description
+ * This is the initialization function for the stroke interface. It
+ * initializes the libstroke library and prepare an array of points
+ * for the mouse footprints.
*
+ * This function has to be called only once at application
+ * initialization before any use of the stroke interface.
*/
-void x_stroke_add_point(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void
+x_stroke_init (void)
{
- STROKE_POINT *new_point;
-
- new_point = (STROKE_POINT *) g_malloc(sizeof(STROKE_POINT));
-
- new_point->x = x;
- new_point->y = y;
-
- if (stroke_points == NULL) {
- stroke_points = new_point;
- stroke_points->next = NULL;
- } else {
- new_point->next = stroke_points;
- stroke_points = new_point;
- }
+ g_return_if_fail (stroke_points == NULL);
+
+ stroke_init ();
- gdk_gc_set_foreground(w_current->gc,
- x_get_color(w_current->stroke_color));
-
- gdk_draw_point(w_current->backingstore, w_current->gc, x, y);
- o_invalidate_rect (w_current, x, y, x, y);
+ stroke_points = g_array_new (FALSE,
+ FALSE,
+ sizeof (StrokePoint));
}
-/*! \todo Finish function documentation!!!
- * \brief
+/*! \brief Frees memory of the stroke interface.
* \par Function Description
- *
- * \note
- * traverse list as well as free each point as you go along
+ * This function frees the memory used for the mouse footprint
+ * points. It terminates the use of the stroke interface.
*/
-void x_stroke_erase_all(GSCHEM_TOPLEVEL *w_current)
+void
+x_stroke_free (void)
{
- STROKE_POINT *temp;
-
- while(stroke_points != NULL) {
-
-#if DEBUG
- printf("%d %d\n", stroke_points->x, stroke_points->y);
-#endif
-
- /* was xor, wasn't working out... see above note */
- gdk_gc_set_foreground(
- w_current->gc,
- x_get_color(w_current->toplevel->background_color));
-
- gdk_draw_point(w_current->backingstore, w_current->gc,
- stroke_points->x, stroke_points->y);
- o_invalidate_rect (w_current, stroke_points->x, stroke_points->y,
- stroke_points->x, stroke_points->y);
-
- temp = stroke_points;
- stroke_points = stroke_points->next;
- g_free(temp);
- }
-
+ g_return_if_fail (stroke_points != NULL);
+
+ g_array_free (stroke_points, TRUE);
stroke_points = NULL;
}
-/*! \todo Finish function documentation!!!
- * \brief
+/*! \brief Records a new point for the stroke.
* \par Function Description
+ * This function adds the point (<B>x</B>,<B>y</B>) as a new point in
+ * the stroke.
*
+ * The footprint is updated and the new point is drawn on the drawing area.
+ *
+ * \param [in] w_current The GSCHEM_TOPLEVEL object.
+ * \param [in] x The X coord of the new point.
+ * \param [in] Y The X coord of the new point.
*/
-void x_stroke_free_all(void)
+void
+x_stroke_record (GSCHEM_TOPLEVEL *w_current, gint x, gint y)
{
- STROKE_POINT *temp;
-
- while(stroke_points != NULL) {
-#if DEBUG
- printf("%d %d\n", stroke_points->x, stroke_points->y);
-#endif
-
- temp = stroke_points;
- stroke_points = stroke_points->next;
- g_free(temp);
+ g_assert (stroke_points != NULL);
+
+ stroke_record (x, y);
+
+ if (stroke_points->len < STROKE_MAX_POINTS) {
+ StrokePoint point = { x, y };
+
+ g_array_append_val (stroke_points, point);
+
+ gdk_gc_set_foreground (w_current->gc,
+ x_get_color (w_current->stroke_color));
+ gdk_draw_point (w_current->window, w_current->gc, x, y);
}
-
- stroke_points = NULL;
+
}
-/*! \todo Finish function documentation!!!
- * \brief
+/*! \brief Evaluates the stroke.
* \par Function Description
+ * This function transforms the stroke input so far in an action.
*
- * \note
- * this is the function that does the actual work of the strokes
- * by executing the right guile function which is associated with the stroke
+ * It makes use of the guile procedure <B>eval-stroke</B> to evaluate
+ * the stroke sequence into a possible action. The mouse footprint is
+ * erased in this function.
+ *
+ * It returns 1 if the stroke has been successfully evaluated as an
+ * action. It returns 0 if libstroke failed to transform the stroke
+ * or there is no action attached to the stroke.
+ *
+ * \param [in] w_current The GSCHEM_TOPLEVEL object.
+ * \returns 1 on success, 0 otherwise.
*/
-int x_stroke_search_execute(char *sequence)
+gint
+x_stroke_translate_and_execute (GSCHEM_TOPLEVEL *w_current)
{
- gchar *guile_string;
- SCM eval;
+ gchar sequence[STROKE_MAX_SEQUENCE];
+ gint i;
+
+ g_assert (stroke_points != NULL);
+
+ /* erase footprint */
+ for (i = 0; i < stroke_points->len; i++) {
+ StrokePoint *point = &g_array_index (stroke_points, StrokePoint, i);
+
+ gdk_gc_set_foreground (w_current->gc,
+ x_get_color (
+ w_current->toplevel->background_color));
+ gdk_draw_point (w_current->window, w_current->gc,
+ point->x, point->y);
+ }
+ /* resets length of array */
+ stroke_points->len = 0;
+
+ /* try evaluating stroke */
+ if (stroke_trans ((char*)&sequence)) {
+ gchar *guile_string =
+ g_strdup_printf("(eval-stroke \"%s\")", sequence);
+ SCM ret;
- guile_string = g_strdup_printf("(eval-stroke \"%s\")", sequence);
+ ret = scm_c_eval_string (guile_string);
- eval = scm_c_eval_string (guile_string);
- g_free(guile_string);
+ g_free (guile_string);
- return (SCM_FALSEP (eval)) ? 0 : 1;
+ return (SCM_NFALSEP (ret));
+ }
+
+ return 0;
}
+
+#endif /* HAS_LIBSTROKE */
--
1.5.6
_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev