[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: pcb.git: branch: master updated (337fa8ba8094cee1ed291cec7bf29895ac7c9d72)



The branch, master has been updated
       via  337fa8ba8094cee1ed291cec7bf29895ac7c9d72 (commit)
      from  33dcf48124dc6164aa32393fc536b2e2f270f5b7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 src/hid.h                |   18 +++++
 src/hid/common/actions.c |  165 ++++++++++++++++++++++++++++++++++++----------
 src/hid/hidint.h         |    2 +-
 src/hid/lesstif/menu.c   |    2 +-
 4 files changed, 151 insertions(+), 36 deletions(-)


=================
 Commit Messages
=================

commit 337fa8ba8094cee1ed291cec7bf29895ac7c9d72
Author: DJ Delorie <dj@xxxxxxxxxxx>
Date:   Wed Mar 25 00:44:46 2009 -0400

    single-action register/deregister
    
    New API to support registering individual actions with a context for them,
    for example for scripting languages to register a hub dispatcher.
    From Igor2@xxxxxxxxxxx (Tibor Palinkas)

:100644 100644 f01b43f... dc73563... M	src/hid.h
:100644 100644 28f39be... 0f2dfb4... M	src/hid/common/actions.c
:100644 100644 a2148a0... 5840e20... M	src/hid/hidint.h
:100644 100644 266b5de... ca8ff4c... M	src/hid/lesstif/menu.c

=========
 Changes
=========

commit 337fa8ba8094cee1ed291cec7bf29895ac7c9d72
Author: DJ Delorie <dj@xxxxxxxxxxx>
Date:   Wed Mar 25 00:44:46 2009 -0400

    single-action register/deregister
    
    New API to support registering individual actions with a context for them,
    for example for scripting languages to register a hub dispatcher.
    From Igor2@xxxxxxxxxxx (Tibor Palinkas)

diff --git a/src/hid.h b/src/hid.h
index f01b43f..dc73563 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -86,7 +86,25 @@ extern "C"
     const char *syntax;
   } HID_Action;
 
+  /* This global variable is always set to the action context, before
+     an action callback is called. Action context can be specified
+     when registering an action with hid_register_action() Intended
+     for plugins with hub action callbacks. */
+  extern void *hid_action_context;
+
+  /* Register a singe action associated with an action context. Makes
+     a copy of HID_Action.  Intended for plugins to register actions
+     with a hub callback. */
+  extern void hid_register_action(const HID_Action *, void *);
+
+  /* Deregister an action registered using hid_register_action().
+     Action context pointer is copied in the 2nd argument if it's not
+     NULL.  Intended for plugins to deregister custom actions. */
+  extern void hid_deregister_action(const char *, void **);
+
+  /* Register a list of static actions without action context */
   extern void hid_register_actions (HID_Action *, int);
+
 #define REGISTER_ACTIONS(a) HIDCONCAT(void register_,a) ()\
 { hid_register_actions(a, sizeof(a)/sizeof(a[0])); }
 
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index 28f39be..0f2dfb4 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <assert.h>
 
 #include "global.h"
 #include "data.h"
@@ -26,14 +27,29 @@ typedef struct HID_ActionNode
   struct HID_ActionNode *next;
   HID_Action *actions;
   int n;
+  /* The registrar the callback function may use this pointer to
+     remember context; the action infrastructure will just pass it
+     along. */
+  void *context;
+  /* is this ActionNode registered runtime? (can be deregistered) */
+  int dynamic;
 } HID_ActionNode;
 
-HID_ActionNode *hid_action_nodes = 0;
+/* The master list of all actions registered */ 
+typedef struct HID_ActionContext
+{
+  HID_Action action;
+  void *context;
+} HID_ActionContext;
 static int n_actions = 0;
-static HID_Action *all_actions = 0;
+static HID_ActionContext *all_actions = NULL;
 
