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

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



The branch, master has been updated
       via  c85fd7cfa63f6a89cb8b9a03dd0002ffdb613729 (commit)
      from  5073f41e743fe69e23806d409b23ee7293642bb7 (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/Makefile.am                 |    2 +
 src/action.c                    |    2 +-
 src/gpcb-menu.res               |   21 ++--
 src/hid/common/actions.c        |    3 +-
 src/hid/common/hid_resource.c   |  205 +++++++++++++++++++++++++++++++++++
 src/hid/common/hid_resource.h   |   17 +++
 src/hid/gtk/gtkhid-main.c       |   55 ++++++++++
 src/hid/gtk/gui-output-events.c |  145 ++-----------------------
 src/hid/gtk/gui-top-window.c    |    5 +-
 src/hid/gtk/gui.h               |   18 ++--
 src/hid/lesstif/lesstif.h       |    8 --
 src/hid/lesstif/main.c          |  226 ++++++---------------------------------
 src/hid/lesstif/menu.c          |    8 +-
 13 files changed, 354 insertions(+), 361 deletions(-)
 create mode 100644 src/hid/common/hid_resource.c
 create mode 100644 src/hid/common/hid_resource.h


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

commit c85fd7cfa63f6a89cb8b9a03dd0002ffdb613729
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Teaching GTK hid to use mouse resources
    
    I had some free time over the weekend and have been wanting to get my
    hands dirty in the PCB code so I took a crack at this and wanted to
    get some feedback.
    
    Attached is a patch with a detailed commit message of what I did, but
    the general idea was to move the lesstif hid's handling of the mouse
    resources into a common hid file (which I called hid_resource) and
    have the gtk hid use that instead of being hardcoded.  This way the
    hid's are only responsible for catching the button press, determining
    which modifier keys were active, then calling the common code to
    handle it.  The common code does what the lesstif hid does, calls the
    actions defined in the resource file.  In theory more common stuff
    could be moved to hid_resource, the code to find and load the resource
    file, for example, is nearly identical in both hids.
    
    I changed up the Mouse resource in gpcb-menu.res to match the
    hardcoded behavior of the gtk hid as closely as possible (see the
    commit message for details).
    
    I've played around with it a bit and it seems to be working, but as
    this my first time meddling with the code, I'm sure I missed some
    stuff.  If anybody has time to look it over and/or try it out that
    would be great.  Comments regarding the approach, formatting, style,
    etc. are all appreciated (I did my best to match the style of the
    surrounding code).
    
    Jared

:100644 100644 48b150d... 1d5e818... M	src/Makefile.am
:100644 100644 ab47e87... eac8d5e... M	src/action.c
:100644 100644 6cde1f0... 50ac639... M	src/gpcb-menu.res
:100644 100644 0f2dfb4... 1829af6... M	src/hid/common/actions.c
:000000 100644 0000000... 8802070... A	src/hid/common/hid_resource.c
:000000 100644 0000000... ab382fc... A	src/hid/common/hid_resource.h
:100644 100644 c27f857... 769f36b... M	src/hid/gtk/gtkhid-main.c
:100644 100644 1a62dd8... adbdbea... M	src/hid/gtk/gui-output-events.c
:100644 100644 3812e68... ca17446... M	src/hid/gtk/gui-top-window.c
:100644 100644 7a46672... 17093ac... M	src/hid/gtk/gui.h
:100644 100644 38f0772... fe31371... M	src/hid/lesstif/lesstif.h
:100644 100644 99f9851... 66dfb66... M	src/hid/lesstif/main.c
:100644 100644 dce6773... d3e421d... M	src/hid/lesstif/menu.c

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

commit c85fd7cfa63f6a89cb8b9a03dd0002ffdb613729
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Teaching GTK hid to use mouse resources
    
    I had some free time over the weekend and have been wanting to get my
    hands dirty in the PCB code so I took a crack at this and wanted to
    get some feedback.
    
    Attached is a patch with a detailed commit message of what I did, but
    the general idea was to move the lesstif hid's handling of the mouse
    resources into a common hid file (which I called hid_resource) and
    have the gtk hid use that instead of being hardcoded.  This way the
    hid's are only responsible for catching the button press, determining
    which modifier keys were active, then calling the common code to
    handle it.  The common code does what the lesstif hid does, calls the
    actions defined in the resource file.  In theory more common stuff
    could be moved to hid_resource, the code to find and load the resource
    file, for example, is nearly identical in both hids.
    
    I changed up the Mouse resource in gpcb-menu.res to match the
    hardcoded behavior of the gtk hid as closely as possible (see the
    commit message for details).
    
    I've played around with it a bit and it seems to be working, but as
    this my first time meddling with the code, I'm sure I missed some
    stuff.  If anybody has time to look it over and/or try it out that
    would be great.  Comments regarding the approach, formatting, style,
    etc. are all appreciated (I did my best to match the style of the
    surrounding code).
    
    Jared

diff --git a/src/Makefile.am b/src/Makefile.am
index 48b150d..1d5e818 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -145,6 +145,8 @@ PCB_SRCS = \
 	hid/common/extents.c \
 	hid/common/draw_helpers.c \
 	hid/common/draw_helpers.h \
+	hid/common/hid_resource.c \
+	hid/common/hid_resource.h \
 	hid/hidint.h 
 
 EXTRA_pcb_SOURCES = ${DBUS_SRCS} toporouter.c toporouter.h
diff --git a/src/action.c b/src/action.c
index ab47e87..eac8d5e 100644
--- a/src/action.c
+++ b/src/action.c
@@ -3086,8 +3086,8 @@ ActionMode (int argc, char **argv, int x, int y)
 	      SaveMode ();
 	      saved_mode = True;
 	      SetMode (ARROW_MODE);
-	      NotifyMode ();
 	    }
+          NotifyMode ();
 	  break;
 #endif
 	case F_Text:
diff --git a/src/gpcb-menu.res b/src/gpcb-menu.res
index 6cde1f0..50ac639 100644
--- a/src/gpcb-menu.res
+++ b/src/gpcb-menu.res
@@ -12,23 +12,24 @@ Mouse =
 {
   Left = {
     Mode(Notify)
+    ctrl = { Mode(Save) Mode(None) Mode(Restore) Mode(Notify) }
+    shift-ctrl = { Mode(Save) Mode(Remove) Mode(Notify) Mode(Restore) }
     up = Mode(Release)
   }
   Right = {
-    { Mode(Save) Mode(Rotate) Mode(Notify) Mode(Release) Mode(Restore) }
+    Pan(1)
+    up = Pan(0)
+    shift = Popup(Popup1)
     ctrl = Display(CycleCrosshair)
   }
   Middle = {
-    Pan(1)
-    up = Pan(0)
-    ctrl = Pan(thumb,1)
-    ctrl-up = Pan(thumb,0)
+    Mode(Stroke)
+    up = Mode(Release)
+    ctrl = { Mode(Save) Mode(Copy) Mode(Notify) }
+    up-ctrl = { Mode(Notify) Mode(Restore) }
+    shift-ctrl = { Display(ToggleRubberbandMode) Mode(Save) Mode(Move) Mode(Notify) }
+    up-shift-ctrl = { Mode(Notify) Mode(Restore) Display(ToggleRubberbandMode) }
   }
-  Up = Zoom(0.8)
-  Down = Zoom(1.25)
-# If you want zoom to center, do this instead.
-#Up = { {Zoom(0.8) Center()} }
-#Down = { {Zoom(1.25) Center()} }
 }
 
 MainMenu =
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index 0f2dfb4..1829af6 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -302,8 +302,7 @@ hid_actionv (const char *name, int argc, char **argv)
   a = hid_find_action (name, &context);
   if (!a)
     return 1;
-  if (a->need_coord_msg)
-    gui->get_coords (a->need_coord_msg, &x, &y);
+  gui->get_coords (a->need_coord_msg, &x, &y);
 
   /* save old action context and set it to the context associated with the action */
   old_context = hid_action_context;
