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

Reply via email to