-void
-hid_register_actions (HID_Action * a, int n)
+HID_ActionNode *hid_action_nodes = NULL;
+
+void *hid_action_context = NULL;
+
+static void
+hid_register_actions_context (HID_Action * a, int n, void *context, int dynamic)
 {
   HID_ActionNode *ha;
 
@@ -41,26 +57,87 @@ hid_register_actions (HID_Action * a, int n)
   ha = (HID_ActionNode *) malloc (sizeof (HID_ActionNode));
   ha->next = hid_action_nodes;
   hid_action_nodes = ha;
-  ha->actions = a;
+  if (dynamic) {
+    assert(n == 1); /* we register dynamic actions one by one */
+    ha->actions = malloc(sizeof(HID_Action));
+    memcpy(ha->actions, a, sizeof(HID_Action));
+  }
+  else
+    ha->actions = a;
+
   ha->n = n;
+  ha->context = context;
+  ha->dynamic = dynamic;
   n_actions += n;
   if (all_actions)
     {
       free (all_actions);
-      all_actions = 0;
+      all_actions = NULL;
     }
 }
 
+void
+hid_register_actions (HID_Action * a, int n)
+{
+  hid_register_actions_context (a, n, NULL, 0);
+}
+
+void
+hid_register_action (const HID_Action * a, void *context)
+{
+  hid_register_actions_context (a, 1, context, 1);
+}
+
+void
+hid_deregister_action (const char *name, void **context)
+{
+  HID_ActionNode *prev, *ha;
+
+  if (context != NULL)
+    *context = NULL;
+
+  /* find the action in hid_action_nodes */
+  for(prev = NULL, ha = hid_action_nodes; ha != NULL; prev = ha, ha = ha->next) {
+    if (ha->dynamic) {
+      if (strcmp(ha->actions->name, name) == 0) {
+	/* found the action in the tree, save context */
+	if (context != NULL)
+	  *context = ha->context;
+
+	/* remove ha */
+	if (prev == NULL)
+	  hid_action_nodes = ha->next;
+	else
+	  prev->next = ha->next;
+
+	free(ha->actions);
+	free(ha);
+
+	/* to make sure the rebuild of the sorted list next time */
+	if (all_actions != NULL) {
+	  free (all_actions);
+	  all_actions = NULL;
+	}
+
+	n_actions--;
+	return;
+      }
+    }
+  }
+
+  /* action not found - nothing to do */
+}
+
 static int
 action_sort (const void *va, const void *vb)
 {
-  HID_Action *a = (HID_Action *) va;
-  HID_Action *b = (HID_Action *) vb;
-  return strcmp (a->name, b->name);
+  HID_ActionContext *a = (HID_ActionContext *) va;
+  HID_ActionContext *b = (HID_ActionContext *) vb;
+  return strcmp (a->action.name, b->action.name);
 }
 
 HID_Action *