diff --git a/src/hid/common/hid_resource.c b/src/hid/common/hid_resource.c
new file mode 100644
index 0000000..8802070
--- /dev/null
+++ b/src/hid/common/hid_resource.c
@@ -0,0 +1,205 @@
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "global.h"
+#include "hid.h"
+#include "resource.h"
+#include "hid/common/hid_resource.h"
+
+/* #define DEBUG_HID_RESOURCE */
+
+static int button_count;   // number of buttons we have actions for
+static int *button_nums;   // list of button numbers
+static int *mod_count;     // how many mods they have
+static unsigned *mods;     // mods, in order, one button after another
+static Resource** actions; // actions, in order, one button after another
+
+static Resource *
+res_wrap (char *value)
+{
+  Resource *tmp;
+  tmp = resource_create (0);
+  resource_add_val (tmp, 0, value, 0);
+  return tmp;
+}
+
+static unsigned
+parse_mods (char *value)
+{
+  unsigned m = 0;
+  long int mod_num;
+  char *s;
+
+  for (s=value; *s; s++)
+    *s = tolower(*s);
+
+  s = strstr(value, "mod");
+  if (s)
+    {
+      s += 3; // skip "mod" to get to number
+      errno = 0;
+      mod_num = strtol(s, (char**) NULL, 0);
+      if (!errno)
+        m |= M_Mod(mod_num);
+    }
+  if (strstr(value, "shift"))
+    m |= M_Shift;
+  if (strstr(value, "ctrl"))
+    m |= M_Ctrl;
+  if (strstr(value, "alt"))
+    m |= M_Alt;
+  if (strstr(value, "up"))
+    m |= M_Release;
+  return m;
+}
+
+static int
+button_name_to_num (const char *name)
+{
+  /* All mouse-related resources must be named.  The name is the
+     mouse button number.  */
+  if (!name)
+    return -1;
+  else if (strcasecmp (name, "left") == 0)
+    return 1;
+  else if (strcasecmp (name, "middle") == 0)
+    return 2;
+  else if (strcasecmp (name, "right") == 0)
+    return 3;
+  else if (strcasecmp (name, "up") == 0)
+    return 4;
+  else if (strcasecmp (name, "down") == 0)
+    return 5;
+  else
+    return atoi (name);
+}
+
+void
+load_mouse_resource (Resource *res)
+{
+  int bi, mi, a;
+  int action_count;
+#ifdef DEBUG_HID_RESOURCE
+  fprintf(stderr, "note mouse resource:\n");
+  resource_dump (res);
+#endif
+
+  button_count = res->c;
+  button_nums = malloc(res->c * sizeof(int));
+  mod_count = malloc(res->c * sizeof(int));
+  action_count = 0;
+  for (bi=0; bi<res->c; bi++)
+    {
+      if (res->v[bi].value)
+        action_count++;
+
+      if (res->v[bi].subres)
+        action_count += res->v[bi].subres->c;
+
+    }
+  mods = malloc(action_count * sizeof(int));
+  actions = malloc(action_count * sizeof(Resource*));
+
+  a = 0;
+  for (bi=0; bi<res->c; bi++)
+    {
+      int button_num = button_name_to_num(res->v[bi].name);
+
+      if (button_num < 0)
+	continue;
+
+      button_nums[bi] = button_num;
+      mod_count[bi] = 0;
+
+      if (res->v[bi].value)
+        {
+          mods[a] = 0;
+          actions[a++] = res_wrap (res->v[bi].value);         
+          mod_count[bi] = 1;
+        }
+
+      if (res->v[bi].subres)
+	{
+	  Resource *m = res->v[bi].subres;
+          mod_count[bi] += m->c;
+
+	  for (mi=0; mi<m->c; mi++, a++)
+	    {
+	      switch (resource_type (m->v[mi]))
+		{
+		case 1: /* subres only */
+                  mods[a] = 0;
+                  actions[a] = m->v[mi].subres;
+		  break;
+
+		case 10: /* value only */
+                  mods[a] = 0;
+                  actions[a] = res_wrap (m->v[mi].value);
+		  break;
+
+		case 101: /* name = subres */
+		  mods[a] = parse_mods (m->v[mi].name);
+		  actions[a] = m->v[mi].subres;
+		  break;
+
+		case 110: /* name = value */
+		  mods[a] = parse_mods (m->v[mi].name);
+		  actions[a] = res_wrap (m->v[mi].value);
+		  break;
+		}
+	    }
+	}
+    }
+}
+
+static Resource*
+find_best_action (int button, int start, unsigned mod_mask)
+{
+  int i, j;
+  int count = mod_count[button];
+  unsigned search_mask = mod_mask & ~M_Release;
+  unsigned release_mask = mod_mask & M_Release;
+
+  // look for exact mod match
+  for (i=start; i<start+count; i++)
+    if (mods[i] == mod_mask) {
+      return actions[i];
+    }
+
+  for (j=search_mask-1; j>=0; j--)
+    if ((j & search_mask) == j) // this would work
+      for (i=start; i<start+count; i++) // search for it
+        if (mods[i] == (j | release_mask))
+          return actions[i];
+
+  return NULL;
+}
+
+void
+do_mouse_action (int button, int mod_mask)
+{
+  Resource *action = NULL;
+  int bi, i, a;
+
+  // find the right set of actions;
+  a = 0;
+  for (bi=0; bi<button_count && !action; bi++)
+    if (button_nums[bi] == button)
+      {
+        action = find_best_action(bi, a, mod_mask);
+        break;
+      }
+    else
+      a += mod_count[bi]; // skip this buttons actions
+
+  if (!action)
+    return;
+
+  for (i = 0; i < action->c; i++)
+    if (action->v[i].value)
+      if (hid_parse_actions (action->v[i].value, hid_actionv))
+	return;
+}
+
+
diff --git a/src/hid/common/hid_resource.h b/src/hid/common/hid_resource.h
new file mode 100644
index 0000000..ab382fc
--- /dev/null
+++ b/src/hid/common/hid_resource.h
@@ -0,0 +1,17 @@
+
+#ifndef __HID_RESOURCE_INCLUDED__
+#define __HID_RESOURCE_INCLUDED__
+
+#include "resource.h"
+
+#define M_Shift   1
+#define M_Ctrl    2
+#define M_Mod(n)  (1<<(n+1))
+#define M_Alt     M_Mod(1)
+#define M_Multi   M_Mod(2)
+#define M_Release (~((unsigned)-1>>1)) // set the top bit
+
+void load_mouse_resource (Resource *res);
+void do_mouse_action (int button, int mods);
+
+#endif
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index c27f857..769f36b 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -2455,6 +2455,60 @@ SetUnits (int argc, char **argv, int x, int y)
 }
 
 /* ------------------------------------------------------------ */
+static const char pan_syntax[] =
+"Pan([thumb], Mode)";
+
+static const char pan_help[] =
+"Start or stop panning (Mode = 1 to start, 0 to stop)\n"
+"Optional thumb argument is ignored for now in gtk hid.\n";
+
+/* %start-doc actions Pan
+
+Start or stop panning.  To start call with Mode = 1, to stop call with
+Mode = 0.  If the Mode is turned on and off with the cross hairs at
+the same coordinates, the auto pan mode is toggled.
+
+%end-doc */
+
+static int
+PanAction (int argc, char **argv, int x, int y)
+{
+  static int on_x, on_y;
+  int mode;
+
+  if (!ghidgui)
+    return 0;
+
+  if (argc != 1 && argc != 2)
+    AFAIL (pan);
+
+  if (argc == 1)
+    mode = atoi(argv[0]);
+  else
+    {
+      mode = atoi(argv[1]);
+      Message ("The gtk gui currently ignores the optional first argument"
+               "to the Pan action.\nFeel free to provide patches.\n");
+    }
+
+  gport->panning = mode;
+
+  if (mode == 1)
+    {
+      on_x = x;
+      on_y = y;
+    }
+  else if (x == on_x && y == on_y)
+    {
+      ghid_show_crosshair (FALSE);
+      ghidgui->auto_pan_on = !ghidgui->auto_pan_on;
+      ghid_show_crosshair (TRUE);
+    }
+
+  return 0;
+}
+
+/* ------------------------------------------------------------ */
 static const char popup_syntax[] =
 "Popup(MenuName, [Button])";
 
@@ -2535,6 +2589,7 @@ HID_Action ghid_main_action_list[] = {
   {"LayerGroupsChanged", 0, LayerGroupsChanged},
   {"LibraryChanged", 0, LibraryChanged},
   {"Load", 0, Load},
+  {"Pan", 0, PanAction, pan_help, pan_syntax},
   {"PCBChanged", 0, PCBChanged},
   {"PointCursor", 0, PointCursor},
   {"Popup", 0, Popup, popup_help, popup_syntax},
diff --git a/src/hid/gtk/gui-output-events.c b/src/hid/gtk/gui-output-events.c
index 1a62dd8..adbdbea 100644
--- a/src/hid/gtk/gui-output-events.c
+++ b/src/hid/gtk/gui-output-events.c
@@ -34,6 +34,7 @@
 
 #include "gui.h"
 #include "gtkhid.h"
+#include "hid/common/hid_resource.h"
 
 #include <gdk/gdkkeysyms.h>
 
@@ -213,10 +214,13 @@ static gint event_x, event_y;
 void
 ghid_get_coords (const char *msg, int *x, int *y)
 {
-  if (!ghid_port.has_entered)
+  if (!ghid_port.has_entered && msg)
     ghid_get_user_xy (msg);
-  *x = SIDE_X (gport->view_x);
-  *y = SIDE_Y (gport->view_y);
+  if (ghid_port.has_entered)
+    {
+      *x = SIDE_X (gport->view_x);
+      *y = SIDE_Y (gport->view_y);
+    }
 }
 
 gboolean
@@ -621,111 +625,31 @@ in_draw_state (void)
   return FALSE;
 }
 
-static gboolean draw_state_reset;
-static gint x_press, y_press;
-
 gboolean
 ghid_port_button_press_cb (GtkWidget * drawing_area,
 			   GdkEventButton * ev, GtkUIManager * ui)
 {
-  GtkWidget *menu = gtk_ui_manager_get_widget (ui, "/Popup1");
   ModifierKeysState mk;
-  gboolean drag, start_pan = FALSE;
+  gboolean drag;
   GdkModifierType state;
 
   /* Reject double and triple click events */
   if (ev->type != GDK_BUTTON_PRESS) return TRUE;
 
-  x_press = ev->x;
-  y_press = ev->y;
-
   ghid_note_event_location (ev);
   state = (GdkModifierType) (ev->state);
   mk = ghid_modifier_keys_state (&state);
   ghid_show_crosshair (FALSE);
   HideCrosshair (TRUE);
   drag = have_crosshair_attachments ();
-  draw_state_reset = FALSE;
 
-  switch (ev->button)
-    {
-    case 1:
-      if (mk == NONE_PRESSED || mk == SHIFT_PRESSED)
-	hid_actionl ("Mode", "Notify", NULL);
-      else if (mk == CONTROL_PRESSED)
-	{
-	  hid_actionl ("Mode", "Save", NULL);
-	  hid_actionl ("Mode", "None", NULL);
-	  hid_actionl ("Mode", "Restore", NULL);
-	  hid_actionl ("Mode", "Notify", NULL);
-	}
-      else if (mk == SHIFT_CONTROL_PRESSED)
-	{
-	  hid_actionl ("Mode", "Save", NULL);
-	  hid_actionl ("Mode", "Remove", NULL);
-	  hid_actionl ("Mode", "Notify", NULL);
-	  hid_actionl ("Mode", "Restore", NULL);
-	}
-      break;
+  do_mouse_action(ev->button, mk);
 
-    case 2:
-      if (mk == NONE_PRESSED && in_draw_state ())
-	{
-	  if (Settings.Mode == LINE_MODE)
-	    hid_actionl ("Mode", "Line", NULL);
-	  else if (Settings.Mode == ARC_MODE)
-	    hid_actionl ("Mode", "Arc", NULL);
-	  else if (Settings.Mode == RECTANGLE_MODE)
-	    hid_actionl ("Mode", "Rectangle", NULL);
-	  else if (Settings.Mode == POLYGON_MODE)
-	    hid_actionl ("Mode", "Polygon", NULL);
-
-	  hid_actionl ("Mode", "Notify", NULL);
-	  draw_state_reset = TRUE;
-	}
-      else if (mk == NONE_PRESSED)
-	{
-	  hid_actionl ("Mode", "Save", NULL);
-	  hid_actionl ("Mode", "Stroke", NULL);
-	}
-      else if (mk == CONTROL_PRESSED)
-	{
-	  hid_actionl ("Mode", "Save", NULL);
-	  hid_actionl ("Mode", "Copy", NULL);
-	  hid_actionl ("Mode", "Notify", NULL);
-	}
-      else if (mk == SHIFT_CONTROL_PRESSED)
-	{
-	  hid_actionl ("Display", "ToggleRubberbandMode", NULL);
-	  hid_actionl ("Mode", "Save", NULL);
-	  hid_actionl ("Mode", "Move", NULL);
-	  hid_actionl ("Mode", "Notify", NULL);
-	}
-      break;
-
-    case 3:
-      if (mk == NONE_PRESSED)
-	{
-	  ghid_mode_cursor (PAN_MODE);
-	  start_pan = TRUE;
-	}
-      else if (mk == SHIFT_PRESSED
-	       && !ghidgui->command_entry_status_line_active)
-	{
-	  ghidgui->in_popup = TRUE;
-	  gtk_widget_grab_focus (drawing_area);
-	  if (GTK_IS_MENU (menu))
-	    gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
-			    drawing_area, 3, ev->time);
-	}
-
-      break;
-    }
   ghid_invalidate_all ();
   RestoreCrosshair (TRUE);
   ghid_set_status_line_label ();
   ghid_show_crosshair (TRUE);
-  if (!start_pan)
+  if (!gport->panning)
     g_idle_add (ghid_idle_cb, NULL);
   return TRUE;
 }
@@ -747,47 +671,8 @@ ghid_port_button_release_cb (GtkWidget * drawing_area,
   if (drag)
     HideCrosshair (TRUE);
 
-  switch (ev->button)
-    {
-    case 1:
-      hid_actionl ("Mode", "Release", NULL);	/* For all modifier states */
-      break;
-
-    case 2:
-      if (mk == NONE_PRESSED && !draw_state_reset)
-	{
-	  hid_actionl ("Mode", "Release", NULL);
-	  hid_actionl ("Mode", "Restore", NULL);
-	}
-      else if (mk == CONTROL_PRESSED)
-	{
-	  hid_actionl ("Mode", "Notify", NULL);
-	  hid_actionl ("Mode", "Restore", NULL);
-	}
-      else if (mk == SHIFT_CONTROL_PRESSED)
-	{
-	  hid_actionl ("Mode", "Notify", NULL);
-	  hid_actionl ("Mode", "Restore", NULL);
-	  hid_actionl ("Display", "ToggleRubberbandMode", NULL);
-	}
-      break;
+  do_mouse_action(ev->button, mk + M_Release);
 
-    case 3:
-      if (mk == SHIFT_PRESSED)
-	{
-	  hid_actionl ("Display", "Center", NULL);
-	  hid_actionl ("Display", "Restore", NULL);
-	}
-      else if (mk == CONTROL_PRESSED)
-	  hid_actionl ("Display", "CycleCrosshair", NULL);
-      else if (ev->x == x_press && ev->y == y_press)
-	{
-	  ghid_show_crosshair (FALSE);
-	  ghidgui->auto_pan_on = !ghidgui->auto_pan_on;
-	  ghid_show_crosshair (TRUE);
-	}
-      break;
-    }
   if (drag)
     {
       AdjustAttachedObjects ();
@@ -876,17 +761,11 @@ gint
 ghid_port_window_motion_cb (GtkWidget * widget,
 			    GdkEventButton * ev, GHidPort * out)
 {
-  ModifierKeysState mk;
   gdouble dx, dy;
   static gint x_prev = -1, y_prev = -1;
   gboolean moved;
-  GdkModifierType state;
-
-  state = (GdkModifierType) (ev->state);
-  mk = ghid_modifier_keys_state (&state);
 
-  if ((ev->state & GDK_BUTTON3_MASK) == GDK_BUTTON3_MASK
-      && mk == NONE_PRESSED)
+  if (out->panning)
     {
       if (gtk_events_pending ())
 	return FALSE;
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 3812e68..ca17446 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -86,6 +86,7 @@ a zoom in/out.
 #include "gui.h"
 #include "hid.h"
 #include "../hidint.h"
+#include "hid/common/hid_resource.h"
 
 #include "action.h"
 #include "autoplace.h"
@@ -3817,9 +3818,7 @@ ghid_load_menus (void)
   if (!mr)
     mr = resource_subres (bir, "Mouse");
   if (mr)
-    Message ("ghid_load_menus():  Mouse resources are currently ignored by the GTK HID.\n"
-	"Please feel free to submit a patch to implement this!\n"
-    );
+    load_mouse_resource (mr);
 
 }
 
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 7a46672..17093ac 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -29,6 +29,7 @@
 
 #include "global.h"
 #include "hid.h"
+#include "hid/common/hid_resource.h"
 
 #include "data.h"
 #include "misc.h"
@@ -210,6 +211,7 @@ typedef struct
   GdkCursorType X_cursor_shape;	/* and its shape */
 
   gboolean has_entered;
+  gboolean panning;
 
 /* zoom value is PCB units per screen pixel.  Larger numbers mean zooming
 |  out - the largest value means you are looking at the whole board.
@@ -227,14 +229,14 @@ extern GHidPort ghid_port, *gport;
 
 typedef enum
 {
-  NONE_PRESSED,
-  SHIFT_PRESSED,
-  CONTROL_PRESSED,
-  MOD1_PRESSED,
-  SHIFT_CONTROL_PRESSED,
-  SHIFT_MOD1_PRESSED,
-  CONTROL_MOD1_PRESSED,
-  SHIFT_CONTROL_MOD1_PRESSED
+  NONE_PRESSED               = 0,
+  SHIFT_PRESSED              = M_Shift,
+  CONTROL_PRESSED            = M_Ctrl,
+  MOD1_PRESSED               = M_Mod(1),
+  SHIFT_CONTROL_PRESSED      = M_Shift | M_Ctrl,
+  SHIFT_MOD1_PRESSED         = M_Shift | M_Mod(1),
+  CONTROL_MOD1_PRESSED       = M_Ctrl | M_Mod(1),
+  SHIFT_CONTROL_MOD1_PRESSED = M_Shift | M_Ctrl | M_Mod(1),
 }
 ModifierKeysState;
 
diff --git a/src/hid/lesstif/lesstif.h b/src/hid/lesstif/lesstif.h
index 38f0772..fe31371 100644
--- a/src/hid/lesstif/lesstif.h
+++ b/src/hid/lesstif/lesstif.h
@@ -22,11 +22,6 @@ extern int screen;
 Widget mainwind, work_area, command, hscroll, vscroll;
 Widget m_click;
 
-#define M_Shift 1
-#define M_Ctrl 2
-#define M_Alt 4
-#define M_Multi 8
-
 extern Widget lesstif_menu (Widget, char *, Arg *, int);
 extern int lesstif_key_event (XKeyEvent *);
 extern int lesstif_button_event (Widget w, XEvent * e);
@@ -60,9 +55,6 @@ extern char *lesstif_fileselect (const char *, const char *,
 				 char *, char *,
 				 const char *, int);
 extern void lesstif_log (const char *fmt, ...);
-#ifdef __RESOURCE_INCLUDED__
-extern void lesstif_note_mouse_resource(Resource *res);
-#endif
 
 #define need_idle_proc lesstif_need_idle_proc
 #define show_crosshair lesstif_show_crosshair
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 99f9851..66dfb66 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -29,6 +29,7 @@
 #include "hid.h"
 #include "../hidint.h"
 #include "hid/common/draw_helpers.h"
+#include "hid/common/hid_resource.h"
 #include "lesstif.h"
 
 #ifdef HAVE_LIBDMALLOC
@@ -1232,7 +1233,6 @@ zoom_by (double factor, int x, int y)
 static int panning = 0;
 static int shift_pressed;
 static int ctrl_pressed;
-static int alt_pressed;
 
 /* X and Y are in screen coordinates.  */
 static void
@@ -1308,29 +1308,6 @@ mod_changed (XKeyEvent * e, int set)
   in_move_event = 0;
 }
 
-#define M_Release 8
-#define MAX_MOUSE_BUTTON 5
-Resource *mouse_actions[MAX_MOUSE_BUTTON+2][16];
-
-static void
-do_mouse_action (int button, int rel_mask)
-{
-  int i;
-  int mods = (shift_pressed ? M_Shift : 0)
-    + (ctrl_pressed ? M_Ctrl : 0)
-    + (alt_pressed ? M_Alt : 0)
-    + rel_mask;
-  Resource *node = mouse_actions[button][mods];
-
-  if (!node)
-    return;
-
-  for (i = 0; i < node->c; i++)
-    if (node->v[i].value)
-      if (hid_parse_actions (node->v[i].value, lesstif_call_action))
-	return;
-}
-
 static void
 work_area_input (Widget w, XtPointer v, XEvent * e, Boolean * ctd)
 {
@@ -1351,35 +1328,44 @@ work_area_input (Widget w, XtPointer v, XEvent * e, Boolean * ctd)
       break;
 
     case ButtonPress:
-      if (pressed_button)
-	return;
-      /*printf("click %d\n", e->xbutton.button); */
-      if (lesstif_button_event (w, e))
+      {
+        int mods;
+        if (pressed_button)
+          return;
+        /*printf("click %d\n", e->xbutton.button); */
+        if (lesstif_button_event (w, e))
 	{
 	  ignore_release = 1;
 	  return;
 	}
-      ignore_release = 0;
-
-      HideCrosshair (True);
-      pressed_button = e->xbutton.button;
-      shift_pressed = (e->xbutton.state & ShiftMask);
-      ctrl_pressed = (e->xbutton.state & ControlMask);
-      alt_pressed = (e->xbutton.state & Mod1Mask);
-
-      do_mouse_action(e->xbutton.button, 0);
-      RestoreCrosshair (True);
-      break;
+        ignore_release = 0;
+
+        HideCrosshair (True);
+        pressed_button = e->xbutton.button;
+        mods = ((e->xbutton.state & ShiftMask) ? M_Shift : 0)
+          + ((e->xbutton.state & ControlMask) ? M_Ctrl : 0)
+          + ((e->xbutton.state & Mod1Mask) ? M_Alt : 0);
+        do_mouse_action(e->xbutton.button, mods);
+        RestoreCrosshair (True);
+        break;
+      }
 
     case ButtonRelease:
-      if (e->xbutton.button != pressed_button)
-	return;
-      lesstif_button_event (w, e);
-      HideCrosshair (True);
-      pressed_button = 0;
-      do_mouse_action (e->xbutton.button, M_Release);
-      RestoreCrosshair (True);
-      break;
+      {
+        int mods;
+        if (e->xbutton.button != pressed_button)
+          return;
+        lesstif_button_event (w, e);
+        HideCrosshair (True);
+        pressed_button = 0;
+        mods = ((e->xbutton.state & ShiftMask) ? M_Shift : 0)
+          + ((e->xbutton.state & ControlMask) ? M_Ctrl : 0)
+          + ((e->xbutton.state & Mod1Mask) ? M_Alt : 0)
+          + M_Release;
+        do_mouse_action (e->xbutton.button, mods);
+        RestoreCrosshair (True);
+        break;
+      }
 
     case MotionNotify:
       {
@@ -1422,152 +1408,6 @@ work_area_input (Widget w, XtPointer v, XEvent * e, Boolean * ctd)
     }
 }
 
-static Resource *
-res_wrap (char *value)
-{
-  Resource *tmp;
-  tmp = resource_create (0);
-  resource_add_val (tmp, 0, value, 0);
-  return tmp;
-}
-
-static int
-parse_mods (char *value)
-{
-  int m = 0;
-  /* This works because "shift" and "alt" have no 'c' in them,
-     etc.  */
-  if (strchr(value, 's') || strchr(value, 'S'))
-    m |= M_Shift;
-  if (strchr(value, 'c') || strchr(value, 'C'))
-    m |= M_Ctrl;
-  if (strchr(value, 'a') || strchr(value, 'A'))
-    m |= M_Alt;
-  if (strchr(value, 'u') || strchr(value, 'U'))
-    m |= M_Release;
-  return m;
-}
-
-void
-lesstif_note_mouse_resource (Resource *res)
-{
-  int bi, mi;
-#if 0
-  Resource *orig_actions[MAX_MOUSE_BUTTON+2][16];
-
-  fprintf(stderr, "note mouse resource:\n");
-  resource_dump (res);
-#endif
-
-  for (bi=0; bi<res->c; bi++)
-    {
-      int button_num;
-
-      /* All mouse-related resources must be named.  The name is the
-	 mouse button number.  */
-      if (!res->v[bi].name)
-	continue;
-      else if (strcasecmp (res->v[bi].name, "left") == 0)
-	button_num = 1;
-      else if (strcasecmp (res->v[bi].name, "middle") == 0)
-	button_num = 2;
-      else if (strcasecmp (res->v[bi].name, "right") == 0)
-	button_num = 3;
-      else if (strcasecmp (res->v[bi].name, "up") == 0)
-	button_num = 4;
-      else if (strcasecmp (res->v[bi].name, "down") == 0)
-	button_num = 5;
-      else
-	button_num = atoi (res->v[bi].name);
-
-      if (button_num < 1 || button_num > MAX_MOUSE_BUTTON)
-	continue;
-
-      if (res->v[bi].value)
-	mouse_actions[button_num][0] = res_wrap (res->v[bi].value);
-
-      if (res->v[bi].subres)
-	{
-	  Resource *m = res->v[bi].subres;
-	  int mods;
-
-	  for (mi=0; mi<m->c; mi++)
-	    {
-	      switch (resource_type (m->v[mi]))
-		{
-		case 1: /* subres only */
-		  mouse_actions[button_num][0] = m->v[mi].subres;
-		  break;
-
-		case 10: /* value only */
-		  mouse_actions[button_num][0] = res_wrap (m->v[mi].value);
-		  break;
-
-		case 101: /* name = subres */
-		  mods = parse_mods (m->v[mi].name);
-		  mouse_actions[button_num][mods] = m->v[mi].subres;
-		  break;
-
-		case 110: /* name = value */
-		  mods = parse_mods (m->v[mi].name);
-		  mouse_actions[button_num][mods] = res_wrap (m->v[mi].value);
-		  break;
-		}
-	    }
-	}
-    }
-
-#if 0
-  printf("Configured mouse actions:\n");
-  for (bi=1; bi<=MAX_MOUSE_BUTTON; bi++)
-    for (mi=0; mi<16; mi++)
-      if (mouse_actions[bi][mi])
-	{
-	  printf("\033[32m===  %c %c %c %c %d  ===\033[0m\n",
-		 mi & M_Release ? 'R' : '-',
-		 mi & M_Alt ? 'A' : '-',
-		 mi & M_Ctrl ? 'C' : '-',
-		 mi & M_Shift ? 'S' : '-',
-		 bi);
-	  resource_dump (mouse_actions[bi][mi]);
-	}
-  memcpy (orig_actions, mouse_actions, sizeof(mouse_actions));
-#endif
-
-  for (bi=0; bi<=MAX_MOUSE_BUTTON; bi++)
-    {
-      int i, j;
-      for (i=15; i>0; i--)
-	if (!mouse_actions[bi][i])
-	  for (j=i-1; j>=(i&M_Release?8:0); j--)
-	    if (((i & j) == j) && mouse_actions[bi][j])
-	      {
-		mouse_actions[bi][i] = mouse_actions[bi][j];
-		break;
-	      }
-    }
-
-#if 0
-  printf("Active mouse actions:\n");
-  for (bi=1; bi<=MAX_MOUSE_BUTTON; bi++)
-    for (mi=0; mi<16; mi++)
-      if (mouse_actions[bi][mi])
-	{
-	  printf("\033[31m===  %c %c %c %c %d  ===\033[0m",
-		 mi & M_Release ? 'R' : '-',
-		 mi & M_Alt ? 'A' : '-',
-		 mi & M_Ctrl ? 'C' : '-',
-		 mi & M_Shift ? 'S' : '-',
-		 bi);
-	  if (!orig_actions[bi][mi])
-	    printf("\033[34m");
-	  resource_dump (mouse_actions[bi][mi]);
-	  if (!orig_actions[bi][mi])
-	    printf("\033[0m");
-	}
-#endif
-}
-
 static void
 draw_right_cross (GC xor_gc, int x, int y,
   int view_width, int view_height)
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index dce6773..d3e421d 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -19,6 +19,7 @@
 
 #include "hid.h"
 #include "../hidint.h"
+#include "hid/common/hid_resource.h"
 #include "resource.h"
 #include "lesstif.h"
 #include "mymem.h"
@@ -805,9 +806,10 @@ lesstif_get_xy (const char *message)
 void
 lesstif_get_coords (const char *msg, int *px, int *py)
 {
-  if (!have_xy)
+  if (!have_xy && msg)
     lesstif_get_xy (msg);
-  lesstif_coords_to_pcb (action_x, action_y, px, py);
+  if (have_xy)
+    lesstif_coords_to_pcb (action_x, action_y, px, py);
 }
 
 int
@@ -1518,7 +1520,7 @@ lesstif_menu (Widget parent, char *name, Arg * margs, int mn)
   if (!mr)
     mr = resource_subres (bir, "Mouse");
   if (mr)
-    lesstif_note_mouse_resource (mr);
+    load_mouse_resource (mr);
 
 
   if (do_dump_keys)




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