-hid_find_action (const char *name)
+hid_find_action (const char *name, void **context)
 {
   HID_ActionNode *ha;
   int i, n, lower, upper;
@@ -68,14 +145,17 @@ hid_find_action (const char *name)
   if (name == NULL)
     return 0;
 
-  if (all_actions == 0)
+  if (all_actions == NULL)
     {
       n = 0;
-      all_actions = malloc (n_actions * sizeof (HID_Action));
+      all_actions = malloc (n_actions * sizeof (HID_ActionContext));
       for (ha = hid_action_nodes; ha; ha = ha->next)
-	for (i = 0; i < ha->n; i++)
-	  all_actions[n++] = ha->actions[i];
-      qsort (all_actions, n_actions, sizeof (HID_Action), action_sort);
+	for (i = 0; i < ha->n; i++) {
+	  all_actions[n].action = ha->actions[i];
+	  all_actions[n].context = ha->context;
+	  n++;
+	}
+      qsort (all_actions, n_actions, sizeof (HID_ActionContext), action_sort);
     }
 
 
@@ -85,10 +165,13 @@ hid_find_action (const char *name)
   while (lower < upper - 1)
     {
       i = (lower + upper) / 2;
-      n = strcmp (all_actions[i].name, name);
+      n = strcmp (all_actions[i].action.name, name);
       /*printf("try [%d].%s, cmp %d\n", i, all_actions[i].name, n); */
-      if (n == 0)
-	return all_actions + i;
+      if (n == 0) {
+	if (context != NULL)
+	  *context = all_actions[i].context;
+	return &(all_actions[i].action);
+      }
       if (n > 0)
 	upper = i;
       else
@@ -96,8 +179,11 @@ hid_find_action (const char *name)
     }
 
   for (i = 0; i < n_actions; i++)
-    if (strcasecmp (all_actions[i].name, name) == 0)
-      return all_actions + i;
+    if (strcasecmp (all_actions[i].action.name, name) == 0) {
+      if (*context != NULL)
+        *context = all_actions[i].context;
+      return &(all_actions[i].action);
+    }
 
   printf ("unknown action `%s'\n", name);
   return 0;
@@ -108,19 +194,19 @@ print_actions ()
 {
   int i;
   /* Forces them to be sorted in all_actions */
-  hid_find_action (hid_action_nodes->actions[0].name);
+  hid_find_action (hid_action_nodes->actions[0].name, NULL);
   fprintf (stderr, "Registered Actions:\n");
   for (i = 0; i < n_actions; i++)
     {
-      if (all_actions[i].description)
-	fprintf (stderr, "  %s - %s\n", all_actions[i].name,
-		 all_actions[i].description);
+      if (all_actions[i].action.description)
+	fprintf (stderr, "  %s - %s\n", all_actions[i].action.name,
+		 all_actions[i].action.description);
       else
-	fprintf (stderr, "  %s\n", all_actions[i].name);
-      if (all_actions[i].syntax)
+	fprintf (stderr, "  %s\n", all_actions[i].action.name);
+      if (all_actions[i].action.syntax)
 	{
 	  const char *bb, *eb;
-	  bb = eb = all_actions[i].syntax;
+	  bb = eb = all_actions[i].action.syntax;
 	  while (1)
 	    {
 	      for (eb = bb; *eb && *eb != '\n'; eb++)
@@ -161,16 +247,16 @@ dump_actions ()
 {
   int i;
   /* Forces them to be sorted in all_actions */
-  hid_find_action (hid_action_nodes->actions[0].name);
+  hid_find_action (hid_action_nodes->actions[0].name, NULL);
   for (i = 0; i < n_actions; i++)
     {
-      const char *desc = all_actions[i].description;
-      const char *synt = all_actions[i].syntax;
+      const char *desc = all_actions[i].action.description;
+      const char *synt = all_actions[i].action.syntax;
 
       desc = desc ? desc : "";
       synt = synt ? synt : "";
 
-      printf ("A%s\n", all_actions[i].name);
+      printf ("A%s\n", all_actions[i].action.name);
       dump_string ('D', desc);
       dump_string ('S', synt);
     }
@@ -200,8 +286,10 @@ hid_actionl (const char *name, ...)
 int
 hid_actionv (const char *name, int argc, char **argv)
 {
-  int x = 0, y = 0, i;
+  int x = 0, y = 0, i, ret;
   HID_Action *a;
+  void *old_context;
+  void *context;
 
   if (Settings.verbose && name)
     {
@@ -211,12 +299,21 @@ hid_actionv (const char *name, int argc, char **argv)
       printf (")\033[0m\n");
     }
 
-  a = hid_find_action (name);
+  a = hid_find_action (name, &context);
   if (!a)
     return 1;
   if (a->need_coord_msg)
     gui->get_coords (a->need_coord_msg, &x, &y);
-  return a->trigger_cb (argc, argv, x, y);
+
+  /* save old action context and set it to the context associated with the action */
+  old_context = hid_action_context;
+  hid_action_context = context;
+
+  ret = a->trigger_cb (argc, argv, x, y);
+
+  /* restore old context and return */
+  hid_action_context = old_context;
+  return ret;
 }
 
 int
diff --git a/src/hid/hidint.h b/src/hid/hidint.h
index a2148a0..5840e20 100644
--- a/src/hid/hidint.h
+++ b/src/hid/hidint.h
@@ -35,7 +35,7 @@ typedef struct HID_AttrNode
 
 extern HID_AttrNode *hid_attr_nodes;
 
-HID_Action *hid_find_action (const char *name);
+HID_Action *hid_find_action (const char *name, void **context);
 
 HID_Flag *hid_find_flag (const char *name);
 
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index 266b5de..ca8ff4c 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -818,7 +818,7 @@ lesstif_call_action (const char *aname, int argc, char **argv)
 
   if (!aname)
     return 1;
-  a = hid_find_action (aname);
+  a = hid_find_action (aname, NULL);
   if (!a)
     {
       int i;




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs