You can subscribe to this list here.
| 2003 | Jan | Feb (4) | Mar (5) | Apr | May (5) | Jun (30) | Jul (2) | Aug (18) | Sep (14) | Oct (7) | Nov (21) | Dec (44) | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 | Jan (63) | Feb (94) | Mar (54) | Apr (39) | May (34) | Jun (25) | Jul (10) | Aug (33) | Sep (16) | Oct (62) | Nov (12) | Dec (2) | 
| 2005 | Jan (71) | Feb (8) | Mar (50) | Apr | May (2) | Jun (12) | Jul (19) | Aug (8) | Sep (3) | Oct (2) | Nov | Dec (8) | 
| 2006 | Jan (10) | Feb (1) | Mar (301) | Apr (232) | May (26) | Jun (20) | Jul (26) | Aug (79) | Sep (92) | Oct (174) | Nov (17) | Dec (93) | 
| 2007 | Jan (27) | Feb (179) | Mar (37) | Apr (81) | May (20) | Jun (5) | Jul | Aug (40) | Sep (68) | Oct (8) | Nov (47) | Dec (34) | 
| 2008 | Jan (154) | Feb (15) | Mar (5) | Apr (21) | May (4) | Jun (1) | Jul (4) | Aug (6) | Sep (8) | Oct (9) | Nov (35) | Dec (50) | 
| 2009 | Jan (8) | Feb (10) | Mar (6) | Apr (9) | May (7) | Jun (40) | Jul (7) | Aug (5) | Sep (2) | Oct (16) | Nov (42) | Dec (5) | 
| 2010 | Jan (3) | Feb (15) | Mar (32) | Apr (18) | May (6) | Jun (9) | Jul | Aug (11) | Sep (16) | Oct | Nov (4) | Dec (35) | 
| 2011 | Jan (24) | Feb (6) | Mar (27) | Apr (119) | May (72) | Jun (20) | Jul (31) | Aug (88) | Sep (86) | Oct (14) | Nov (11) | Dec (30) | 
| 2012 | Jan (4) | Feb (3) | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 2017 | Jan | Feb | Mar (1) | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 
      
      
      From: <gi...@gp...> - 2010-08-03 23:36:08
      
     | 
| The branch, master has been updated
       via  97c150e44a768b873946b62b36bad430c9a1b8a0 (commit)
      from  ea13d896dbead7151e9d86819c51f4d34d52c8d6 (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/select.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit 97c150e44a768b873946b62b36bad430c9a1b8a0
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Don't select silk on the far side if the far side is not shown
    
    The logic for determining if a layer was "on" didn't take into
    account that the two silkscreen layers are handled differently.
    Thus, if you tried to select shown silk, you would select hidden
    silk on the other side too, unknowingly moving that around.
    
    With this patch, silk on the far side is only selected if the
    far side ("invisible" side) is shown.
:100644 100644 5240837... aa65f36... M	src/select.c
=========
 Changes
=========
commit 97c150e44a768b873946b62b36bad430c9a1b8a0
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Don't select silk on the far side if the far side is not shown
    
    The logic for determining if a layer was "on" didn't take into
    account that the two silkscreen layers are handled differently.
    Thus, if you tried to select shown silk, you would select hidden
    silk on the other side too, unknowingly moving that around.
    
    With this patch, silk on the far side is only selected if the
    far side ("invisible" side) is shown.
diff --git a/src/select.c b/src/select.c
index 5240837..aa65f36 100644
--- a/src/select.c
+++ b/src/select.c
@@ -292,8 +292,19 @@ SelectBlock (BoxTypePtr Box, bool Flag)
   /* check layers */
   LAYER_LOOP(PCB->Data, max_layer + 2);
   {
-    if (! (layer->On || !Flag))
-      continue;
+    if (layer == & PCB->Data->SILKLAYER)
+      {
+	if (! (PCB->ElementOn || !Flag))
+	  continue;
+      }
+    else if (layer == & PCB->Data->BACKSILKLAYER)
+      {
+	if (! (PCB->InvisibleObjectsOn || !Flag))
+	  continue;
+      }
+    else
+      if (! (layer->On || !Flag))
+	continue;
 
     LINE_LOOP (layer);
     {
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-06 22:38:21
      
     | 
| The branch, master has been updated
       via  ea13d896dbead7151e9d86819c51f4d34d52c8d6 (commit)
       via  0400962a289e36dacdcc99fb36b938bb69c0a1e5 (commit)
       via  183d8a3535bfaefbeb3ac5045956c7b9c9e60982 (commit)
      from  76bc5883fdf1e1f6c5b9c16bdef7208911d713d6 (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/action.c                            |  130 ++++++++++++++++-
 src/autoroute.c                         |    1 +
 src/buffer.c                            |    4 +-
 src/const.h                             |    1 +
 src/copy.c                              |   18 ++-
 src/create.c                            |   11 ++
 src/create.h                            |    1 +
 src/crosshair.c                         |   55 +++----
 src/file.c                              |   20 +++-
 src/file.h                              |    2 +-
 src/flags.c                             |    1 +
 src/global.h                            |   32 +++--
 src/gpcb-menu.res                       |    1 +
 src/hid/gtk/gui-icons-mode-buttons.data |   28 ++++
 src/hid/gtk/gui-misc.c                  |    1 +
 src/hid/gtk/gui-output-events.c         |    1 +
 src/hid/gtk/gui-top-window.c            |    1 +
 src/hid/lesstif/main.c                  |    4 +
 src/insert.c                            |   18 ++-
 src/insert.h                            |    2 +-
 src/mymem.c                             |   23 +++
 src/mymem.h                             |    2 +
 src/parse_l.l                           |    1 +
 src/parse_y.y                           |   91 ++++++++----
 src/pcb-menu.res                        |    1 +
 src/polygon.c                           |  239 +++++++++++++++++++++++++------
 src/polygon.h                           |    6 +
 src/remove.c                            |  130 +++++++++++++----
 src/report.c                            |    3 +-
 src/set.c                               |    1 +
 src/undo.c                              |  158 +++++++++++++++++++--
 src/undo.h                              |    2 +
 32 files changed, 810 insertions(+), 179 deletions(-)
=================
 Commit Messages
=================
commit ea13d896dbead7151e9d86819c51f4d34d52c8d6
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Introduce POLYGONHOLE_MODE for creating holes in polygons
    
    Having selected polygon hole mode, the first click selects which
    polygon to cut a hole in. A second click defines the start point of
    the hole contour. The tool then behaves in a similar way to the
    polygon drawing tool, with the hole ending when the start point is
    re-clicked.
    
    To avoid creating illegal polygons, the hole drawn is subtracted from
    a representation of the original polygon with the poly_Boolean_free().
    This consolidates any contours it intersects with and prevents the user
    defining contours which intersect each other. (Although we don't
    currently prevent the the user drawing self-intersecting contours).
    
    The resulting POLYAREA is re-processed into PolygonType objects,
    potentially more than one - if the hole drawn bisects the original
    polygon. To keep undo operations simple, these are added as completely
    new objects and the original polygon is deleted - along with its ID.
:100644 100644 ab2d6c5... 5f1c7a1... M	src/action.c
:100644 100644 2f97d4e... 676a6f0... M	src/const.h
:100644 100644 fa08695... b9a3dd2... M	src/crosshair.c
:100644 100644 41e0b55... 60688dd... M	src/flags.c
:100644 100644 df307be... 0db5aad... M	src/gpcb-menu.res
:100644 100644 1938ee2... be040f1... M	src/hid/gtk/gui-icons-mode-buttons.data
:100644 100644 32ca1c9... a607a69... M	src/hid/gtk/gui-misc.c
:100644 100644 c82e067... 7230aa3... M	src/hid/gtk/gui-output-events.c
:100644 100644 4d4ba7c... 4c00c13... M	src/hid/gtk/gui-top-window.c
:100644 100644 3280032... e16397e... M	src/hid/lesstif/main.c
:100644 100644 38e86e4... 0df4b7f... M	src/pcb-menu.res
:100644 100644 48d704d... 7a41f73... M	src/set.c
commit 0400962a289e36dacdcc99fb36b938bb69c0a1e5
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Expose APIs for creating POLYAREA from PolygonType objects and back
    
    The PolygonPoly() API wraps polygon.c's original_poly() function,
    whilst PolyToPolygonsOnLayer() converts the passed POLYAREA and all
    those linked to it into discrete PolygonType objects on the board.
:100644 100644 e916741... f2745ed... M	src/polygon.c
:100644 100644 a93d965... e29f67f... M	src/polygon.h
commit 183d8a3535bfaefbeb3ac5045956c7b9c9e60982
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Support holes in input polygons (incl. file-format addition)
    
    PCB file-format date is now 20100606, and files saved with this
    or greater PCB version will not load with older versions of PCB.
    If a particular board doesn't make use of the polygon hole feature,
    the PCB revision date in the file can be manually reset to 20070407.
    
    The file-format addition is as follows. Previously, a polygon would
    be specified as a series of coordinates, such as:
    
    Layer(1 "component")
    (
      Polygon("clearpoly")
      (
        [6000 6000] [81000 6000] [81000 59000] [6000 59000]
      )
    )
    
    This commit introduces the ability to specify negative contours
    which form holes in the polygon shape, e.g.:
    
    Layer(1 "component")
    (
      Polygon("")
      (
        [6000 6000] [81000 6000] [81000 59000] [6000 59000]
        Hole (
          [76000 55000] [76000 38000] [58000 38000] [58000 55000]
        )
        Hole (
          [10000 10000] [10000 28000] [27000 28000] [27000 10000]
        )
      )
    )
    
    The winding order of the contours specified in the file does not
    matter, since PCB will automatically invert the order of the points
    as necessary (as it always did with the outer contour).
    
    Hole contours should not intersect or self-intersect (although this
    isn't checked for at load time). Hole contours must not intersect
    the polygon's outer contour.
    
    Technical details:
    
    The PolygonType structure has a number of new fields, the critical
    ones being an array of indices defining the start of hole contours.
    
    (PolygonType *)->HoleIndex[n]
    
    The number of hole contours is stored in (PolygonType *)->HoleIndexN,
    and the maximum allocated memory for indices in (...)->HoleIndexMax.
    The first hole contour starts at the point given by
    (...)->Points[(...)->HoleIndex[0]], and continues until the start of
    the next contour, or the last point defined.
    
    By storing all polygon points (including holes) in the existing array
    (...)->Points[], existing code which operates on the polygon as a
    whole, e.g. translation and rotation, can operate without change.
    
    For other operations, determining wrap-around to operate within the
    same contour requires more computation. Some helper functions have
    been introduced in polygon.c to aid this, next_contour_point() and
    prev_contour_point(). Where applicable, these have been used to
    simplify existing code which used ad-hoc wrap-around code.
    
    polygon_point_idx() computes the array index of a point in a polygon
    from its PointTypePtr address. This is used to replace a search idiom
    used in a number of places. polygon_point_contour() returns the
    number of the contour a given point index belongs in, 0 for the outer
    contour, 1 for the first hole etc..
    
    Undo:
    
    Undo with holes has become a little more complex. The undo for a point
    removal must now record which contour the point came from. This is
    determined by the index of the removed point, and a new boolean flag
    "last_in_contour", indicating if the point was at the end of its contour.
    This flag is passed to InsertPointIntoObject(), which uses it to
    disambiguate inserting a point at an index on the boundary of two
    contours.
    
    Undo operations for removing hole contours "cheat" by saving a copy of
    the whole polygon into the undo buffer rather than attempting to
    describe the operation as a delta change to an existing polygon. When
    undoing, the object IDs are swapped to keep them consistent.
:100644 100644 6546be1... ab2d6c5... M	src/action.c
:100644 100644 b6bf91d... 7fb7443... M	src/autoroute.c
:100644 100644 e04ae2a... 7b8bce8... M	src/buffer.c
:100644 100644 ffa0ed3... 58ce9df... M	src/copy.c
:100644 100644 0c5abe1... b3d5bee... M	src/create.c
:100644 100644 b9f418c... 8086b1e... M	src/create.h
:100644 100644 13ddc71... fa08695... M	src/crosshair.c
:100644 100644 3129601... a61d53f... M	src/file.c
:100644 100644 5791dda... 4b9ecf2... M	src/file.h
:100644 100644 62be07f... bb78abc... M	src/global.h
:100644 100644 b4bcfe7... 5e62463... M	src/insert.c
:100644 100644 87b6cbb... 350a0de... M	src/insert.h
:100644 100644 46714bb... bed0f9b... M	src/mymem.c
:100644 100644 b9d4de1... 81dff7a... M	src/mymem.h
:100644 100644 0f3b72e... 8aa754c... M	src/parse_l.l
:100644 100644 1d64fe8... a5b2d23... M	src/parse_y.y
:100644 100644 97164ab... e916741... M	src/polygon.c
:100644 100644 1eb5757... a93d965... M	src/polygon.h
:100644 100644 a537bc0... 98b9ade... M	src/remove.c
:100644 100644 6a1c47b... dc01153... M	src/report.c
:100644 100644 50c6de5... 68ea8ff... M	src/undo.c
:100644 100644 c7a0288... 0a4601f... M	src/undo.h
=========
 Changes
=========
commit ea13d896dbead7151e9d86819c51f4d34d52c8d6
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Introduce POLYGONHOLE_MODE for creating holes in polygons
    
    Having selected polygon hole mode, the first click selects which
    polygon to cut a hole in. A second click defines the start point of
    the hole contour. The tool then behaves in a similar way to the
    polygon drawing tool, with the hole ending when the start point is
    re-clicked.
    
    To avoid creating illegal polygons, the hole drawn is subtracted from
    a representation of the original polygon with the poly_Boolean_free().
    This consolidates any contours it intersects with and prevents the user
    defining contours which intersect each other. (Although we don't
    currently prevent the the user drawing self-intersecting contours).
    
    The resulting POLYAREA is re-processed into PolygonType objects,
    potentially more than one - if the hole drawn bisects the original
    polygon. To keep undo operations simple, these are added as completely
    new objects and the original polygon is deleted - along with its ID.
diff --git a/src/action.c b/src/action.c
index ab2d6c5..5f1c7a1 100644
--- a/src/action.c
+++ b/src/action.c
@@ -145,6 +145,7 @@ typedef enum
   F_PinOrPadName,
   F_Pinout,
   F_Polygon,
+  F_PolygonHole,
   F_PreviousPoint,
   F_RatsNest,
   F_Rectangle,
@@ -380,6 +381,7 @@ static FunctionType Functions[] = {
   {"PinOrPadName", F_PinOrPadName},
   {"Pinout", F_Pinout},
   {"Polygon", F_Polygon},
+  {"PolygonHole", F_PolygonHole},
   {"PreviousPoint", F_PreviousPoint},
   {"RatsNest", F_RatsNest},
   {"Rectangle", F_Rectangle},
@@ -843,6 +845,7 @@ AdjustAttachedObjects (void)
 
       /* polygon creation mode */
     case POLYGON_MODE:
+    case POLYGONHOLE_MODE:
       AdjustAttachedLine ();
       break;
       /* line creation mode */
@@ -1448,6 +1451,101 @@ NotifyMode (void)
 	break;
       }
 
+    case POLYGONHOLE_MODE:
+      {
+	switch (Crosshair.AttachedObject.State)
+	  {
+	    /* first notify, lookup object */
+	  case STATE_FIRST:
+	    Crosshair.AttachedObject.Type =
+	      SearchScreen (Note.X, Note.Y, POLYGON_TYPE,
+			    &Crosshair.AttachedObject.Ptr1,
+			    &Crosshair.AttachedObject.Ptr2,
+			    &Crosshair.AttachedObject.Ptr3);
+
+	    if (Crosshair.AttachedObject.Type != NO_TYPE)
+	      {
+		if (TEST_FLAG (LOCKFLAG, (PolygonTypePtr)
+			       Crosshair.AttachedObject.Ptr2))
+		  {
+		    Message (_("Sorry, the object is locked\n"));
+		    Crosshair.AttachedObject.Type = NO_TYPE;
+		    break;
+		  }
+		else
+		  Crosshair.AttachedObject.State = STATE_SECOND;
+	      }
+	    break;
+
+            /* second notify, insert new point into object */
+          case STATE_SECOND:
+            {
+	      PointTypePtr points = Crosshair.AttachedPolygon.Points;
+	      Cardinal n = Crosshair.AttachedPolygon.PointN;
+	      POLYAREA *original, *new_hole, *result;
+	      FlagType Flags;
+
+	      /* do update of position; use the 'LINE_MODE' mechanism */
+	      NotifyLine ();
+
+	      /* check if this is the last point of a polygon */
+	      if (n >= 3 &&
+		  points->X == Crosshair.AttachedLine.Point2.X &&
+		  points->Y == Crosshair.AttachedLine.Point2.Y)
+		{
+		  /* Create POLYAREAs from the original polygon
+		   * and the new hole polygon */
+		  original = PolygonToPoly (Crosshair.AttachedObject.Ptr2);
+		  new_hole = PolygonToPoly (&Crosshair.AttachedPolygon);
+
+		  /* Subtract the hole from the original polygon shape */
+		  poly_Boolean_free (original, new_hole, &result, PBO_SUB);
+
+		  /* Convert the resulting polygon(s) into a new set of nodes
+		   * and place them on the page. Delete the original polygon.
+		   */
+		  SaveUndoSerialNumber ();
+		  Flags = ((PolygonType *)Crosshair.AttachedObject.Ptr2)->Flags;
+		  PolyToPolygonsOnLayer (PCB->Data, Crosshair.AttachedObject.Ptr1,
+					 result, Flags);
+		  RemoveObject (POLYGON_TYPE,
+				Crosshair.AttachedObject.Ptr1,
+				Crosshair.AttachedObject.Ptr2,
+				Crosshair.AttachedObject.Ptr3);
+		  RestoreUndoSerialNumber ();
+		  IncrementUndoSerialNumber ();
+		  Draw ();
+
+		/* reset state of attached line */
+		memset (&Crosshair.AttachedPolygon, 0, sizeof (PolygonType));
+		Crosshair.AttachedLine.State = STATE_FIRST;
+		addedLines = 0;
+
+		  break;
+		}
+
+	      /* create new point if it's the first one or if it's
+	       * different to the last one
+	       */
+	      if (!n ||
+		  points[n - 1].X != Crosshair.AttachedLine.Point2.X ||
+		  points[n - 1].Y != Crosshair.AttachedLine.Point2.Y)
+		{
+		  CreateNewPointInPolygon (&Crosshair.AttachedPolygon,
+					   Crosshair.AttachedLine.Point2.X,
+					   Crosshair.AttachedLine.Point2.Y);
+
+		  /* copy the coordinates */
+		  Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X;
+		  Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y;
+		}
+	      break;
+	    }
+	  }
+
+	break;
+      }
+
     case PASTEBUFFER_MODE:
       {
 	TextType estr[MAX_ELEMENTNAMES];
@@ -3022,6 +3120,16 @@ ActionMode (int argc, char **argv, int x, int y)
 		  }
 		break;
 
+	      case POLYGONHOLE_MODE:
+		if (Crosshair.AttachedLine.State == STATE_FIRST)
+		  SetMode (ARROW_MODE);
+		else
+		  {
+		    SetMode (NO_MODE);
+		    SetMode (POLYGONHOLE_MODE);
+		  }
+		break;
+
 	      case ARC_MODE:
 		if (Crosshair.AttachedBox.State == STATE_FIRST)
 		  SetMode (ARROW_MODE);
@@ -3050,6 +3158,9 @@ ActionMode (int argc, char **argv, int x, int y)
 	case F_Polygon:
 	  SetMode (POLYGON_MODE);
 	  break;
+	case F_PolygonHole:
+	  SetMode (POLYGONHOLE_MODE);
+	  break;
 #ifndef HAVE_LIBSTROKE
 	case F_Release:
 	  ReleaseMode ();
@@ -6098,7 +6209,8 @@ ActionUndo (int argc, char **argv, int x, int y)
   if (!function || !*function)
     {
       /* don't allow undo in the middle of an operation */
-      if (Crosshair.AttachedObject.State != STATE_FIRST)
+      if (Settings.Mode != POLYGONHOLE_MODE &&
+	  Crosshair.AttachedObject.State != STATE_FIRST)
 	return 1;
       if (Crosshair.AttachedBox.State != STATE_FIRST
 	  && Settings.Mode != ARC_MODE)
@@ -6106,7 +6218,9 @@ ActionUndo (int argc, char **argv, int x, int y)
       /* undo the last operation */
 
       HideCrosshair (true);
-      if (Settings.Mode == POLYGON_MODE && Crosshair.AttachedPolygon.PointN)
+      if ((Settings.Mode == POLYGON_MODE ||
+           Settings.Mode == POLYGONHOLE_MODE) &&
+          Crosshair.AttachedPolygon.PointN)
 	{
 	  GoToPreviousPoint ();
 	  RestoreCrosshair (true);
@@ -6268,7 +6382,8 @@ three "undone" lines.
 static int
 ActionRedo (int argc, char **argv, int x, int y)
 {
-  if ((Settings.Mode == POLYGON_MODE &&
+  if (((Settings.Mode == POLYGON_MODE ||
+        Settings.Mode == POLYGONHOLE_MODE) &&
        Crosshair.AttachedPolygon.PointN) ||
       Crosshair.AttachedLine.State == STATE_SECOND)
     return 1;
diff --git a/src/const.h b/src/const.h
index 2f97d4e..676a6f0 100644
--- a/src/const.h
+++ b/src/const.h
@@ -92,6 +92,7 @@
 #define ARROW_MODE		110	/* selection with arrow mode */
 #define PAN_MODE                0	/* same as no mode */
 #define LOCK_MODE               111	/* lock/unlock objects */
+#define	POLYGONHOLE_MODE	112	/* cut holes in filled polygons */
 
 /* ---------------------------------------------------------------------------
  * object flags
diff --git a/src/crosshair.c b/src/crosshair.c
index fa08695..b9a3dd2 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -588,8 +588,9 @@ DrawAttached (bool BlockToo)
 	}
       break;
 
-      /* the attached line is used by both LINEMODE and POLYGON_MODE */
+      /* the attached line is used by both LINEMODE, POLYGON_MODE and POLYGONHOLE_MODE*/
     case POLYGON_MODE:
+    case POLYGONHOLE_MODE:
       /* draw only if starting point is set */
       if (Crosshair.AttachedLine.State != STATE_FIRST)
 	gui->draw_line (Crosshair.GC,
@@ -598,7 +599,7 @@ DrawAttached (bool BlockToo)
 			Crosshair.AttachedLine.Point2.X,
 			Crosshair.AttachedLine.Point2.Y);
 
-      /* draw attached polygon only if in POLYGON_MODE */
+      /* draw attached polygon only if in POLYGON_MODE or POLYGONHOLE_MODE */
       if (Crosshair.AttachedPolygon.PointN > 1)
 	{
 	  XORPolygon (&Crosshair.AttachedPolygon, 0, 0);
diff --git a/src/flags.c b/src/flags.c
index 41e0b55..60688dd 100644
--- a/src/flags.c
+++ b/src/flags.c
@@ -192,6 +192,7 @@ HID_Flag flags_flag_list[] = {
   {"movemode", FlagMode, MOVE_MODE},
   {"pastebuffermode", FlagMode, PASTEBUFFER_MODE},
   {"polygonmode", FlagMode, POLYGON_MODE},
+  {"polygonholemode", FlagMode, POLYGONHOLE_MODE},
   {"rectanglemode", FlagMode, RECTANGLE_MODE},
   {"removemode", FlagMode, REMOVE_MODE},
   {"rotatemode", FlagMode, ROTATE_MODE},
diff --git a/src/gpcb-menu.res b/src/gpcb-menu.res
index df307be..0db5aad 100644
--- a/src/gpcb-menu.res
+++ b/src/gpcb-menu.res
@@ -508,6 +508,7 @@ PopupMenus =
        {"Text" checked=textmode,1 Mode(Text) a={"F4" "<Key>F4"}}
        {"Rectangle" checked=rectanglemode,1 Mode(Rectangle) a={"F5" "<Key>F5"}}
        {"Polygon" checked=polygonmode,1 Mode(Polygon) a={"F6" "<Key>F6"}}
+       {"Polygon Hole" checked=polygonholemode,1 Mode(PolygonHole)}
        {"Buffer" checked=pastebuffermode,1 Mode(PasteBuffer) a={"F7" "<Key>F7"}}
        {"Remove" checked=removemode,1 Mode(Remove) a={"F8" "<Key>F8"}}
        {"Rotate" checked=rotatemode,1 Mode(Rotate) a={"F9" "<Key>F9"}}
diff --git a/src/hid/gtk/gui-icons-mode-buttons.data b/src/hid/gtk/gui-icons-mode-buttons.data
index 1938ee2..be040f1 100644
--- a/src/hid/gtk/gui-icons-mode-buttons.data
+++ b/src/hid/gtk/gui-icons-mode-buttons.data
@@ -283,6 +283,34 @@ static char *poly[] = {
 "ooooooooooooooooooooo"
 };
 
+/* XPM */
+static char * polyhole[] = {
+"21 21 3 1",
+" 	c None",
+".	c #6EA5D7",
+"+	c #000000",
+"        ..           ",
+"       ...           ",
+"      .....          ",
+"     .......         ",
+"    .........        ",
+"  ....+++++...       ",
+"  ....+   +....      ",
+"  ...+    +.....     ",
+"  ...++++++......    ",
+"  ................   ",
+"  .................  ",
+"                     ",
+"  +  +  ++  +   +++  ",
+"  +  + +  + +   +    ",
+"  +  + +  + +   +    ",
+"  ++++ +  + +   +++  ",
+"  +  + +  + +   +    ",
+"  +  + +  + +   +    ",
+"  +  + +  + +   +    ",
+"  +  +  ++  +++ +++  ",
+"                     "
+};
 
 /* XPM */
 static char *rect[] = {
diff --git a/src/hid/gtk/gui-misc.c b/src/hid/gtk/gui-misc.c
index 32ca1c9..a607a69 100644
--- a/src/hid/gtk/gui-misc.c
+++ b/src/hid/gtk/gui-misc.c
@@ -220,6 +220,7 @@ ghid_mode_cursor (int Mode)
       break;
 
     case POLYGON_MODE:
+    case POLYGONHOLE_MODE:
       gport_set_cursor (GDK_SB_UP_ARROW);
       break;
 
diff --git a/src/hid/gtk/gui-output-events.c b/src/hid/gtk/gui-output-events.c
index c82e067..7230aa3 100644
--- a/src/hid/gtk/gui-output-events.c
+++ b/src/hid/gtk/gui-output-events.c
@@ -277,6 +277,7 @@ have_crosshair_attachments (void)
       result = TRUE;
       break;
     case POLYGON_MODE:
+    case POLYGONHOLE_MODE:
       if (Crosshair.AttachedLine.State != STATE_FIRST)
 	result = TRUE;
       break;
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 4d4ba7c..4c00c13 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -1983,6 +1983,7 @@ static ModeButton mode_buttons[] = {
   {NULL, NULL, NULL, "text", TEXT_MODE, text},
   {NULL, NULL, NULL, "rectangle", RECTANGLE_MODE, rect},
   {NULL, NULL, NULL, "polygon", POLYGON_MODE, poly},
+  {NULL, NULL, NULL, "polygonhole", POLYGONHOLE_MODE, polyhole},
   {NULL, NULL, NULL, "buffer", PASTEBUFFER_MODE, buf},
   {NULL, NULL, NULL, "remove", REMOVE_MODE, del},
   {NULL, NULL, NULL, "rotate", ROTATE_MODE, rot},
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 3280032..e16397e 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -2631,6 +2631,10 @@ idle_proc (XtPointer dummy)
 	    s = "Polygon";
 	    cursor = XC_sb_up_arrow;
 	    break;
+	  case POLYGONHOLE_MODE:
+	    s = "Polygon Hole";
+	    cursor = XC_sb_up_arrow;
+	    break;
 	  case PASTEBUFFER_MODE:
 	    s = "Paste";
 	    cursor = XC_hand1;
diff --git a/src/pcb-menu.res b/src/pcb-menu.res
index 38e86e4..0df4b7f 100644
--- a/src/pcb-menu.res
+++ b/src/pcb-menu.res
@@ -174,6 +174,7 @@ MainMenu =
    {"Text" checked=textmode,1 Mode(Text) a={"F4" "<Key>F4"}}
    {"Rectangle" checked=rectanglemode,1 Mode(Rectangle) a={"F5" "<Key>F5"}}
    {"Polygon" checked=polygonmode,1 Mode(Polygon) a={"F6" "<Key>F6"}}
+   {"Polygon Hole" checked=polygonholemode,1 Mode(PolygonHole)}
    {"Buffer" checked=pastebuffermode,1 Mode(PasteBuffer) a={"F7" "<Key>F7"}}
    {"Remove" checked=removemode,1 Mode(Remove) a={"F8" "<Key>F8"}}
    {"Rotate" checked=rotatemode,1 Mode(Rotate) a={"F9" "<Key>F9"}}
diff --git a/src/set.c b/src/set.c
index 48d704d..7a41f73 100644
--- a/src/set.c
+++ b/src/set.c
@@ -253,6 +253,7 @@ SetMode (int Mode)
     {
       if (Mode == ARC_MODE || Mode == RECTANGLE_MODE ||
 	  Mode == VIA_MODE || Mode == POLYGON_MODE ||
+	  Mode == POLYGONHOLE_MODE ||
 	  Mode == TEXT_MODE || Mode == INSERTPOINT_MODE ||
 	  Mode == THERMAL_MODE)
 	{
commit 0400962a289e36dacdcc99fb36b938bb69c0a1e5
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Expose APIs for creating POLYAREA from PolygonType objects and back
    
    The PolygonPoly() API wraps polygon.c's original_poly() function,
    whilst PolyToPolygonsOnLayer() converts the passed POLYAREA and all
    those linked to it into discrete PolygonType objects on the board.
diff --git a/src/polygon.c b/src/polygon.c
index e916741..f2745ed 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -319,6 +319,12 @@ original_poly (PolygonType * p)
 }
 
 POLYAREA *
+PolygonToPoly (PolygonType *p)
+{
+  return original_poly (p);
+}
+
+POLYAREA *
 RectPoly (LocationType x1, LocationType x2, LocationType y1, LocationType y2)
 {
   PLINE *contour = NULL;
@@ -1830,3 +1836,59 @@ debug_polygon (PolygonType *p)
 	break;
     }
 }
+
+/* Convert a POLYAREA (and all linked POLYAREA) to
+ * raw PCB polygons on the given layer.
+ */
+void
+PolyToPolygonsOnLayer (DataType *Destination, LayerType *Layer,
+                       POLYAREA *Input, FlagType Flags)
+{
+  PolygonType *Polygon;
+  POLYAREA *pa;
+  PLINE *pline;
+  VNODE *node;
+  bool outer;
+
+  if (Input == NULL)
+    return;
+
+  pa = Input;
+  do
+    {
+      Polygon = CreateNewPolygon (Layer, Flags);
+
+      pline = pa->contours;
+      outer = true;
+
+      do
+        {
+          if (!outer)
+            CreateNewHoleInPolygon (Polygon);
+          outer = false;
+
+          node = &pline->head;
+          do
+            {
+              CreateNewPointInPolygon (Polygon, node->point[0],
+                                                node->point[1]);
+            }
+          while ((node = node->next) != &pline->head);
+
+        }
+      while ((pline = pline->next) != NULL);
+
+      InitClip (Destination, Layer, Polygon);
+      SetPolygonBoundingBox (Polygon);
+      if (!Layer->polygon_tree)
+        Layer->polygon_tree = r_create_tree (NULL, 0, 0);
+      r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
+
+      DrawPolygon (Layer, Polygon, 0);
+      /* add to undo list */
+      AddObjectToCreateUndoList (POLYGON_TYPE, Layer, Polygon, Polygon);
+    }
+  while ((pa = pa->f) != Input);
+
+  SetChangedFlag (true);
+}
diff --git a/src/polygon.h b/src/polygon.h
index a93d965..e29f67f 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -50,6 +50,7 @@ int PlowsPolygon (DataType *, int, void *, void *,
 		  int (*callback) (DataTypePtr, LayerTypePtr, PolygonTypePtr, int, void *, void *));
 void ComputeNoHoles (PolygonType *poly);
 POLYAREA * ContourToPoly (PLINE *);
+POLYAREA * PolygonToPoly (PolygonType *);
 POLYAREA * RectPoly (LocationType x1, LocationType x2, LocationType y1, LocationType y2);
 POLYAREA * CirclePoly(LocationType x, LocationType y, BDimension radius);
 POLYAREA * OctagonPoly(LocationType x, LocationType y, BDimension radius);
@@ -70,4 +71,5 @@ bool isects (POLYAREA *, PolygonTypePtr, bool);
 bool MorphPolygon (LayerTypePtr, PolygonTypePtr);
 void NoHolesPolygonDicer (PolygonType *p, const BoxType *clip,
                           void (*emit) (PLINE *, void *), void *user_data);
+void PolyToPolygonsOnLayer (DataType *, LayerType *, POLYAREA *, FlagType);
 #endif
commit 183d8a3535bfaefbeb3ac5045956c7b9c9e60982
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Support holes in input polygons (incl. file-format addition)
    
    PCB file-format date is now 20100606, and files saved with this
    or greater PCB version will not load with older versions of PCB.
    If a particular board doesn't make use of the polygon hole feature,
    the PCB revision date in the file can be manually reset to 20070407.
    
    The file-format addition is as follows. Previously, a polygon would
    be specified as a series of coordinates, such as:
    
    Layer(1 "component")
    (
      Polygon("clearpoly")
      (
        [6000 6000] [81000 6000] [81000 59000] [6000 59000]
      )
    )
    
    This commit introduces the ability to specify negative contours
    which form holes in the polygon shape, e.g.:
    
    Layer(1 "component")
    (
      Polygon("")
      (
        [6000 6000] [81000 6000] [81000 59000] [6000 59000]
        Hole (
          [76000 55000] [76000 38000] [58000 38000] [58000 55000]
        )
        Hole (
          [10000 10000] [10000 28000] [27000 28000] [27000 10000]
        )
      )
    )
    
    The winding order of the contours specified in the file does not
    matter, since PCB will automatically invert the order of the points
    as necessary (as it always did with the outer contour).
    
    Hole contours should not intersect or self-intersect (although this
    isn't checked for at load time). Hole contours must not intersect
    the polygon's outer contour.
    
    Technical details:
    
    The PolygonType structure has a number of new fields, the critical
    ones being an array of indices defining the start of hole contours.
    
    (PolygonType *)->HoleIndex[n]
    
    The number of hole contours is stored in (PolygonType *)->HoleIndexN,
    and the maximum allocated memory for indices in (...)->HoleIndexMax.
    The first hole contour starts at the point given by
    (...)->Points[(...)->HoleIndex[0]], and continues until the start of
    the next contour, or the last point defined.
    
    By storing all polygon points (including holes) in the existing array
    (...)->Points[], existing code which operates on the polygon as a
    whole, e.g. translation and rotation, can operate without change.
    
    For other operations, determining wrap-around to operate within the
    same contour requires more computation. Some helper functions have
    been introduced in polygon.c to aid this, next_contour_point() and
    prev_contour_point(). Where applicable, these have been used to
    simplify existing code which used ad-hoc wrap-around code.
    
    polygon_point_idx() computes the array index of a point in a polygon
    from its PointTypePtr address. This is used to replace a search idiom
    used in a number of places. polygon_point_contour() returns the
    number of the contour a given point index belongs in, 0 for the outer
    contour, 1 for the first hole etc..
    
    Undo:
    
    Undo with holes has become a little more complex. The undo for a point
    removal must now record which contour the point came from. This is
    determined by the index of the removed point, and a new boolean flag
    "last_in_contour", indicating if the point was at the end of its contour.
    This flag is passed to InsertPointIntoObject(), which uses it to
    disambiguate inserting a point at an index on the boundary of two
    contours.
    
    Undo operations for removing hole contours "cheat" by saving a copy of
    the whole polygon into the undo buffer rather than attempting to
    describe the operation as a delta change to an existing polygon. When
    undoing, the object IDs are swapped to keep them consistent.
diff --git a/src/action.c b/src/action.c
index 6546be1..ab2d6c5 100644
--- a/src/action.c
+++ b/src/action.c
@@ -1641,9 +1641,8 @@ NotifyMode (void)
 			GetLowestDistancePolygonPoint (fake.poly, Note.X,
 						       Note.Y);
 		      fake.line.Point1 = fake.poly->Points[polyIndex];
-		      fake.line.Point2 = (polyIndex) ?
-			fake.poly->Points[polyIndex - 1]
-			: fake.poly->Points[fake.poly->PointN - 1];
+		      fake.line.Point2 = fake.poly->Points[
+			  prev_contour_point (fake.poly, polyIndex)];
 		      Crosshair.AttachedObject.Ptr2 = &fake.line;
 
 		    }
@@ -1659,13 +1658,13 @@ NotifyMode (void)
 	    InsertPointIntoObject (POLYGON_TYPE,
 				   Crosshair.AttachedObject.Ptr1, fake.poly,
 				   &polyIndex,
-				   InsertedPoint.X, InsertedPoint.Y, false);
+				   InsertedPoint.X, InsertedPoint.Y, false, false);
 	  else
 	    InsertPointIntoObject (Crosshair.AttachedObject.Type,
 				   Crosshair.AttachedObject.Ptr1,
 				   Crosshair.AttachedObject.Ptr2,
 				   &polyIndex,
-				   InsertedPoint.X, InsertedPoint.Y, false);
+				   InsertedPoint.X, InsertedPoint.Y, false, false);
 	  SetChangedFlag (true);
 
 	  /* reset identifiers */
diff --git a/src/autoroute.c b/src/autoroute.c
index b6bf91d..7fb7443 100644
--- a/src/autoroute.c
+++ b/src/autoroute.c
@@ -768,6 +768,7 @@ AddPolygon (PointerListType layergroupboxes[], Cardinal layer,
 			     polygon->BoundingBox.Y2,
 			     layergroup, polygon, style);
   if (polygon->PointN == 4 &&
+      polygon->HoleIndexN == 0 &&
       (polygon->Points[0].X == polygon->Points[1].X ||
        polygon->Points[0].Y == polygon->Points[1].Y) &&
       (polygon->Points[1].X == polygon->Points[2].X ||
diff --git a/src/buffer.c b/src/buffer.c
index e04ae2a..7b8bce8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -194,7 +194,7 @@ AddPolygonToBuffer (LayerTypePtr Layer, PolygonTypePtr Polygon)
   LayerTypePtr layer = &Dest->Layer[GetLayerNumber (Source, Layer)];
   PolygonTypePtr polygon;
 
-  polygon = GetPolygonMemory (layer);
+  polygon = CreateNewPolygon (layer, Polygon->Flags);
   CopyPolygonLowLevel (polygon, Polygon);
   CLEAR_FLAG (FOUNDFLAG | ExtraFlag, polygon);
   return (polygon);
@@ -1001,7 +1001,7 @@ polygon_is_rectangle (PolygonTypePtr poly)
 {
   int i, best;
   PointType temp[4];
-  if (poly->PointN != 4)
+  if (poly->PointN != 4 || poly->HoleIndexN != 0)
     return 0;
   best = 0;
   for (i=1; i<4; i++)
diff --git a/src/copy.c b/src/copy.c
index ffa0ed3..58ce9df 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -95,12 +95,18 @@ static ObjectFunctionType CopyFunctions = {
 PolygonTypePtr
 CopyPolygonLowLevel (PolygonTypePtr Dest, PolygonTypePtr Src)
 {
-  /* copy all data */
-  POLYGONPOINT_LOOP (Src);
-  {
-    CreateNewPointInPolygon (Dest, point->X, point->Y);
-  }
-  END_LOOP;
+  Cardinal hole = 0;
+  Cardinal n;
+
+  for (n = 0; n < Src->PointN; n++)
+    {
+      if (hole < Src->HoleIndexN && n == Src->HoleIndex[hole])
+        {
+          CreateNewHoleInPolygon (Dest);
+          hole++;
+        }
+      CreateNewPointInPolygon (Dest, Src->Points[n].X, Src->Points[n].Y);
+    }
   SetPolygonBoundingBox (Dest);
   Dest->Flags = Src->Flags;
   CLEAR_FLAG (FOUNDFLAG, Dest);
diff --git a/src/create.c b/src/create.c
index 0c5abe1..b3d5bee 100644
--- a/src/create.c
+++ b/src/create.c
@@ -635,6 +635,17 @@ CreateNewPointInPolygon (PolygonTypePtr Polygon, LocationType X,
 }
 
 /* ---------------------------------------------------------------------------
+ * creates a new hole in a polygon
+ */
+PolygonType *
+CreateNewHoleInPolygon (PolygonType *Polygon)
+{
+  Cardinal *holeindex = GetHoleIndexMemoryInPolygon (Polygon);
+  *holeindex = Polygon->PointN;
+  return Polygon;
+}
+
+/* ---------------------------------------------------------------------------
  * creates an new element
  * memory is allocated if needed
  */
diff --git a/src/create.h b/src/create.h
index b9f418c..8086b1e 100644
--- a/src/create.h
+++ b/src/create.h
@@ -62,6 +62,7 @@ TextTypePtr CreateNewText (LayerTypePtr, FontTypePtr, LocationType,
 PolygonTypePtr CreateNewPolygon (LayerTypePtr, FlagType);
 PointTypePtr CreateNewPointInPolygon (PolygonTypePtr,
 				      LocationType, LocationType);
+PolygonType *CreateNewHoleInPolygon (PolygonType *polygon);
 ElementTypePtr CreateNewElement (DataTypePtr, ElementTypePtr,
 				 FontTypePtr, FlagType, char *, char *,
 				 char *, LocationType, LocationType, BYTE,
diff --git a/src/crosshair.c b/src/crosshair.c
index 13ddc71..fa08695 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -48,6 +48,7 @@
 #include "misc.h"
 #include "mymem.h"
 #include "search.h"
+#include "polygon.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -92,16 +93,16 @@ static void DrawAttached (bool);
 static void
 XORPolygon (PolygonTypePtr polygon, LocationType dx, LocationType dy)
 {
-  int i;
-  for (i = 0; i < polygon->PointN - 1; i++)
-    gui->draw_line (Crosshair.GC,
-		    polygon->Points[i].X + dx, polygon->Points[i].Y + dy,
-		    polygon->Points[i + 1].X + dx,
-		    polygon->Points[i + 1].Y + dy);
-  if (i > 1)
-    gui->draw_line (Crosshair.GC,
-		    polygon->Points[i].X + dx, polygon->Points[i].Y + dy,
-		    polygon->Points[0].X + dx, polygon->Points[0].Y + dy);
+  Cardinal i;
+  for (i = 0; i < polygon->PointN; i++)
+    {
+      Cardinal next = next_contour_point (polygon, i);
+      gui->draw_line (Crosshair.GC,
+                      polygon->Points[i].X + dx,
+                      polygon->Points[i].Y + dy,
+                      polygon->Points[next].X + dx,
+                      polygon->Points[next].Y + dy);
+    }
 }
 
 /*-----------------------------------------------------------
@@ -473,35 +474,24 @@ XORDrawMoveOrCopyObject (void)
     case POLYGONPOINT_TYPE:
       {
 	PolygonTypePtr polygon;
-	PointTypePtr point, previous, following;
+	PointTypePtr point;
+	Cardinal point_idx, prev, next;
 
 	polygon = (PolygonTypePtr) Crosshair.AttachedObject.Ptr2;
 	point = (PointTypePtr) Crosshair.AttachedObject.Ptr3;
+	point_idx = polygon_point_idx (polygon, point);
 
 	/* get previous and following point */
-	if (point == polygon->Points)
-	  {
-	    previous = &polygon->Points[polygon->PointN - 1];
-	    following = point + 1;
-	  }
-	else if (point == &polygon->Points[polygon->PointN - 1])
-	  {
-	    previous = point - 1;
-	    following = &polygon->Points[0];
-	  }
-	else
-	  {
-	    previous = point - 1;
-	    following = point + 1;
-	  }
+	prev = prev_contour_point (polygon, point_idx);
+	next = next_contour_point (polygon, point_idx);
 
 	/* draw the two segments */
 	gui->draw_line (Crosshair.GC,
-			previous->X,
-			previous->Y, point->X + dx, point->Y + dy);
+			polygon->Points[prev].X, polygon->Points[prev].Y,
+			point->X + dx, point->Y + dy);
 	gui->draw_line (Crosshair.GC,
-			point->X + dx,
-			point->Y + dy, following->X, following->Y);
+			point->X + dx, point->Y + dy,
+			polygon->Points[next].X, polygon->Points[next].Y);
 	break;
       }
 
diff --git a/src/file.c b/src/file.c
index 3129601..a61d53f 100644
--- a/src/file.c
+++ b/src/file.c
@@ -825,14 +825,32 @@ WriteLayerData (FILE * FP, Cardinal Number, LayerTypePtr layer)
 	{
 	  PolygonTypePtr polygon = &layer->Polygon[n];
 	  int p, i = 0;
+	  Cardinal hole = 0;
 	  fprintf (FP, "\tPolygon(%s)\n\t(", F2S (polygon, POLYGON_TYPE));
 	  for (p = 0; p < polygon->PointN; p++)
 	    {
 	      PointTypePtr point = &polygon->Points[p];
+
+	      if (hole < polygon->HoleIndexN &&
+		  p == polygon->HoleIndex[hole])
+		{
+		  if (hole > 0)
+		    fputs ("\n\t\t)", FP);
+		  fputs ("\n\t\tHole (", FP);
+		  hole++;
+		  i = 0;
+		}
+
 	      if (i++ % 5 == 0)
-		fputs ("\n\t\t", FP);
+		{
+		  fputs ("\n\t\t", FP);
+		  if (hole)
+		    fputs ("\t", FP);
+		}
 	      fprintf (FP, "[%i %i] ", (int) point->X, (int) point->Y);
 	    }
+	  if (hole > 0)
+	    fputs ("\n\t\t)", FP);
 	  fputs ("\n\t)\n", FP);
 	}
       fputs (")\n", FP);
diff --git a/src/file.h b/src/file.h
index 5791dda..4b9ecf2 100644
--- a/src/file.h
+++ b/src/file.h
@@ -56,7 +56,7 @@ void sort_netlist (void);
  * guidance to the user as to what the minimum version of pcb required
  * is.
  */
-#define PCB_FILE_VERSION 20070407
+#define PCB_FILE_VERSION 20100606
 
 
 #ifndef HAS_ATEXIT
diff --git a/src/global.h b/src/global.h
index 62be07f..bb78abc 100644
--- a/src/global.h
+++ b/src/global.h
@@ -260,6 +260,10 @@ struct polygon_st			/* holds information about a polygon */
   PLINE *NoHoles;		/* the polygon broken into hole-less regions */
   int NoHolesValid;		/* Is the NoHoles polygon up to date? */
   PointTypePtr Points;		/* data */
+  Cardinal *HoleIndex;		/* Index of hole data within the Points array */
+  Cardinal HoleIndexN;		/* number of holes in polygon */
+  Cardinal HoleIndexMax;	/* max number from malloc() */
+
 };
 
 typedef struct			/* holds information about arcs */
@@ -779,19 +783,21 @@ struct drc_violation_st
 #define	UNDO_REMOVE			0x0004	/* removing objects */
 #define	UNDO_REMOVE_POINT		0x0008	/* removing polygon/... points */
 #define	UNDO_INSERT_POINT		0x0010	/* inserting polygon/... points */
-#define	UNDO_ROTATE			0x0020	/* rotations */
-#define	UNDO_CREATE			0x0040	/* creation of objects */
-#define	UNDO_MOVETOLAYER		0x0080	/* moving objects to */
-#define UNDO_FLAG			0x0100	/* toggling SELECTED flag */
-#define UNDO_CHANGESIZE			0x0200	/* change size of object */
-#define UNDO_CHANGE2NDSIZE		0x0400	/* change 2ndSize of object */
-#define UNDO_MIRROR			0x0800	/* change side of board */
-#define UNDO_CHANGECLEARSIZE		0x1000	/* change clearance size */
-#define UNDO_CHANGEMASKSIZE		0x2000	/* change mask size */
-#define UNDO_CHANGEANGLES		0x4000	/* change arc angles */
-#define UNDO_LAYERCHANGE		0x8000	/* layer new/delete/move */
-#define UNDO_CLEAR		       0x10000  /* clear/restore to polygons */
-#define UNDO_NETLISTCHANGE     	       0x20000	/* netlist change */
+#define	UNDO_REMOVE_CONTOUR		0x0020	/* removing a contour from a polygon */
+#define	UNDO_INSERT_CONTOUR		0x0040	/* inserting a contour from a polygon */
+#define	UNDO_ROTATE			0x0080	/* rotations */
+#define	UNDO_CREATE			0x0100	/* creation of objects */
+#define	UNDO_MOVETOLAYER		0x0200	/* moving objects to */
+#define	UNDO_FLAG			0x0400	/* toggling SELECTED flag */
+#define	UNDO_CHANGESIZE			0x0800	/* change size of object */
+#define	UNDO_CHANGE2NDSIZE		0x1000	/* change 2ndSize of object */
+#define	UNDO_MIRROR			0x2000	/* change side of board */
+#define	UNDO_CHANGECLEARSIZE		0x4000	/* change clearance size */
+#define	UNDO_CHANGEMASKSIZE		0x8000	/* change mask size */
+#define	UNDO_CHANGEANGLES	       0x10000	/* change arc angles */
+#define	UNDO_LAYERCHANGE	       0x20000	/* layer new/delete/move */
+#define	UNDO_CLEAR		       0x40000	/* clear/restore to polygons */
+#define	UNDO_NETLISTCHANGE	       0x80000	/* netlist change */
 
 
 /* ---------------------------------------------------------------------------
diff --git a/src/insert.c b/src/insert.c
index b4bcfe7..5e62463 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -74,6 +74,7 @@ static void *InsertPointIntoRat (RatTypePtr);
 static LocationType InsertX,	/* used by local routines as offset */
   InsertY;
 static Cardinal InsertAt;
+static bool InsertLast;
 static bool Forcible;
 static ObjectFunctionType InsertFunctions = {
   InsertPointIntoLine,
@@ -174,10 +175,7 @@ InsertPointIntoPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
        * first make sure adding the point is sensible
        */
       line.Thickness = 0;
-      if (InsertAt == 0)
-	line.Point1 = Polygon->Points[Polygon->PointN - 1];
-      else
-	line.Point1 = Polygon->Points[InsertAt - 1];
+      line.Point1 = Polygon->Points[prev_contour_point (Polygon, InsertAt)];
       line.Point2 = Polygon->Points[InsertAt];
       if (IsPointOnLine ((float) InsertX, (float) InsertY, 0.0, &line))
 	return (NULL);
@@ -190,10 +188,18 @@ InsertPointIntoPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
   save = *CreateNewPointInPolygon (Polygon, InsertX, InsertY);
   for (n = Polygon->PointN - 1; n > InsertAt; n--)
     Polygon->Points[n] = Polygon->Points[n - 1];
+
+  /* Shift up indices of any holes */
+  for (n = 0; n < Polygon->HoleIndexN; n++)
+    if (Polygon->HoleIndex[n] > InsertAt ||
+	(InsertLast && Polygon->HoleIndex[n] == InsertAt))
+      Polygon->HoleIndex[n]++;
+
   Polygon->Points[InsertAt] = save;
   SetChangedFlag (true);
   AddObjectToInsertPointUndoList (POLYGONPOINT_TYPE, Layer, Polygon,
 				  &Polygon->Points[InsertAt]);
+
   SetPolygonBoundingBox (Polygon);
   r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
   InitClip (PCB->Data, Layer, Polygon);
@@ -210,7 +216,8 @@ InsertPointIntoPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
  */
 void *
 InsertPointIntoObject (int Type, void *Ptr1, void *Ptr2, Cardinal * Ptr3,
-		       LocationType DX, LocationType DY, bool Force)
+		       LocationType DX, LocationType DY, bool Force,
+		       bool insert_last)
 {
   void *ptr;
 
@@ -218,6 +225,7 @@ InsertPointIntoObject (int Type, void *Ptr1, void *Ptr2, Cardinal * Ptr3,
   InsertX = DX;
   InsertY = DY;
   InsertAt = *Ptr3;
+  InsertLast = insert_last;
   Forcible = Force;
 
   /* the operation insert the points to the undo-list */
diff --git a/src/insert.h b/src/insert.h
index 87b6cbb..350a0de 100644
--- a/src/insert.h
+++ b/src/insert.h
@@ -39,7 +39,7 @@
  * prototypes
  */
 void *InsertPointIntoObject (int, void *, void *, Cardinal *, LocationType,
-			     LocationType, bool);
+			     LocationType, bool, bool);
 PointTypePtr AdjustInsertPoint (void);
 
 #endif
diff --git a/src/mymem.c b/src/mymem.c
index 46714bb..bed0f9b 100644
--- a/src/mymem.c
+++ b/src/mymem.c
@@ -459,6 +459,28 @@ GetPointMemoryInPolygon (PolygonTypePtr Polygon)
 }
 
 /* ---------------------------------------------------------------------------
+ * gets the next slot for a point in a polygon struct, allocates memory
+ * if necessary
+ */
+Cardinal *
+GetHoleIndexMemoryInPolygon (PolygonTypePtr Polygon)
+{
+  Cardinal *holeindex = Polygon->HoleIndex;
+
+  /* realloc new memory if necessary and clear it */
+  if (Polygon->HoleIndexN >= Polygon->HoleIndexMax)
+    {
+      Polygon->HoleIndexMax += STEP_POLYGONHOLEINDEX;
+      holeindex = MyRealloc (holeindex, Polygon->HoleIndexMax * sizeof (int),
+			     "GetHoleIndexMemoryInPolygon()");
+      Polygon->HoleIndex = holeindex;
+      memset (holeindex + Polygon->HoleIndexN, 0,
+	      STEP_POLYGONHOLEINDEX * sizeof (int));
+    }
+  return (holeindex + Polygon->HoleIndexN++);
+}
+
+/* ---------------------------------------------------------------------------
  * get next slot for an element, allocates memory if necessary
  */
 ElementTypePtr
@@ -734,6 +756,7 @@ FreePolygonMemory (PolygonTypePtr Polygon)
   if (Polygon)
     {
       MYFREE (Polygon->Points);
+      MYFREE (Polygon->HoleIndex);
       if (Polygon->Clipped)
 	poly_Free (&Polygon->Clipped);
       poly_FreeContours (&Polygon->NoHoles);
diff --git a/src/mymem.h b/src/mymem.h
index b9d4de1..81dff7a 100644
--- a/src/mymem.h
+++ b/src/mymem.h
@@ -58,6 +58,7 @@
 #define	STEP_UNDOLIST		500
 #define	STEP_POLYGON		10
 #define	STEP_POLYGONPOINT	10
+#define	STEP_POLYGONHOLEINDEX	10
 #define	STEP_LIBRARYMENU	10
 #define	STEP_LIBRARYENTRY	20
 #define	STEP_RUBBERBAND		100
@@ -82,6 +83,7 @@ RatTypePtr GetRatMemory (DataTypePtr);
 TextTypePtr GetTextMemory (LayerTypePtr);
 PolygonTypePtr GetPolygonMemory (LayerTypePtr);
 PointTypePtr GetPointMemoryInPolygon (PolygonTypePtr);
+Cardinal *GetHoleIndexMemoryInPolygon (PolygonTypePtr);
 ElementTypePtr GetElementMemory (DataTypePtr);
 BoxTypePtr GetBoxMemory (BoxListTypePtr);
 ConnectionTypePtr GetConnectionMemory (NetTypePtr);
diff --git a/src/parse_l.l b/src/parse_l.l
index 0f3b72e..8aa754c 100644
--- a/src/parse_l.l
+++ b/src/parse_l.l
@@ -129,6 +129,7 @@ Mark		{ return(T_MARK); }
 Groups		{ return(T_GROUPS); }
 Styles		{ return(T_STYLES); }
 Polygon		{ return(T_POLYGON); }
+Hole		{ return(T_POLYGON_HOLE); }
 Arc		{ return(T_ARC); }
 NetList		{ return(T_NETLIST); }
 Net		{ return(T_NET); }
diff --git a/src/parse_y.y b/src/parse_y.y
index 1d64fe8..a5b2d23 100644
--- a/src/parse_y.y
+++ b/src/parse_y.y
@@ -102,9 +102,8 @@ static int check_file_version (int);
 
 %token	T_FILEVERSION T_PCB T_LAYER T_VIA T_RAT T_LINE T_ARC T_RECTANGLE T_TEXT T_ELEMENTLINE
 %token	T_ELEMENT T_PIN T_PAD T_GRID T_FLAGS T_SYMBOL T_SYMBOLLINE T_CURSOR
-%token	T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_NETLIST T_NET T_CONN
+%token	T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_POLYGON_HOLE T_NETLIST T_NET T_CONN
 %token	T_AREA T_THERMAL T_DRC T_ATTRIBUTE
-
 %type	<number>	symbolid
 %type	<string>	opt_string
 %type	<flagtype>	flags
@@ -895,31 +894,7 @@ layerdefinition
 		| text_newformat
 		| text_oldformat
 		| { attr_list = & Layer->Attributes; } attributes
-			/* flags are passed in */
-		| T_POLYGON '(' flags ')' '('
-			{
-				Polygon = CreateNewPolygon(Layer, $3);
-			}
-		  polygonpoints ')'
-		  	{
-					/* ignore junk */
-				if (Polygon->PointN >= 3)
-				  {
-				    SetPolygonBoundingBox (Polygon);
-				    if (!Layer->polygon_tree)
-				      Layer->polygon_tree = r_create_tree (NULL, 0, 0);
-				    r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
-				  }
-				else
-				{
-					Message("WARNING parsing file '%s'\n"
-						"    line:        %i\n"
-						"    description: 'ignored polygon (< 3 points)'\n",
-						yyfilename, yylineno);
-					DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
-				}
-			}
-		;
+		| polygon_format
 
 /* %start-doc pcbfile Line
 
@@ -1124,6 +1099,11 @@ text_hi_format
 Polygon (SFlags) (
 @ @ @ @dots{} (X Y) @dots{}
 @ @ @ @dots{} [X Y] @dots{}
+@ @ @ Hole (
+@ @ @ @ @ @ @dots{} (X Y) @dots{}
+@ @ @ @ @ @ @dots{} [X Y] @dots{}
+@ @ @ )
+@ @ @ @dots{}
 )
 @end syntax
 
@@ -1132,10 +1112,67 @@ Polygon (SFlags) (
 Symbolic or numeric flags.
 @item X Y
 Coordinates of each vertex.  You must list at least three coordinates.
+@item Hole (...)
+Defines a hole within the polygon's outer contour. There may be zero or more such sections.
 @end table
 
 %end-doc */
 
+polygon_format
+		: /* flags are passed in */
+		T_POLYGON '(' flags ')' '('
+			{
+				Polygon = CreateNewPolygon(Layer, $3);
+			}
+		  polygonpoints
+		  polygonholes ')'
+			{
+				Cardinal contour, contour_start, contour_end;
+				bool bad_contour_found = false;
+				/* ignore junk */
+				for (contour = 0; contour <= Polygon->HoleIndexN; contour++)
+				  {
+				    contour_start = (contour == 0) ?
+						      0 : Polygon->HoleIndex[contour - 1];
+				    contour_end = (contour == Polygon->HoleIndexN) ?
+						 Polygon->PointN :
+						 Polygon->HoleIndex[contour];
+				    if (contour_end - contour_start < 3)
+				      bad_contour_found = true;
+				  }
+
+				if (bad_contour_found)
+				  {
+				    Message("WARNING parsing file '%s'\n"
+					    "    line:        %i\n"
+					    "    description: 'ignored polygon (< 3 points in a contour)'\n",
+					    yyfilename, yylineno);
+				    DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
+				  }
+				else
+				  {
+				    SetPolygonBoundingBox (Polygon);
+				    if (!Layer->polygon_tree)
+				      Layer->polygon_tree = r_create_tree (NULL, 0, 0);
+				    r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
+				  }
+			}
+		;
+
+polygonholes
+		: /* empty */
+		| polygonhole
+		| polygonholes polygonhole
+		;
+
+polygonhole
+		: T_POLYGON_HOLE '('
+			{
+				CreateNewHoleInPolygon (Polygon);
+			}
+		  polygonpoints ')'
+		;
+
 polygonpoints
 		: polygonpoint
 		| polygonpoints polygonpoint
diff --git a/src/polygon.c b/src/polygon.c
index 97164ab..e916741 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -120,6 +120,73 @@ static double circleVerticies[] = {
   0.98768834059513777, 0.15643446504023087,
 };
 
+Cardinal
+polygon_point_idx (PolygonTypePtr polygon, PointTypePtr point)
+{
+  assert (point >= polygon->Points);
+  assert (point <= polygon->Points + polygon->PointN);
+  return ((char *)point - (char *)polygon->Points) / sizeof (PointType);
+}
+
+/* Find contour number: 0 for outer, 1 for first hole etc.. */
+Cardinal
+polygon_point_contour (PolygonTypePtr polygon, Cardinal point)
+{
+  Cardinal i;
+  Cardinal contour = 0;
+
+  for (i = 0; i < polygon->HoleIndexN; i++)
+    if (point >= polygon->HoleIndex[i])
+      contour = i + 1;
+  return contour;
+}
+
+Cardinal
+next_contour_point (PolygonTypePtr polygon, Cardinal point)
+{
+  Cardinal contour;
+  Cardinal this_contour_start;
+  Cardinal next_contour_start;
+
+  contour = polygon_point_contour (polygon, point);
+
+  this_contour_start = (contour == 0) ? 0 :
+                                        polygon->HoleIndex[contour - 1];
+  next_contour_start =
+    (contour == polygon->HoleIndexN) ? polygon->PointN :
+                                       polygon->HoleIndex[contour];
+
+  /* Wrap back to the start of the contour we're in if we pass the end */
+  if (++point == next_contour_start)
+    point = this_contour_start;
+
+  return point;
+}
+
+Cardinal
+prev_contour_point (PolygonTypePtr polygon, Cardinal point)
+{
+  Cardinal contour;
+  Cardinal prev_contour_end;
+  Cardinal this_contour_end;
+
+  contour = polygon_point_contour (polygon, point);
+
+  prev_contour_end = (contour == 0) ? 0 :
+                                      polygon->HoleIndex[contour - 1];
+  this_contour_end =
+    (contour == polygon->HoleIndexN) ? polygon->PointN - 1:
+                                       polygon->HoleIndex[contour] - 1;
+
+  /* Wrap back to the start of the contour we're in if we pass the end */
+  if (point == prev_contour_end)
+    point = this_contour_end;
+  else
+    point--;
+
+  return point;
+}
+
 static void
 add_noholes_polyarea (PLINE *pline, void *user_data)
 {
@@ -205,33 +272,49 @@ original_poly (PolygonType * p)
 {
   PLINE *contour = NULL;
   POLYAREA *np = NULL;
+  Cardinal n;
   Vector v;
+  int hole = 0;
 
-  /* first make initial polygon contour */
-  POLYGONPOINT_LOOP (p);
-  {
-    v[0] = point->X;
-    v[1] = point->Y;
-    if (contour == NULL)
-      {
-        if ((contour = poly_NewContour (v)) == NULL)
-          return NULL;
-      }
-    else
-      {
-        poly_InclVertex (contour->head.prev, poly_CreateNode (v));
-      }
-  }
-  END_LOOP;
-  poly_PreContour (contour, TRUE);
-  /* make sure it is a positive contour */
-  if ((contour->Flags.orient) != PLF_DIR)
-    poly_InvContour (contour);
-  assert ((contour->Flags.orient) == PLF_DIR);
   if ((np = poly_Create ()) == NULL)
     return NULL;
-  poly_InclContour (np, contour);
-  assert (poly_Valid (np));
+
+  /* first make initial polygon contour */
+  for (n = 0; n < p->PointN; n++)
+    {
+      /* No current contour? Make a new one starting at point */
+      /*   (or) Add point to existing contour */
+
+      v[0] = p->Points[n].X;
+      v[1] = p->Points[n].Y;
+      if (contour == NULL)
+        {
+          if ((contour = poly_NewContour (v)) == NULL)
+            return NULL;
+        }
+      else
+        {
+          poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+        }
+
+      /* Is current point last in contour? If so process it. */
+      if (n == p->PointN - 1 ||
+          (hole < p->HoleIndexN && n == p->HoleIndex[hole] - 1))
+        {
+          poly_PreContour (contour, TRUE);
+
+          /* make sure it is a positive contour (outer) or negative (hole) */
+          if (contour->Flags.orient != (hole ? PLF_INV : PLF_DIR))
+            poly_InvContour (contour);
+          assert (contour->Flags.orient == (hole ? PLF_INV : PLF_DIR));
+
+          poly_InclContour (np, contour);
+          contour = NULL;
+          assert (poly_Valid (np));
+
+          hole++;
+        }
+  }
   return biggest (np);
 }
 
@@ -1078,31 +1161,26 @@ InitClip (DataTypePtr Data, LayerTypePtr layer, PolygonType * p)
 bool
 RemoveExcessPolygonPoints (LayerTypePtr Layer, PolygonTypePtr Polygon)
 {
-  PointTypePtr pt1, pt2, pt3;
-  Cardinal n;
+  PointTypePtr p;
+  Cardinal n, prev, next;
   LineType line;
   bool changed = false;
 
   if (Undoing ())
     return (false);
-  /* there are always at least three points in a polygon */
-  pt1 = &Polygon->Points[Polygon->PointN - 1];
-  pt2 = &Polygon->Points[0];
-  pt3 = &Polygon->Points[1];
-  for (n = 0; n < Polygon->PointN; n++, pt1++, pt2++, pt3++)
+
+  for (n = 0; n < Polygon->PointN; n++)
     {
-      /* wrap around polygon */
-      if (n == 1)
-        pt1 = &Polygon->Points[0];
-      if (n == Polygon->PointN - 1)
-        pt3 = &Polygon->Points[0];
-      line.Point1 = *pt1;
-      line.Point2 = *pt3;
+      prev = prev_contour_point (Polygon, n);
+      next = next_contour_point (Polygon, n);
+      p = &Polygon->Points[n];
+
+      line.Point1 = Polygon->Points[prev];
+      line.Point2 = Polygon->Points[next];
       line.Thickness = 0;
-      if (IsPointOnLine ((float) pt2->X, (float) pt2->Y, 0.0, &line))
+      if (IsPointOnLine ((float) p->X, (float) p->Y, 0.0, &line))
         {
-          RemoveObject (POLYGONPOINT_TYPE, (void *) Layer, (void *) Polygon,
-                        (void *) pt2);
+          RemoveObject (POLYGONPOINT_TYPE, Layer, Polygon, p);
           changed = true;
         }
     }
@@ -1119,8 +1197,7 @@ GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, LocationType X,
                                LocationType Y)
 {
   double mindistance = (double) MAX_COORD * MAX_COORD;
-  PointTypePtr ptr1 = &Polygon->Points[Polygon->PointN - 1],
-    ptr2 = &Polygon->Points[0];
+  PointTypePtr ptr1, ptr2;
   Cardinal n, result = 0;
 
   /* we calculate the distance to each segment and choose the
@@ -1130,9 +1207,12 @@ GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, LocationType X,
    * to the segment end point.
    */
 
-  for (n = 0; n < Polygon->PointN; n++, ptr2++)
+  for (n = 0; n < Polygon->PointN; n++)
     {
       register double u, dx, dy;
+      ptr1 = &Polygon->Points[prev_contour_point (Polygon, n)];
+      ptr2 = &Polygon->Points[n];
+
       dx = ptr2->X - ptr1->X;
       dy = ptr2->Y - ptr1->Y;
       if (dx != 0.0 || dy != 0.0)
@@ -1159,7 +1239,6 @@ GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, LocationType X,
               result = n;
             }
         }
-      ptr1 = ptr2;
     }
   return (result);
 }
@@ -1729,11 +1808,19 @@ debug_polyarea (POLYAREA *p)
 void
 debug_polygon (PolygonType *p)
 {
-  int i;
+  Cardinal i;
   POLYAREA *pa;
   fprintf (stderr, "POLYGON %p  %d pts\n", p, p->PointN);
   for (i=0; i<p->PointN; i++)
     fprintf(stderr, "\t%d: %d, %d\n", i, p->Points[i].X, p->Points[i].Y);
+  if (p->HoleIndexN)
+    {
+      fprintf (stderr, "%d holes, starting at indices\n", p->HoleIndexN);
+      for (i=0; i<p->HoleIndexN; i++)
+        fprintf(stderr, "\t%d: %d\n", i, p->HoleIndex[i]);
+    }
+  else
+    fprintf (stderr, "it has no holes\n");
   pa = p->Clipped;
   while (pa)
     {
diff --git a/src/polygon.h b/src/polygon.h
index 1eb5757..a93d965 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -33,6 +33,10 @@
 
 #include "global.h"
 
+Cardinal polygon_point_idx (PolygonTypePtr polygon, PointTypePtr point);
+Cardinal polygon_point_contour (PolygonTypePtr polygon, Cardinal point);
+Cardinal prev_contour_point (PolygonTypePtr polygon, Cardinal point);
+Cardinal next_contour_point (PolygonTypePtr polygon, Cardinal point);
 Cardinal GetLowestDistancePolygonPoint (PolygonTypePtr,
 					LocationType, LocationType);
 bool RemoveExcessPolygonPoints (LayerTypePtr, PolygonTypePtr);
diff --git a/src/remove.c b/src/remove.c
index a537bc0..98b9ade 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -74,6 +74,7 @@ static void *DestroyElement (ElementTypePtr);
 static void *RemoveVia (PinTypePtr);
 static void *RemoveRat (RatTypePtr);
 static void *DestroyPolygonPoint (LayerTypePtr, PolygonTypePtr, PointTypePtr);
+static void *RemovePolygonContour (LayerTypePtr, PolygonTypePtr, Cardinal);
 static void *RemovePolygonPoint (LayerTypePtr, PolygonTypePtr, PointTypePtr);
 static void *RemoveLinePoint (LayerTypePtr, LineTypePtr, PointTypePtr);
 
@@ -203,17 +204,33 @@ static void *
 DestroyPolygonPoint (LayerTypePtr Layer,
 		     PolygonTypePtr Polygon, PointTypePtr Point)
 {
-  PointTypePtr ptr;
+  Cardinal point_idx;
+  Cardinal i;
+  Cardinal contour;
+  Cardinal contour_start, contour_end, contour_points;
+
+  point_idx = polygon_point_idx (Polygon, Point);
+  contour = polygon_point_contour (Polygon, point_idx);
+  contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1];
+  contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN :
+                                                   Polygon->HoleIndex[contour];
+  contour_points = contour_end - contour_start;
+
+  if (contour_points <= 3)
+    return RemovePolygonContour (Layer, Polygon, contour);
 
-  if (Polygon->PointN <= 3)
-    return RemovePolygon (Layer, Polygon);
   r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon);
-  for (ptr = Point + 1; ptr != &Polygon->Points[Polygon->PointN]; ptr++)
-    {
-      *Point = *ptr;
-      Point = ptr;
-    }
+
+  /* remove point from list, keep point order */
+  for (i = point_idx; i < Polygon->PointN - 1; i++)
+    Polygon->Points[i] = Polygon->Points[i + 1];
   Polygon->PointN--;
+
+  /* Shift down indices of any holes */
+  for (i = 0; i < Polygon->HoleIndexN; i++)
+    if (Polygon->HoleIndex[i] > point_idx)
+      Polygon->HoleIndex[i]--;
+
   SetPolygonBoundingBox (Polygon);
   r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
   InitClip (PCB->Data, Layer, Polygon);
@@ -481,41 +498,100 @@ RemovePolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
 }
 
 /* ---------------------------------------------------------------------------
+ * removes a contour from a polygon.
+ * If removing the outer contour, it removes the whole polygon.
+ */
+static void *
+RemovePolygonContour (LayerTypePtr Layer,
+                      PolygonTypePtr Polygon,
+                      Cardinal contour)
+{
+  Cardinal contour_start, contour_end, contour_points;
+  Cardinal i;
+
+  if (contour == 0)
+    return RemovePolygon (Layer, Polygon);
+
+  if (Layer->On)
+    {
+      ErasePolygon (Polygon);
+      if (!Bulk)
+        Draw ();
+    }
+
+  /* Copy the polygon to the undo list */
+  AddObjectToRemoveContourUndoList (POLYGON_TYPE, Layer, Polygon);
+
+  contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1];
+  contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN :
+                                                   Polygon->HoleIndex[contour];
+  contour_points = contour_end - contour_start;
+
+  /* remove points from list, keep point order */
+  for (i = contour_start; i < Polygon->PointN - contour_points; i++)
+    Polygon->Points[i] = Polygon->Points[i + contour_po...
 
[truncated message content] | 
| 
      
      
      From: <gi...@gp...> - 2010-06-05 22:49:07
      
     | 
| The branch, master has been updated
       via  76bc5883fdf1e1f6c5b9c16bdef7208911d713d6 (commit)
       via  8aa0eac4e7025398c6bbe49580ef9afdae0016ac (commit)
      from  c524ef4fa55162cd11ba79625896a018e8c55602 (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/gpcb-menu.res            |    2 +-
 src/hid/gtk/gui-log-window.c |    1 +
 src/pcb-menu.res             |    2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit 76bc5883fdf1e1f6c5b9c16bdef7208911d713d6
Author: Jared Casper <jar...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add missing return statement.
:100644 100644 33e1940... ae25ed7... M	src/hid/gtk/gui-log-window.c
commit 8aa0eac4e7025398c6bbe49580ef9afdae0016ac
Author: Jared Casper <jar...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Fix Bug #2717258, Lock mode with F12.
    
    Binds F12 to lock mode in the default gcpb-menu.res and pcb-menu.res
    files, bringing them inline with existing documentation.
:100644 100644 37e141d... df307be... M	src/gpcb-menu.res
:100644 100644 cbdcd2d... 38e86e4... M	src/pcb-menu.res
=========
 Changes
=========
commit 76bc5883fdf1e1f6c5b9c16bdef7208911d713d6
Author: Jared Casper <jar...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add missing return statement.
diff --git a/src/hid/gtk/gui-log-window.c b/src/hid/gtk/gui-log-window.c
index 33e1940..ae25ed7 100644
--- a/src/hid/gtk/gui-log-window.c
+++ b/src/hid/gtk/gui-log-window.c
@@ -218,6 +218,7 @@ GhidLogShowOnAppend (int argc, char **argv, int x, int y)
     {
       log_show_on_append = FALSE;
     }
+  return 0;
 }
 
 HID_Action ghid_log_action_list[] = {
commit 8aa0eac4e7025398c6bbe49580ef9afdae0016ac
Author: Jared Casper <jar...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Fix Bug #2717258, Lock mode with F12.
    
    Binds F12 to lock mode in the default gcpb-menu.res and pcb-menu.res
    files, bringing them inline with existing documentation.
diff --git a/src/gpcb-menu.res b/src/gpcb-menu.res
index 37e141d..df307be 100644
--- a/src/gpcb-menu.res
+++ b/src/gpcb-menu.res
@@ -516,7 +516,7 @@ PopupMenus =
        {"Insert Point" checked=insertpointmode,1 Mode(InsertPoint) a={"Insert" "<Key>Insert"}}
        {"Move" checked=movemode,1 Mode(Move)}
        {"Copy" checked=copymode,1 Mode(Copy)}
-       {"Lock" checked=lockmode,1 Mode(Lock)}
+       {"Lock" checked=lockmode,1 Mode(Lock) a={"F12" "<Key>F12"}}
        {"Cancel" Mode(Escape) a={"Esc" "<Key>Escape"}}
       }
     }
diff --git a/src/pcb-menu.res b/src/pcb-menu.res
index cbdcd2d..38e86e4 100644
--- a/src/pcb-menu.res
+++ b/src/pcb-menu.res
@@ -182,7 +182,7 @@ MainMenu =
    {"Insert Point" checked=insertpointmode,1 Mode(InsertPoint) a={"Insert" "<Key>Insert"}}
    {"Move" checked=movemode,1 Mode(Move)}
    {"Copy" checked=copymode,1 Mode(Copy)}
-   {"Lock" checked=lockmode,1 Mode(Lock)}
+   {"Lock" checked=lockmode,1 Mode(Lock) a={"F12" "<Key>F12"}}
    {"Cancel" Mode(Cancel) a={"Esc" "<Key>Escape"}}
    -
    {"Command" Command() a={":" "<Key>:"}}
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-05 11:50:22
      
     | 
| The branch, master has been updated
  discards  7dcc3d0b7b6dcba356601aa8601d5e2a11993e39 (commit)
       via  c524ef4fa55162cd11ba79625896a018e8c55602 (commit)
      from  7dcc3d0b7b6dcba356601aa8601d5e2a11993e39 (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/crosshair.c        |    2 +-
 src/hid/lesstif/main.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit c524ef4fa55162cd11ba79625896a018e8c55602
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Revert some "True" -> "true" string changes
    
    These were inadvertently changed by the mechanised Boolean -> bool
    replacement in commit ad5eb5a165442be38624aa622beeb57dc1d2afbd
:100644 100644 88b9cc0... 13ddc71... M	src/crosshair.c
:100644 100644 bc8f17c... 3280032... M	src/hid/lesstif/main.c
=========
 Changes
=========
commit c524ef4fa55162cd11ba79625896a018e8c55602
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Revert some "True" -> "true" string changes
    
    These were inadvertently changed by the mechanised Boolean -> bool
    replacement in commit ad5eb5a165442be38624aa622beeb57dc1d2afbd
diff --git a/src/crosshair.c b/src/crosshair.c
index 88b9cc0..13ddc71 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -940,7 +940,7 @@ FitCrosshairIntoGrid (LocationType X, LocationType Y)
 	if (ans == NO_TYPE)
 	  hid_action("PointCursor");
 	else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
-	  hid_actionl("PointCursor","true", NULL);
+	  hid_actionl("PointCursor","True", NULL);
     }
   if (Settings.Mode == LINE_MODE
       && Crosshair.AttachedLine.State != STATE_FIRST
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index bc8f17c..3280032 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -2020,7 +2020,7 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	    break;
 	  case HID_Boolean:
 	    o->argKind = XrmoptionNoArg;
-	    o->value = "true";
+	    o->value = "True";
 	    acount++;
 	    break;
 	  default:
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-05 11:48:02
      
     | 
| The branch, master has been updated
       via  7dcc3d0b7b6dcba356601aa8601d5e2a11993e39 (commit)
      from  ad5eb5a165442be38624aa622beeb57dc1d2afbd (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
=========
=================
 Commit Messages
=================
=========
 Changes
=========
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-05 03:38:22
      
     | 
| The branch, master has been updated
       via  ad5eb5a165442be38624aa622beeb57dc1d2afbd (commit)
      from  fa761a714fc916db435d36e1f873a6fb1b8fb012 (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/action.c                     |  674 ++++++++++++++++++------------------
 src/action.h                     |    2 +-
 src/autoplace.c                  |   32 +-
 src/autoplace.h                  |    2 +-
 src/autoroute.c                  |  220 ++++++------
 src/autoroute.h                  |    2 +-
 src/box.h                        |   10 +-
 src/buffer.c                     |   76 ++--
 src/buffer.h                     |   10 +-
 src/change.c                     |  316 +++++++++---------
 src/change.h                     |   78 +++---
 src/clip.c                       |   14 +-
 src/clip.h                       |    2 +-
 src/command.c                    |    4 +-
 src/copy.c                       |   14 +-
 src/copy.h                       |    4 +-
 src/create.c                     |    8 +-
 src/create.h                     |    4 +-
 src/crosshair.c                  |   46 ++--
 src/crosshair.h                  |   12 +-
 src/data.c                       |    4 +-
 src/data.h                       |    6 +-
 src/djopt.c                      |    2 +-
 src/draw.c                       |  136 ++++----
 src/draw.h                       |    2 +-
 src/drill.c                      |   12 +-
 src/file.c                       |   48 ++--
 src/file.h                       |    2 +-
 src/find.c                       |  700 +++++++++++++++++++-------------------
 src/find.h                       |   28 +-
 src/flags.c                      |    2 +-
 src/global.h                     |   27 +-
 src/gts/gts.h                    |    2 +-
 src/hid/gerber/gerber.c          |   24 +-
 src/hid/gtk/gui-command-window.c |    8 +-
 src/hid/gtk/gui-dialog-size.c    |    4 +-
 src/hid/gtk/gui-drc-window.c     |   26 +-
 src/hid/gtk/gui-library-window.c |    4 +-
 src/hid/gtk/gui-misc.c           |    8 +-
 src/hid/gtk/gui-netlist-window.c |   12 +-
 src/hid/gtk/gui-output-events.c  |    4 +-
 src/hid/gtk/gui-top-window.c     |    8 +-
 src/hid/lesstif/dialogs.c        |   44 ++--
 src/hid/lesstif/library.c        |    4 +-
 src/hid/lesstif/main.c           |   30 +-
 src/hid/lesstif/menu.c           |    6 +-
 src/hid/lesstif/netlist.c        |   26 +-
 src/hid/lesstif/styles.c         |    6 +-
 src/hid/nelma/nelma.c            |    2 +-
 src/insert.c                     |    6 +-
 src/insert.h                     |    2 +-
 src/line.c                       |   40 ++--
 src/main.c                       |    2 +-
 src/misc.c                       |   86 +++---
 src/misc.h                       |    8 +-
 src/move.c                       |   20 +-
 src/move.h                       |    4 +-
 src/mtspace.c                    |   22 +-
 src/mtspace.h                    |    2 +-
 src/mymem.c                      |    8 +-
 src/netlist.c                    |    4 +-
 src/parse_l.l                    |    4 +-
 src/parse_y.y                    |   44 ++--
 src/polygon.c                    |   64 ++--
 src/polygon.h                    |   12 +-
 src/polygon1.c                   |    4 +-
 src/rats.c                       |  116 ++++----
 src/rats.h                       |    6 +-
 src/remove.c                     |   32 +-
 src/remove.h                     |    4 +-
 src/report.c                     |   22 +-
 src/rotate.c                     |    6 +-
 src/rtree.c                      |   48 ++--
 src/rtree.h                      |    2 +-
 src/rubberband.c                 |   10 +-
 src/search.c                     |  230 +++++++-------
 src/search.h                     |   18 +-
 src/select.c                     |  122 ++++----
 src/select.h                     |   12 +-
 src/set.c                        |   36 +-
 src/set.h                        |   10 +-
 src/thermal.c                    |   10 +-
 src/toporouter.c                 |   10 +-
 src/undo.c                       |  218 ++++++------
 src/undo.h                       |   10 +-
 src/vendor.c                     |   52 ++--
 src/vendor.h                     |    2 +-
 87 files changed, 2011 insertions(+), 2014 deletions(-)
=================
 Commit Messages
=================
commit ad5eb5a165442be38624aa622beeb57dc1d2afbd
Author: Robert Spanton <rsp...@ze...>
Commit: DJ Delorie <dj...@de...>
    Change all Booleans to bool.
    
    c99 provides bool.  Declaring Boolean adds some obscurity to the code,
    and could also miss out on some machine-specific optimisations.
    
    This patch removes the definition of Boolean, and changes all
    instances of it to bool.
    
    If you've come across this commit because it's causing you issues when
    rebasing on mainline pcb, then you should find the following script
    useful.  You can use it to rewrite all of your local commits to use
    bool instead of Boolean like so:
    
    	git filter-branch --tree-filter rename-bool.sh HEAD...${HASH}
    
    Replacing ${HASH} with the latest commit that's in mainline.
    
    if [ ! -f src/autoplace.c ]
        then
        echo "This doesn't look like the PCB source directory."
        echo "Cowardly exiting to avoid causing misery!"
        exit
    fi
    
    chg_bool ()
    {
        FNAME=$1
        ADDR=$2
    
        sed -i -e "${ADDR}s/\bBoolean\b/bool/g" "$FNAME"
        sed -i -e "${ADDR}s/\bTrue\b/true/g" "$FNAME"
        sed -i -e "${ADDR}s/\bFalse\b/false/g" "$FNAME"
    }
    
    find -name '*.[ch]' | while read f
    do
        chg_bool "$f"
    done
    
    find -name '*.[yl]' | while read f
    do
        # Replace first '%%' line with __TMP_MARKER_
        sed -i -e '0,/^%%/s/^%%/__TMP_MARKER_/' "$f"
    
        # Replace in section before the first '%%'
        chg_bool "$f" "0,/^__TMP_MARKER_/"
        # Replace in section after the last '%%'
        chg_bool "$f" "/^%%/,$"
    
        # Remove the temporary marker:
        sed -i -e 's/^__TMP_MARKER_/%%/' "$f"
    done
:100644 100644 dde6484... 6546be1... M	src/action.c
:100644 100644 8ce4a15... ee116e8... M	src/action.h
:100644 100644 2c85739... 2572755... M	src/autoplace.c
:100644 100644 66b1869... ffb15df... M	src/autoplace.h
:100644 100644 b9f1fdd... b6bf91d... M	src/autoroute.c
:100644 100644 960043d... 59f75ad... M	src/autoroute.h
:100644 100644 291c6d7... bedb6ab... M	src/box.h
:100644 100644 fbd1735... e04ae2a... M	src/buffer.c
:100644 100644 07c21c1... 98da959... M	src/buffer.h
:100644 100644 2fedc52... 5546f1f... M	src/change.c
:100644 100644 fc577a0... 7bae706... M	src/change.h
:100644 100644 f24f442... f38c660... M	src/clip.c
:100644 100644 f4633d4... fcc5f2e... M	src/clip.h
:100644 100644 9404ac4... b41263b... M	src/command.c
:100644 100644 583feb8... ffa0ed3... M	src/copy.c
:100644 100644 472fc75... ac50e2c... M	src/copy.h
:100644 100644 1a79ae6... 0c5abe1... M	src/create.c
:100644 100644 a994c84... b9f418c... M	src/create.h
:100644 100644 367922e... 88b9cc0... M	src/crosshair.c
:100644 100644 2e1fe7c... 8299778... M	src/crosshair.h
:100644 100644 c938389... d07413f... M	src/data.c
:100644 100644 53618c4... 101e3db... M	src/data.h
:100644 100644 c8ae961... 92fd2b8... M	src/djopt.c
:100644 100644 d06813d... 1bbbaa1... M	src/draw.c
:100644 100644 5d7c874... c0e23a3... M	src/draw.h
:100644 100644 455c524... 738ed18... M	src/drill.c
:100644 100644 2704ede... 3129601... M	src/file.c
:100644 100644 64eba23... 5791dda... M	src/file.h
:100644 100644 6fb62b6... 593be70... M	src/find.c
:100644 100644 c6e6eef... 5b04980... M	src/find.h
:100644 100644 c6c7458... 41e0b55... M	src/flags.c
:100644 100644 b7c9d0f... 62be07f... M	src/global.h
:100644 100644 99a92b7... 9397230... M	src/gts/gts.h
:100644 100644 dee7d06... fa908ce... M	src/hid/gerber/gerber.c
:100644 100644 15dd6db... ef2f637... M	src/hid/gtk/gui-command-window.c
:100644 100644 90d2cd4... 2f49f06... M	src/hid/gtk/gui-dialog-size.c
:100644 100644 fa2ec86... e2fa201... M	src/hid/gtk/gui-drc-window.c
:100644 100644 8bd0d7b... f54d914... M	src/hid/gtk/gui-library-window.c
:100644 100644 e8ad916... 32ca1c9... M	src/hid/gtk/gui-misc.c
:100644 100644 0cfe51d... 1d8e939... M	src/hid/gtk/gui-netlist-window.c
:100644 100644 3912aa3... c82e067... M	src/hid/gtk/gui-output-events.c
:100644 100644 09a29c1... 4d4ba7c... M	src/hid/gtk/gui-top-window.c
:100644 100644 ac61c7c... 6ab4b78... M	src/hid/lesstif/dialogs.c
:100644 100644 cc6c7cc... f818fe5... M	src/hid/lesstif/library.c
:100644 100644 1613547... bc8f17c... M	src/hid/lesstif/main.c
:100644 100644 f88664d... 59ab80b... M	src/hid/lesstif/menu.c
:100644 100644 ba4415c... 7d31197... M	src/hid/lesstif/netlist.c
:100644 100644 ec4e019... fb9d3b3... M	src/hid/lesstif/styles.c
:100644 100644 8e5ff0c... 68d7d5b... M	src/hid/nelma/nelma.c
:100644 100644 3d4a2f5... b4bcfe7... M	src/insert.c
:100644 100644 bbe99d5... 87b6cbb... M	src/insert.h
:100644 100644 ff2c884... 943660a... M	src/line.c
:100644 100644 8b80afe... 3340c7f... M	src/main.c
:100644 100644 20048db... dfbb1d7... M	src/misc.c
:100644 100644 3634f9b... d58e12e... M	src/misc.h
:100644 100644 6f0c82f... cd23253... M	src/move.c
:100644 100644 f060ff5... c4a844b... M	src/move.h
:100644 100644 f5ce554... 3640f5c... M	src/mtspace.c
:100644 100644 4e6eb8e... 4bbbbbf... M	src/mtspace.h
:100644 100644 4118cf0... 46714bb... M	src/mymem.c
:100644 100644 be81e4e... ade8326... M	src/netlist.c
:100644 100644 2a9d589... 0f3b72e... M	src/parse_l.l
:100644 100644 b76e689... 1d64fe8... M	src/parse_y.y
:100644 100644 365539a... 97164ab... M	src/polygon.c
:100644 100644 2faaa20... 1eb5757... M	src/polygon.h
:100644 100644 a8a8b89... 329058e... M	src/polygon1.c
:100644 100644 0e2a068... 29e9831... M	src/rats.c
:100644 100644 7a4dace... eb928d4... M	src/rats.h
:100644 100644 a82b478... a537bc0... M	src/remove.c
:100644 100644 8b7c166... 9fd4625... M	src/remove.h
:100644 100644 2e80e66... 6a1c47b... M	src/report.c
:100644 100644 247a1a9... 9e19581... M	src/rotate.c
:100644 100644 f7ffe4d... 0d5bf51... M	src/rtree.c
:100644 100644 254d64a... 3e91297... M	src/rtree.h
:100644 100644 ec4920f... e5fb797... M	src/rubberband.c
:100644 100644 4d450d3... 3f23ff4... M	src/search.c
:100644 100644 11d7d03... ae71967... M	src/search.h
:100644 100644 7b96fec... 5240837... M	src/select.c
:100644 100644 7a48dae... e24ab82... M	src/select.h
:100644 100644 912db04... 48d704d... M	src/set.c
:100644 100644 319bdce... e139766... M	src/set.h
:100644 100644 445b97d... 4fdcb1c... M	src/thermal.c
:100644 100644 e820677... fa57635... M	src/toporouter.c
:100644 100644 cb8d180... 50c6de5... M	src/undo.c
:100644 100644 a138927... c7a0288... M	src/undo.h
:100644 100644 7d4de5d... 39359cc... M	src/vendor.c
:100644 100644 8d7ef6f... 3b4d2d4... M	src/vendor.h
=========
 Changes
=========
commit ad5eb5a165442be38624aa622beeb57dc1d2afbd
Author: Robert Spanton <rsp...@ze...>
Commit: DJ Delorie <dj...@de...>
    Change all Booleans to bool.
    
    c99 provides bool.  Declaring Boolean adds some obscurity to the code,
    and could also miss out on some machine-specific optimisations.
    
    This patch removes the definition of Boolean, and changes all
    instances of it to bool.
    
    If you've come across this commit because it's causing you issues when
    rebasing on mainline pcb, then you should find the following script
    useful.  You can use it to rewrite all of your local commits to use
    bool instead of Boolean like so:
    
    	git filter-branch --tree-filter rename-bool.sh HEAD...${HASH}
    
    Replacing ${HASH} with the latest commit that's in mainline.
    
    if [ ! -f src/autoplace.c ]
        then
        echo "This doesn't look like the PCB source directory."
        echo "Cowardly exiting to avoid causing misery!"
        exit
    fi
    
    chg_bool ()
    {
        FNAME=$1
        ADDR=$2
    
        sed -i -e "${ADDR}s/\bBoolean\b/bool/g" "$FNAME"
        sed -i -e "${ADDR}s/\bTrue\b/true/g" "$FNAME"
        sed -i -e "${ADDR}s/\bFalse\b/false/g" "$FNAME"
    }
    
    find -name '*.[ch]' | while read f
    do
        chg_bool "$f"
    done
    
    find -name '*.[yl]' | while read f
    do
        # Replace first '%%' line with __TMP_MARKER_
        sed -i -e '0,/^%%/s/^%%/__TMP_MARKER_/' "$f"
    
        # Replace in section before the first '%%'
        chg_bool "$f" "0,/^__TMP_MARKER_/"
        # Replace in section after the last '%%'
        chg_bool "$f" "/^%%/,$"
    
        # Remove the temporary marker:
        sed -i -e 's/^__TMP_MARKER_/%%/' "$f"
    done
diff --git a/src/action.c b/src/action.c
index dde6484..6546be1 100644
--- a/src/action.c
+++ b/src/action.c
@@ -306,8 +306,8 @@ static struct
   int X;
   int Y;
   Cardinal Buffer;
-  Boolean Click;
-  Boolean Moving;		/* selected type clicked on */
+  bool Click;
+  bool Moving;		/* selected type clicked on */
   int Hit;			/* move type clicked on */
   void *ptr1;
   void *ptr2;
@@ -319,10 +319,10 @@ static int defer_updates = 0;
 static int defer_needs_update = 0;
 
 static Cardinal polyIndex = 0;
-static Boolean IgnoreMotionEvents = False;
-static Boolean saved_mode = False;
+static bool IgnoreMotionEvents = false;
+static bool saved_mode = false;
 #ifdef HAVE_LIBSTROKE
-static Boolean mid_stroke = False;
+static bool mid_stroke = false;
 static BoxType StrokeBox;
 #endif
 static FunctionType Functions[] = {
@@ -475,7 +475,7 @@ FinishStroke (void)
   unsigned long num;
   void *ptr1, *ptr2, *ptr3;
 
-  mid_stroke = False;
+  mid_stroke = false;
   if (stroke_trans (msg))
     {
       num = atoi (msg);
@@ -512,7 +512,7 @@ FinishStroke (void)
 	case 147423:
 	case 147523:
 	case 1474123:
-	  Redo (True);
+	  Redo (true);
 	  break;
 	case 148963:
 	case 147863:
@@ -555,7 +555,7 @@ FinishStroke (void)
 		   log (2.0));
 	    SetZoom (z);
 
-	    CenterDisplay (x, y, False);
+	    CenterDisplay (x, y, false);
 	    break;
 	  }
 
@@ -575,7 +575,7 @@ FinishStroke (void)
 static void
 ClearWarnings ()
 {
-  Settings.RatWarn = False;
+  Settings.RatWarn = false;
   ALLPIN_LOOP (PCB->Data);
   {
     if (TEST_FLAG (WARNFLAG, pin))
@@ -602,53 +602,53 @@ click_cb (hidval hv)
 {
   if (Note.Click)
     {
-      Note.Click = False;
+      Note.Click = false;
       if (Note.Moving && !gui->shift_is_pressed ())
 	{
-	  HideCrosshair (True);
+	  HideCrosshair (true);
 	  Note.Buffer = Settings.BufferNumber;
 	  SetBufferNumber (MAX_BUFFER - 1);
 	  ClearBuffer (PASTEBUFFER);
-	  AddSelectedToBuffer (PASTEBUFFER, Note.X, Note.Y, True);
+	  AddSelectedToBuffer (PASTEBUFFER, Note.X, Note.Y, true);
 	  SaveUndoSerialNumber ();
 	  RemoveSelected ();
 	  SaveMode ();
-	  saved_mode = True;
+	  saved_mode = true;
 	  SetMode (PASTEBUFFER_MODE);
-	  RestoreCrosshair (True);
+	  RestoreCrosshair (true);
 	}
       else if (Note.Hit && !gui->shift_is_pressed ())
 	{
-	  HideCrosshair (True);
+	  HideCrosshair (true);
 	  SaveMode ();
-	  saved_mode = True;
+	  saved_mode = true;
 	  SetMode (gui->control_is_pressed ()? COPY_MODE : MOVE_MODE);
 	  Crosshair.AttachedObject.Ptr1 = Note.ptr1;
 	  Crosshair.AttachedObject.Ptr2 = Note.ptr2;
 	  Crosshair.AttachedObject.Ptr3 = Note.ptr3;
 	  Crosshair.AttachedObject.Type = Note.Hit;
 	  AttachForCopy (Note.X, Note.Y);
-	  RestoreCrosshair (True);
+	  RestoreCrosshair (true);
 	}
       else
 	{
 	  BoxType box;
 
 	  Note.Hit = 0;
-	  Note.Moving = False;
-	  HideCrosshair (True);
+	  Note.Moving = false;
+	  HideCrosshair (true);
 	  SaveUndoSerialNumber ();
 	  box.X1 = -MAX_COORD;
 	  box.Y1 = -MAX_COORD;
 	  box.X2 = MAX_COORD;
 	  box.Y2 = MAX_COORD;
 	  /* unselect first if shift key not down */
-	  if (!gui->shift_is_pressed () && SelectBlock (&box, False))
-	    SetChangedFlag (True);
+	  if (!gui->shift_is_pressed () && SelectBlock (&box, false))
+	    SetChangedFlag (true);
 	  NotifyBlock ();
 	  Crosshair.AttachedBox.Point1.X = Note.X;
 	  Crosshair.AttachedBox.Point1.Y = Note.Y;
-	  RestoreCrosshair (True);
+	  RestoreCrosshair (true);
 	}
     }
 }
@@ -667,13 +667,13 @@ ReleaseMode (void)
       box.X2 = MAX_COORD;
       box.Y2 = MAX_COORD;
 
-      Note.Click = False;	/* inhibit timer action */
+      Note.Click = false;	/* inhibit timer action */
       SaveUndoSerialNumber ();
       /* unselect first if shift key not down */
       if (!gui->shift_is_pressed ())
 	{
-	  if (SelectBlock (&box, False))
-	    SetChangedFlag (True);
+	  if (SelectBlock (&box, false))
+	    SetChangedFlag (true);
 	  if (Note.Moving)
 	    {
 	      Note.Moving = 0;
@@ -683,7 +683,7 @@ ReleaseMode (void)
 	}
       RestoreUndoSerialNumber ();
       if (SelectObject ())
-	SetChangedFlag (True);
+	SetChangedFlag (true);
       Note.Hit = 0;
       Note.Moving = 0;
     }
@@ -693,7 +693,7 @@ ReleaseMode (void)
       NotifyMode ();
       ClearBuffer (PASTEBUFFER);
       SetBufferNumber (Note.Buffer);
-      Note.Moving = False;
+      Note.Moving = false;
       Note.Hit = 0;
     }
   else if (Note.Hit)
@@ -712,15 +712,15 @@ ReleaseMode (void)
       box.Y2 = MAX (Crosshair.AttachedBox.Point1.Y,
 		    Crosshair.AttachedBox.Point2.Y);
       RestoreUndoSerialNumber ();
-      if (SelectBlock (&box, True))
-	SetChangedFlag (True);
+      if (SelectBlock (&box, true))
+	SetChangedFlag (true);
       else if (Bumped)
 	IncrementUndoSerialNumber ();
       Crosshair.AttachedBox.State = STATE_FIRST;
     }
   if (saved_mode)
     RestoreMode ();
-  saved_mode = False;
+  saved_mode = false;
 }
 
 /* ---------------------------------------------------------------------------
@@ -873,7 +873,7 @@ NotifyLine (void)
   void *ptr1, *ptr2, *ptr3;
 
   if (!Marked.status || TEST_FLAG (LOCALREFFLAG, PCB))
-    SetLocalRef (Crosshair.X, Crosshair.Y, True);
+    SetLocalRef (Crosshair.X, Crosshair.Y, true);
   switch (Crosshair.AttachedLine.State)
     {
     case STATE_FIRST:		/* first point */
@@ -889,7 +889,7 @@ NotifyLine (void)
 	  type = SearchScreen (Crosshair.X, Crosshair.Y,
 			       PIN_TYPE | PAD_TYPE | VIA_TYPE, &ptr1, &ptr2,
 			       &ptr3);
-	  LookupConnection (Crosshair.X, Crosshair.Y, True, TO_PCB (1),
+	  LookupConnection (Crosshair.X, Crosshair.Y, true, TO_PCB (1),
 			    FOUNDFLAG);
 	}
       if (type == PIN_TYPE || type == VIA_TYPE)
@@ -943,7 +943,7 @@ NotifyLine (void)
 static void
 NotifyBlock (void)
 {
-  HideCrosshair (True);
+  HideCrosshair (true);
   switch (Crosshair.AttachedBox.State)
     {
     case STATE_FIRST:		/* setup first point */
@@ -958,7 +958,7 @@ NotifyBlock (void)
       Crosshair.AttachedBox.State = STATE_THIRD;
       break;
     }
-  RestoreCrosshair (True);
+  RestoreCrosshair (true);
 }
 
 
@@ -984,7 +984,7 @@ NotifyMode (void)
 	int test;
 	hidval hv;
 
-	Note.Click = True;
+	Note.Click = true;
 	/* do something after click time */
 	gui->add_timer (click_cb, CLICK_TIME, hv);
 
@@ -1006,7 +1006,7 @@ NotifyMode (void)
 	      }
 	    if (!Note.Moving && (type & SELECT_TYPES) &&
 		TEST_FLAG (SELECTEDFLAG, (PinTypePtr) ptr2))
-	      Note.Moving = True;
+	      Note.Moving = true;
 	    if ((Note.Hit && Note.Moving) || type == NO_TYPE)
 	      break;
 	  }
@@ -1474,7 +1474,7 @@ NotifyMode (void)
 	      }
 	  }
 	if (CopyPastebufferToLayout (Note.X, Note.Y))
-	  SetChangedFlag (True);
+	  SetChangedFlag (true);
 	if (e)
 	  {
 	    int type =
@@ -1539,7 +1539,7 @@ NotifyMode (void)
 	    }
 	  RemoveObject (type, ptr1, ptr2, ptr3);
 	  IncrementUndoSerialNumber ();
-	  SetChangedFlag (True);
+	  SetChangedFlag (true);
 	}
       break;
 
@@ -1598,9 +1598,9 @@ NotifyMode (void)
 				       Crosshair.AttachedObject.Ptr3,
 				       Note.X - Crosshair.AttachedObject.X,
 				       Note.Y - Crosshair.AttachedObject.Y);
-	      SetLocalRef (0, 0, False);
+	      SetLocalRef (0, 0, false);
 	    }
-	  SetChangedFlag (True);
+	  SetChangedFlag (true);
 
 	  /* reset identifiers */
 	  Crosshair.AttachedObject.Type = NO_TYPE;
@@ -1659,14 +1659,14 @@ NotifyMode (void)
 	    InsertPointIntoObject (POLYGON_TYPE,
 				   Crosshair.AttachedObject.Ptr1, fake.poly,
 				   &polyIndex,
-				   InsertedPoint.X, InsertedPoint.Y, False);
+				   InsertedPoint.X, InsertedPoint.Y, false);
 	  else
 	    InsertPointIntoObject (Crosshair.AttachedObject.Type,
 				   Crosshair.AttachedObject.Ptr1,
 				   Crosshair.AttachedObject.Ptr2,
 				   &polyIndex,
-				   InsertedPoint.X, InsertedPoint.Y, False);
-	  SetChangedFlag (True);
+				   InsertedPoint.X, InsertedPoint.Y, false);
+	  SetChangedFlag (true);
 
 	  /* reset identifiers */
 	  Crosshair.AttachedObject.Type = NO_TYPE;
@@ -1773,7 +1773,7 @@ ActionDRCheck (int argc, char **argv, int x, int y)
 	       PCB->minDrill / 100, PCB->minDrill % 100,
 	       PCB->minRing / 100, PCB->minRing % 100);
     }
-  HideCrosshair (True);
+  HideCrosshair (true);
   count = DRCAll ();
   if (gui->drc_gui == NULL || gui->drc_gui->log_drc_overview)
     {
@@ -1784,7 +1784,7 @@ ActionDRCheck (int argc, char **argv, int x, int y)
       else
 	Message (_("Aborted DRC after %d design rule errors.\n"), -count);
     }
-  RestoreCrosshair (True);
+  RestoreCrosshair (true);
   return 0;
 }
 
@@ -1869,7 +1869,7 @@ ActionFlip (int argc, char **argv, int x, int y)
 
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -1890,7 +1890,7 @@ ActionFlip (int argc, char **argv, int x, int y)
 	  err = 1;
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
       if (!err)
 	return 0;
     }
@@ -1974,10 +1974,10 @@ ActionSetThermal (int argc, char **argv, int x, int y)
 
   if (function && *function && style && *style)
     {
-      Boolean absolute;
+      bool absolute;
 
       kind = GetValue (style, NULL, &absolute);
-      HideCrosshair (True);
+      HideCrosshair (true);
       if (absolute)
 	switch (GetFunctionID (function))
 	  {
@@ -2007,7 +2007,7 @@ ActionSetThermal (int argc, char **argv, int x, int y)
 	  }
       else
 	err = 1;
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
       if (!err)
 	return 0;
     }
@@ -2034,11 +2034,11 @@ ActionMovePointer (char *deltax, char *deltay)
   /* restore crosshair for erasure */
   Crosshair.X = x;
   Crosshair.Y = y;
-  HideCrosshair (False);
+  HideCrosshair (false);
   MoveCrosshairRelative (TO_SCREEN_SIGN_X (dx), TO_SCREEN_SIGN_Y (dy));
   /* update object position and cursor location */
   AdjustAttachedObjects ();
-  RestoreCrosshair (False);
+  RestoreCrosshair (false);
 }
 
 /* ---------------------------------------------------------------------------
@@ -2067,11 +2067,11 @@ EventMoveCrosshair (int ev_x, int ev_y)
 
 	  /* update object position and cursor location */
 	  AdjustAttachedObjects ();
-	  RestoreCrosshair (False);
+	  RestoreCrosshair (false);
 	}
     }
   else
-    IgnoreMotionEvents = False;
+    IgnoreMotionEvents = false;
 }
 
 /* --------------------------------------------------------------------------- */
@@ -2114,19 +2114,19 @@ ActionSetValue (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *val = ARG (1);
   char *units = ARG (2);
-  Boolean r;			/* flag for 'relative' value */
+  bool r;			/* flag for 'relative' value */
   float value;
   int err = 0;
 
   if (function && val)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       value = GetValue (val, units, &r);
       switch (GetFunctionID (function))
 	{
 	case F_ViaDrillingHole:
 	  SetViaDrillingHole (r ? value : value + Settings.ViaDrillingHole,
-			      False);
+			      false);
 	  hid_action ("RouteStylesChanged");
 	  break;
 
@@ -2142,11 +2142,11 @@ ActionSetValue (int argc, char **argv, int x, int y)
 		   * PCB drawing unit 
 		   */
                   if ((value + PCB->Grid) < 1)
-                     SetGrid (1, False);
+                     SetGrid (1, false);
                   else if (PCB->Grid == 1)
-                    SetGrid ( value, False);
+                    SetGrid ( value, false);
                   else
-                    SetGrid (value + PCB->Grid, False);
+                    SetGrid (value + PCB->Grid, false);
                 }
 
 	      else
@@ -2154,7 +2154,7 @@ ActionSetValue (int argc, char **argv, int x, int y)
 			 ("Don't combine metric/English grids like that!\n"));
 	    }
 	  else
-	    SetGrid (value, False);
+	    SetGrid (value, false);
 	  break;
 
 	case F_LineSize:
@@ -2165,7 +2165,7 @@ ActionSetValue (int argc, char **argv, int x, int y)
 
 	case F_Via:
 	case F_ViaSize:
-	  SetViaSize (r ? value : value + Settings.ViaThickness, False);
+	  SetViaSize (r ? value : value + Settings.ViaThickness, false);
 	  hid_action ("RouteStylesChanged");
 	  break;
 
@@ -2178,7 +2178,7 @@ ActionSetValue (int argc, char **argv, int x, int y)
 	  err = 1;
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
       if (!err)
 	return 0;
     }
@@ -2255,32 +2255,32 @@ ActionConnection (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Find:
 	  {
 	    gui->get_coords (_("Click on a connection"), &x, &y);
-	    LookupConnection (x, y, True, 1, FOUNDFLAG);
+	    LookupConnection (x, y, true, 1, FOUNDFLAG);
 	    break;
 	  }
 
 	case F_ResetLinesAndPolygons:
-	  ResetFoundLinesAndPolygons (True);
+	  ResetFoundLinesAndPolygons (true);
 	  break;
 
 	case F_ResetPinsViasAndPads:
-	  ResetFoundPinsViasAndPads (True);
+	  ResetFoundPinsViasAndPads (true);
 	  break;
 
 	case F_Reset:
 	  SaveUndoSerialNumber ();
-	  ResetFoundPinsViasAndPads (True);
+	  ResetFoundPinsViasAndPads (true);
 	  RestoreUndoSerialNumber ();
-	  ResetFoundLinesAndPolygons (True);
+	  ResetFoundLinesAndPolygons (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
       return 0;
     }
 
@@ -2407,7 +2407,7 @@ ActionDisperseElements (int argc, char **argv, int x, int y)
   IncrementUndoSerialNumber ();
 
   ClearAndRedrawOutput ();
-  SetChangedFlag (True);
+  SetChangedFlag (true);
 
   return 0;
 }
@@ -2559,7 +2559,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 
   if (function && (!str_dir || !*str_dir))
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (id = GetFunctionID (function))
 	{
 
@@ -2691,12 +2691,12 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	  if (TEST_FLAG (AUTODRCFLAG, PCB) && Settings.Mode == LINE_MODE)
 	    {
 	      SaveUndoSerialNumber ();
-	      ResetFoundPinsViasAndPads (True);
+	      ResetFoundPinsViasAndPads (true);
 	      RestoreUndoSerialNumber ();
-	      ResetFoundLinesAndPolygons (True);
+	      ResetFoundLinesAndPolygons (true);
 	      if (Crosshair.AttachedLine.State != STATE_FIRST)
 		LookupConnection (Crosshair.AttachedLine.Point1.X,
-				  Crosshair.AttachedLine.Point1.Y, True, 1,
+				  Crosshair.AttachedLine.Point1.Y, true, 1,
 				  FOUNDFLAG);
 	    }
 	  break;
@@ -2736,8 +2736,8 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	    oldGrid = PCB->Grid;
 	    PCB->Grid = 1.0;
 	    if (MoveCrosshairAbsolute (childX, childY))
-	      RestoreCrosshair (False);	/* was hidden by MoveCrosshairAbs */
-	    SetGrid (oldGrid, True);
+	      RestoreCrosshair (false);	/* was hidden by MoveCrosshairAbs */
+	    SetGrid (oldGrid, true);
 	  }
 	  break;
 
@@ -2796,7 +2796,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 		  TOGGLE_FLAG (DISPLAYNAMEFLAG, pad);
 		}
 		END_LOOP;
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		IncrementUndoSerialNumber ();
 		Draw ();
 		break;
@@ -2808,7 +2808,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 		  DrawPinName ((PinTypePtr) ptr2, 0);
 		AddObjectToFlagUndoList (PIN_TYPE, ptr1, ptr2, ptr3);
 		TOGGLE_FLAG (DISPLAYNAMEFLAG, (PinTypePtr) ptr2);
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		IncrementUndoSerialNumber ();
 		Draw ();
 		break;
@@ -2820,7 +2820,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 		  DrawPadName ((PadTypePtr) ptr2, 0);
 		AddObjectToFlagUndoList (PAD_TYPE, ptr1, ptr2, ptr3);
 		TOGGLE_FLAG (DISPLAYNAMEFLAG, (PadTypePtr) ptr2);
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		IncrementUndoSerialNumber ();
 		Draw ();
 		break;
@@ -2831,7 +2831,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 		  DrawViaName ((PinTypePtr) ptr2, 0);
 		AddObjectToFlagUndoList (VIA_TYPE, ptr1, ptr2, ptr3);
 		TOGGLE_FLAG (DISPLAYNAMEFLAG, (PinTypePtr) ptr2);
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		IncrementUndoSerialNumber ();
 		Draw ();
 		break;
@@ -2841,7 +2841,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	default:
 	  err = 1;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   else if (function && str_dir)
     {
@@ -2940,7 +2940,7 @@ ActionMode (int argc, char **argv, int x, int y)
     {
       Note.X = Crosshair.X;
       Note.Y = Crosshair.Y;
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Arc:
@@ -3074,7 +3074,7 @@ ActionMode (int argc, char **argv, int x, int y)
 	  break;
 	case F_Stroke:
 #ifdef HAVE_LIBSTROKE
-	  mid_stroke = True;
+	  mid_stroke = true;
 	  StrokeBox.X1 = Crosshair.X;
 	  StrokeBox.Y1 = Crosshair.Y;
 	  break;
@@ -3099,7 +3099,7 @@ ActionMode (int argc, char **argv, int x, int y)
 	  else
 	    {
 	      SaveMode ();
-	      saved_mode = True;
+	      saved_mode = true;
 	      SetMode (ARROW_MODE);
 	      NotifyMode ();
 	    }
@@ -3123,7 +3123,7 @@ ActionMode (int argc, char **argv, int x, int y)
 	  SaveMode ();
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
       return 0;
     }
 
@@ -3143,10 +3143,10 @@ static const char removeselected_help[] = "Removes any selected objects.";
 static int
 ActionRemoveSelected (int argc, char **argv, int x, int y)
 {
-  HideCrosshair (True);
+  HideCrosshair (true);
   if (RemoveSelected ())
-    SetChangedFlag (True);
-  RestoreCrosshair (True);
+    SetChangedFlag (true);
+  RestoreCrosshair (true);
   return 0;
 }
 
@@ -3165,7 +3165,7 @@ static const char renumber_help[] =
 static int
 ActionRenumber (int argc, char **argv, int x, int y)
 {
-  Boolean changed = False;
+  bool changed = false;
   ElementTypePtr *element_list;
   ElementTypePtr *locked_element_list;
   unsigned int i, j, k, cnt, lock_cnt;
@@ -3425,7 +3425,7 @@ ActionRenumber (int argc, char **argv, int x, int y)
 
 	      ChangeObjectName (ELEMENT_TYPE, element_list[i], NULL, NULL,
 				tmps);
-	      changed = True;
+	      changed = true;
 
 	      /* we don't free tmps in this case because it is used */
 	    }
@@ -3496,7 +3496,7 @@ ActionRenumber (int argc, char **argv, int x, int y)
 
       NetlistChanged (0);
       IncrementUndoSerialNumber ();
-      SetChangedFlag (True);
+      SetChangedFlag (true);
     }
 
   free (locked_element_list);
@@ -3536,11 +3536,11 @@ static int
 ActionRipUp (int argc, char **argv, int x, int y)
 {
   char *function = ARG (0);
-  Boolean changed = False;
+  bool changed = false;
 
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_All:
@@ -3549,7 +3549,7 @@ ActionRipUp (int argc, char **argv, int x, int y)
 	    if (TEST_FLAG (AUTOFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
 	      {
 		RemoveObject (LINE_TYPE, layer, line, line);
-		changed = True;
+		changed = true;
 	      }
 	  }
 	  ENDALL_LOOP;
@@ -3558,7 +3558,7 @@ ActionRipUp (int argc, char **argv, int x, int y)
 	    if (TEST_FLAG (AUTOFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
 	      {
 		RemoveObject (VIA_TYPE, via, via, via);
-		changed = True;
+		changed = true;
 	      }
 	  }
 	  END_LOOP;
@@ -3566,7 +3566,7 @@ ActionRipUp (int argc, char **argv, int x, int y)
 	  if (changed)
 	    {
 	      IncrementUndoSerialNumber ();
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	    }
 	  break;
 	case F_Selected:
@@ -3576,7 +3576,7 @@ ActionRipUp (int argc, char **argv, int x, int y)
 		&& !TEST_FLAG (LOCKFLAG, line))
 	      {
 		RemoveObject (LINE_TYPE, layer, line, line);
-		changed = True;
+		changed = true;
 	      }
 	  }
 	  ENDALL_LOOP;
@@ -3587,14 +3587,14 @@ ActionRipUp (int argc, char **argv, int x, int y)
 		&& !TEST_FLAG (LOCKFLAG, via))
 	      {
 		RemoveObject (VIA_TYPE, via, via, via);
-		changed = True;
+		changed = true;
 	      }
 	  }
 	  END_LOOP;
 	  if (changed)
 	    {
 	      IncrementUndoSerialNumber ();
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	    }
 	  break;
 	case F_Element:
@@ -3618,12 +3618,12 @@ ActionRipUp (int argc, char **argv, int x, int y)
 		RestoreUndoSerialNumber ();
 		CopyPastebufferToLayout (0, 0);
 		SetBufferNumber (Note.Buffer);
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	      }
 	  }
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -3664,17 +3664,17 @@ ActionAddRats (int argc, char **argv, int x, int y)
     {
       if (Settings.RatWarn)
 	ClearWarnings ();
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_AllRats:
-	  if (AddAllRats (False, NULL))
-	    SetChangedFlag (True);
+	  if (AddAllRats (false, NULL))
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedRats:
 	case F_Selected:
-	  if (AddAllRats (True, NULL))
-	    SetChangedFlag (True);
+	  if (AddAllRats (true, NULL))
+	    SetChangedFlag (true);
 	  break;
 	case F_Close:
 	  small = SQUARE (MAX_COORD);
@@ -3700,11 +3700,11 @@ ActionAddRats (int argc, char **argv, int x, int y)
 	      Draw ();
 	      CenterDisplay ((shorty->Point2.X + shorty->Point1.X) / 2,
 			     (shorty->Point2.Y + shorty->Point1.Y) / 2,
-			     False);
+			     false);
 	    }
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -3733,11 +3733,11 @@ ActionDelete (int argc, char **argv, int x, int y)
 
   if (id == -1) /* no arg */
     {
-      if (RemoveSelected() == False)
+      if (RemoveSelected() == false)
 	id = F_Object;
     }
 
-  HideCrosshair (True);
+  HideCrosshair (true);
   switch (id)
     {
     case F_Object:
@@ -3750,16 +3750,16 @@ ActionDelete (int argc, char **argv, int x, int y)
       RemoveSelected();
       break;
     case F_AllRats:
-      if (DeleteRats (False))
-	SetChangedFlag (True);
+      if (DeleteRats (false))
+	SetChangedFlag (true);
       break;
     case F_SelectedRats:
-      if (DeleteRats (True))
-	SetChangedFlag (True);
+      if (DeleteRats (true))
+	SetChangedFlag (true);
       break;
     }
 
-  RestoreCrosshair (True);
+  RestoreCrosshair (true);
   return 0;
 }
 
@@ -3782,20 +3782,20 @@ ActionDeleteRats (int argc, char **argv, int x, int y)
     {
       if (Settings.RatWarn)
 	ClearWarnings ();
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_AllRats:
-	  if (DeleteRats (False))
-	    SetChangedFlag (True);
+	  if (DeleteRats (false))
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedRats:
 	case F_Selected:
-	  if (DeleteRats (True))
-	    SetChangedFlag (True);
+	  if (DeleteRats (true))
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -3820,10 +3820,10 @@ ActionAutoPlaceSelected (int argc, char **argv, int x, int y)
   if (gui->confirm_dialog (_("Auto-placement can NOT be undone.\n"
 			     "Do you want to continue anyway?\n"), 0))
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       if (AutoPlaceSelected ())
-	SetChangedFlag (True);
-      RestoreCrosshair (True);
+	SetChangedFlag (true);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -3864,20 +3864,20 @@ ActionAutoRoute (int argc, char **argv, int x, int y)
   hid_action("Busy");
   if (function)			/* one parameter */
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_AllRats:
-	  if (AutoRoute (False))
-	    SetChangedFlag (True);
+	  if (AutoRoute (false))
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedRats:
 	case F_Selected:
-	  if (AutoRoute (True))
-	    SetChangedFlag (True);
+	  if (AutoRoute (true))
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -3911,24 +3911,24 @@ ActionMarkCrosshair (int argc, char **argv, int x, int y)
     {
       if (Marked.status)
 	{
-	  DrawMark (True);
-	  Marked.status = False;
+	  DrawMark (true);
+	  Marked.status = false;
 	}
       else
 	{
-	  Marked.status = True;
+	  Marked.status = true;
 	  Marked.X = Crosshair.X;
 	  Marked.Y = Crosshair.Y;
-	  DrawMark (False);
+	  DrawMark (false);
 	}
     }
   else if (GetFunctionID (function) == F_Center)
     {
-      DrawMark (True);
-      Marked.status = True;
+      DrawMark (true);
+      Marked.status = true;
       Marked.X = Crosshair.X;
       Marked.Y = Crosshair.Y;
-      DrawMark (False);
+      DrawMark (false);
     }
   return 0;
 }
@@ -3960,13 +3960,13 @@ ActionChangeSize (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *delta = ARG (1);
   char *units = ARG (2);
-  Boolean r;			/* indicates if absolute size is given */
+  bool r;			/* indicates if absolute size is given */
   float value;
 
   if (function && delta)
     {
       value = GetValue (delta, units, &r);
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -3980,57 +3980,57 @@ ActionChangeSize (int argc, char **argv, int x, int y)
 	      if (TEST_FLAG (LOCKFLAG, (PinTypePtr) ptr2))
 		Message (_("Sorry, the object is locked\n"));
 	    if (ChangeObjectSize (type, ptr1, ptr2, ptr3, value, r))
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedVias:
 	  if (ChangeSelectedSize (VIA_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ChangeSelectedSize (PIN_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPads:
 	  if (ChangeSelectedSize (PAD_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedArcs:
 	  if (ChangeSelectedSize (ARC_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedLines:
 	  if (ChangeSelectedSize (LINE_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedTexts:
 	  if (ChangeSelectedSize (TEXT_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedNames:
 	  if (ChangeSelectedSize (ELEMENTNAME_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedElements:
 	  if (ChangeSelectedSize (ELEMENT_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelectedSize (CHANGESIZE_TYPES, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4054,13 +4054,13 @@ ActionChange2ndSize (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *delta = ARG (1);
   char *units = ARG (2);
-  Boolean r;
+  bool r;
   float value;
 
   if (function && delta)
     {
       value = GetValue (delta, units, &r);
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -4073,27 +4073,27 @@ ActionChange2ndSize (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGE2NDSIZE_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ChangeObject2ndSize
-		  (type, ptr1, ptr2, ptr3, value, r, True))
-		SetChangedFlag (True);
+		  (type, ptr1, ptr2, ptr3, value, r, true))
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedVias:
 	  if (ChangeSelected2ndSize (VIA_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ChangeSelected2ndSize (PIN_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelected2ndSize (PIN_TYPES, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4123,13 +4123,13 @@ ActionChangeClearSize (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *delta = ARG (1);
   char *units = ARG (2);
-  Boolean r;
+  bool r;
   float value;
 
   if (function && delta)
     {
       value = 2 * GetValue (delta, units, &r);
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -4143,36 +4143,36 @@ ActionChangeClearSize (int argc, char **argv, int x, int y)
 			       CHANGECLEARSIZE_TYPES, &ptr1, &ptr2,
 			       &ptr3)) != NO_TYPE)
 	      if (ChangeObjectClearSize (type, ptr1, ptr2, ptr3, value, r))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 	case F_SelectedVias:
 	  if (ChangeSelectedClearSize (VIA_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedPads:
 	  if (ChangeSelectedClearSize (PAD_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedPins:
 	  if (ChangeSelectedClearSize (PIN_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedLines:
 	  if (ChangeSelectedClearSize (LINE_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_SelectedArcs:
 	  if (ChangeSelectedClearSize (ARC_TYPE, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelectedClearSize (CHANGECLEARSIZE_TYPES, value, r))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4199,7 +4199,7 @@ ActionMinMaskGap (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *delta = ARG (1);
   char *units = ARG (2);
-  Boolean r;
+  bool r;
   int value;
   int flags;
 
@@ -4215,7 +4215,7 @@ ActionMinMaskGap (int argc, char **argv, int x, int y)
     }
   value = 2 * GetValue (delta, units, &r);
 
-  HideCrosshair (True);
+  HideCrosshair (true);
   SaveUndoSerialNumber ();
   ELEMENT_LOOP (PCB->Data);
   {
@@ -4283,7 +4283,7 @@ ActionMinClearGap (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   char *delta = ARG (1);
   char *units = ARG (2);
-  Boolean r;
+  bool r;
   int value;
   int flags;
 
@@ -4299,7 +4299,7 @@ ActionMinClearGap (int argc, char **argv, int x, int y)
     }
   value = 2 * GetValue (delta, units, &r);
 
-  HideCrosshair (True);
+  HideCrosshair (true);
   SaveUndoSerialNumber ();
   ELEMENT_LOOP (PCB->Data);
   {
@@ -4417,7 +4417,7 @@ ActionChangePinName (int argc, char **argv, int x, int y)
 	       * it is used in the undo list
 	       */
 	      pin->Name = strdup (pinname);
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	      changed = 1;
 	    }
 	}
@@ -4434,7 +4434,7 @@ ActionChangePinName (int argc, char **argv, int x, int y)
 	       * it is used in the undo list
 	       */
 	      pad->Name = strdup (pinname);
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	      changed = 1;
 	    }
 	}
@@ -4492,7 +4492,7 @@ ActionChangeName (int argc, char **argv, int x, int y)
 
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	  /* change the name of an object */
@@ -4509,7 +4509,7 @@ ActionChangeName (int argc, char **argv, int x, int y)
 		SaveUndoSerialNumber ();
 		if (QueryInputAndChangeObjectName (type, ptr1, ptr2, ptr3))
 		  {
-		    SetChangedFlag (True);
+		    SetChangedFlag (true);
 		    if (type == ELEMENT_TYPE)
 		      {
 			RubberbandTypePtr ptr;
@@ -4541,7 +4541,7 @@ ActionChangeName (int argc, char **argv, int x, int y)
 	  name =
 	    gui->prompt_for (_("Enter the layout name:"), EMPTY (PCB->Name));
 	  if (name && ChangeLayoutName (name))	/* XXX memory leak */
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	  /* change the name of the active layer */
@@ -4549,10 +4549,10 @@ ActionChangeName (int argc, char **argv, int x, int y)
 	  name = gui->prompt_for (_("Enter the layer name:"),
 				  EMPTY (CURRENT->Name));
 	  if (name && ChangeLayerName (CURRENT, name))	/* XXX memory leak */
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4581,7 +4581,7 @@ ActionMorphPolygon (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -4636,7 +4636,7 @@ ActionToggleHideName (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function && PCB->ElementOn)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_Object:
@@ -4660,7 +4660,7 @@ ActionToggleHideName (int argc, char **argv, int x, int y)
 	case F_SelectedElements:
 	case F_Selected:
 	  {
-	    Boolean changed = False;
+	    bool changed = false;
 	    ELEMENT_LOOP (PCB->Data);
 	    {
 	      if ((TEST_FLAG (SELECTEDFLAG, element) ||
@@ -4673,7 +4673,7 @@ ActionToggleHideName (int argc, char **argv, int x, int y)
 		  EraseElementName (element);
 		  TOGGLE_FLAG (HIDENAMEFLAG, element);
 		  DrawElementName (element, 0);
-		  changed = True;
+		  changed = true;
 		}
 	    }
 	    END_LOOP;
@@ -4684,7 +4684,7 @@ ActionToggleHideName (int argc, char **argv, int x, int y)
 	      }
 	  }
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4713,7 +4713,7 @@ ActionChangeJoin (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -4727,27 +4727,27 @@ ActionChangeJoin (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGEJOIN_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ChangeObjectJoin (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedLines:
 	  if (ChangeSelectedJoin (LINE_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedArcs:
 	  if (ChangeSelectedJoin (ARC_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelectedJoin (CHANGEJOIN_TYPES))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4776,7 +4776,7 @@ ActionChangeSquare (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -4790,27 +4790,27 @@ ActionChangeSquare (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGESQUARE_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ChangeObjectSquare (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (ChangeSelectedSquare (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ChangeSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -4836,7 +4836,7 @@ ActionSetSquare (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function && *function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -4850,27 +4850,27 @@ ActionSetSquare (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGESQUARE_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (SetObjectSquare (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (SetSelectedSquare (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (SetSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (SetSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -4897,7 +4897,7 @@ ActionClearSquare (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function && *function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -4911,27 +4911,27 @@ ActionClearSquare (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGESQUARE_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ClrObjectSquare (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (ClrSelectedSquare (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ClrSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ClrSelectedSquare (PIN_TYPE | PAD_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -4957,7 +4957,7 @@ ActionChangeOctagon (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -4971,32 +4971,32 @@ ActionChangeOctagon (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGEOCTAGON_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ChangeObjectOctagon (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (ChangeSelectedOctagon (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ChangeSelectedOctagon (PIN_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedVias:
 	  if (ChangeSelectedOctagon (VIA_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ChangeSelectedOctagon (PIN_TYPES))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -5020,7 +5020,7 @@ ActionSetOctagon (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -5034,32 +5034,32 @@ ActionSetOctagon (int argc, char **argv, int x, int y)
 		 SearchScreen (x, y, CHANGEOCTAGON_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (SetObjectOctagon (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (SetSelectedOctagon (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (SetSelectedOctagon (PIN_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedVias:
 	  if (SetSelectedOctagon (VIA_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (SetSelectedOctagon (PIN_TYPES))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -5085,7 +5085,7 @@ ActionClearOctagon (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -5099,32 +5099,32 @@ ActionClearOctagon (int argc, char **argv, int x, int y)
 		 SearchScreen (Crosshair.X, Crosshair.Y, CHANGEOCTAGON_TYPES,
 			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
 	      if (ClrObjectOctagon (type, ptr1, ptr2, ptr3))
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 	    break;
 	  }
 
 	case F_SelectedElements:
 	  if (ClrSelectedOctagon (ELEMENT_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedPins:
 	  if (ClrSelectedOctagon (PIN_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_SelectedVias:
 	  if (ClrSelectedOctagon (VIA_TYPE))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	case F_Selected:
 	case F_SelectedObjects:
 	  if (ClrSelectedOctagon (PIN_TYPES))
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -5149,7 +5149,7 @@ ActionChangeHole (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -5169,10 +5169,10 @@ ActionChangeHole (int argc, char **argv, int x, int y)
 	case F_SelectedVias:
 	case F_Selected:
 	  if (ChangeSelectedHole ())
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -5199,7 +5199,7 @@ ActionChangePaste (int argc, char **argv, int x, int y)
   char *function = ARG (0);
   if (function)
     {
-      /* HideCrosshair (True); */
+      /* HideCrosshair (true); */
       switch (GetFunctionID (function))
 	{
 	case F_ToggleObject:
@@ -5219,10 +5219,10 @@ ActionChangePaste (int argc, char **argv, int x, int y)
 	case F_SelectedPads:
 	case F_Selected:
 	  if (ChangeSelectedPaste ())
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 	}
-      /* RestoreCrosshair (True); */
+      /* RestoreCrosshair (true); */
     }
   return 0;
 }
@@ -5283,7 +5283,7 @@ ActionSelect (int argc, char **argv, int x, int y)
   if (function)
     {
 
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
@@ -5316,8 +5316,8 @@ ActionSelect (int argc, char **argv, int x, int y)
 		|| (pattern =
 		    gui->prompt_for (_("Enter pattern:"), "")) != NULL)
 	      {
-		if (SelectObjectByName (type, pattern, True))
-		  SetChangedFlag (True);
+		if (SelectObjectByName (type, pattern, true))
+		  SetChangedFlag (true);
 		if (ARG (1) == 0)
 		  free (pattern);
 	      }
@@ -5329,7 +5329,7 @@ ActionSelect (int argc, char **argv, int x, int y)
 	case F_ToggleObject:
 	case F_Object:
 	  if (SelectObject ())
-	    SetChangedFlag (True);
+	    SetChangedFlag (true);
 	  break;
 
 	  /* all objects in block */
@@ -5347,9 +5347,9 @@ ActionSelect (int argc, char **argv, int x, int y)
 			  Crosshair.AttachedBox.Point2.Y);
 	    NotifyBlock ();
 	    if (Crosshair.AttachedBox.State == STATE_THIRD &&
-		SelectBlock (&box, True))
+		SelectBlock (&box, true))
 	      {
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		Crosshair.AttachedBox.State = STATE_FIRST;
 	      }
 	    break;
@@ -5364,17 +5364,17 @@ ActionSelect (int argc, char **argv, int x, int y)
 	    box.Y1 = -MAX_COORD;
 	    box.X2 = MAX_COORD;
 	    box.Y2 = MAX_COORD;
-	    if (SelectBlock (&box, True))
-	      SetChangedFlag (True);
+	    if (SelectBlock (&box, true))
+	      SetChangedFlag (true);
 	    break;
 	  }
 
 	  /* all found connections */
 	case F_Connection:
-	  if (SelectConnection (True))
+	  if (SelectConnection (true))
 	    {
 	      IncrementUndoSerialNumber ();
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	    }
 	  break;
 
@@ -5387,7 +5387,7 @@ ActionSelect (int argc, char **argv, int x, int y)
 	    gui->get_coords (_("Select the Element's Mark Location"), &x, &y);
 	    x = GRIDFIT_X (x, PCB->Grid);
 	    y = GRIDFIT_Y (y, PCB->Grid);
-	    AddSelectedToBuffer (PASTEBUFFER, x, y, True);
+	    AddSelectedToBuffer (PASTEBUFFER, x, y, true);
 	    SaveUndoSerialNumber ();
 	    RemoveSelected ();
 	    ConvertBufferToElement (PASTEBUFFER);
@@ -5398,11 +5398,11 @@ ActionSelect (int argc, char **argv, int x, int y)
 	  break;
 
 	default:
-	  RestoreCrosshair (True);
+	  RestoreCrosshair (true);
 	  AFAIL (select);
 	  break;
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -5466,7 +5466,7 @@ ActionUnselect (int argc, char **argv, int x, int y)
 
   if (function)
     {
-      HideCrosshair (True);
+      HideCrosshair (true);
       switch (GetFunctionID (function))
 	{
 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
@@ -5499,8 +5499,8 @@ ActionUnselect (int argc, char **argv, int x, int y)
 		|| (pattern =
 		    gui->prompt_for (_("Enter pattern:"), "")) != NULL)
 	      {
-		if (SelectObjectByName (type, pattern, False))
-		  SetChangedFlag (True);
+		if (SelectObjectByName (type, pattern, false))
+		  SetChangedFlag (true);
 		if (ARG (1) == 0)
 		  free (pattern);
 	      }
@@ -5523,9 +5523,9 @@ ActionUnselect (int argc, char **argv, int x, int y)
 			  Crosshair.AttachedBox.Point2.Y);
 	    NotifyBlock ();
 	    if (Crosshair.AttachedBox.State == STATE_THIRD &&
-		SelectBlock (&box, False))
+		SelectBlock (&box, false))
 	      {
-		SetChangedFlag (True);
+		SetChangedFlag (true);
 		Crosshair.AttachedBox.State = STATE_FIRST;
 	      }
 	    break;
@@ -5540,27 +5540,27 @@ ActionUnselect (int argc, char **argv, int x, int y)
 	    box.Y1 = -MAX_COORD;
 	    box.X2 = MAX_COORD;
 	    box.Y2 = MAX_COORD;
-	    if (SelectBlock (&box, False))
-	      SetChangedFlag (True);
+	    if (SelectBlock (&box, false))
+	      SetChangedFlag (true);
 	    break;
 	  }
 
 	  /* all found connections */
 	case F_Connection:
-	  if (SelectConnection (False))
+	  if (SelectConnection (false))
 	    {
 	      IncrementUndoSerialNumber ();
-	      SetChangedFlag (True);
+	      SetChangedFlag (true);
 	    }
 	  break;
 
 	default:
-	  RestoreCrosshair (True);
+	  RestoreCrosshair (true);
 	  AFAIL (unselect);
 	  break;
 
 	}
-      RestoreCrosshair (True);
+      RestoreCrosshair (true);
     }
   return 0;
 }
@@ -5629,12 +5629,12 @@ ActionSaveTo (int argc, char **argv, int x, int y)
   if (strcasecmp (function, "AllConnections") == 0)
     {
       FILE *fp;
-      Boolean result;
-      if ((fp = CheckAndOpenFile (name, True, False, &result, NULL)) != NULL)
+      bool result;
+      if ((fp = CheckAndOpenFile (name, true, false, &result, NULL)) != NULL)
 	{
 	  LookupConnectionsToAllElements (fp);
 	  ...
 
[truncated message content] | 
| 
      
      
      From: <gi...@gp...> - 2010-06-03 22:34:34
      
     | 
| The branch, master has been updated
       via  fa761a714fc916db435d36e1f873a6fb1b8fb012 (commit)
      from  480a9aca8ffe79ab08657f62790c41faf87f6e60 (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/file.c    |    2 +-
 src/parse_y.y |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit fa761a714fc916db435d36e1f873a6fb1b8fb012
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Refer to git, not cvs when reading a file from newer PCB.
:100644 100644 639c971... 2704ede... M	src/file.c
:100644 100644 bbb7255... b76e689... M	src/parse_y.y
=========
 Changes
=========
commit fa761a714fc916db435d36e1f873a6fb1b8fb012
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Refer to git, not cvs when reading a file from newer PCB.
diff --git a/src/file.c b/src/file.c
index 639c971..2704ede 100644
--- a/src/file.c
+++ b/src/file.c
@@ -544,7 +544,7 @@ WritePCBDataHeader (FILE * FP)
    * ************************** README *******************
    */
 
-  fprintf (FP, "\n# To read pcb files, the pcb version (or the cvs source date) must be >= the file version\n");
+  fprintf (FP, "\n# To read pcb files, the pcb version (or the git source date) must be >= the file version\n");
   fprintf (FP, "FileVersion[%i]\n", PCB_FILE_VERSION);
 
   fputs ("\nPCB[", FP);
diff --git a/src/parse_y.y b/src/parse_y.y
index bbb7255..b76e689 100644
--- a/src/parse_y.y
+++ b/src/parse_y.y
@@ -1916,7 +1916,7 @@ check_file_version (int ver)
     Message ("ERROR:  The file you are attempting to load is in a format\n"
 	     "which is too new for this version of pcb.  To load this file\n"
 	     "you need a version of pcb which is >= %d.  If you are\n"
-	     "using a version built from cvs sources, the source date\n"
+	     "using a version built from git source, the source date\n"
 	     "must be >= %d.  This copy of pcb can only read files\n"
 	     "up to file version %d.\n", ver, ver, PCB_FILE_VERSION);
     return 1;
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-02 20:45:02
      
     | 
| The branch, master has been updated
       via  480a9aca8ffe79ab08657f62790c41faf87f6e60 (commit)
       via  00547b9e5c9226c70fed4661d5dd151858f27283 (commit)
       via  0c5de87b90a620b22a031c580f0de5d13d60106d (commit)
       via  c1942a989b1464cb909c599e53df1d5e76f38178 (commit)
       via  bd416424854aee73aa97cb1e172359be15a8fded (commit)
       via  1dd0b04518a1aceac01e08f8d1a75618cc93fa32 (commit)
       via  4bd69a615c59a05259f60b39114a55f86f8a6d8c (commit)
       via  44157eecc76efd135f9bfcdb8905644133b7d45a (commit)
       via  3b07dcf01965e7c65a48293b00023edbd8414e96 (commit)
      from  bef0dea06cc86cbca3a0b2d3c8a254b69e5027cc (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
=========
 autogen.sh                       |    6 +
 po/LINGUAS                       |    1 +
 po/POTFILES.in                   |    4 +
 po/ru.po                         | 4691 ++++++++++++++++++++++++++++++++++++++
 src/action.c                     |   76 +-
 src/change.c                     |    4 +-
 src/create.c                     |    4 +-
 src/global.h                     |   19 +-
 src/gpcb-menu.res                |   40 +-
 src/hid/common/actions.c         |    2 +-
 src/hid/gtk/gtkhid-main.c        |   70 +-
 src/hid/gtk/gui-command-window.c |    9 +-
 src/hid/gtk/gui-config.c         |   10 +-
 src/hid/gtk/gui-keyref-window.c  |    2 +-
 src/hid/gtk/gui-top-window.c     |   32 +-
 src/hid/gtk/gui.h                |   21 -
 src/hid/ps/ps.c                  |    2 +-
 src/pcb-menu.res                 |    2 +-
 src/rats.c                       |    2 +-
 19 files changed, 4844 insertions(+), 153 deletions(-)
 create mode 100644 po/ru.po
=================
 Commit Messages
=================
commit 480a9aca8ffe79ab08657f62790c41faf87f6e60
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add Russian translation
:100644 100644 527e861... 2ccede6... M	po/LINGUAS
:000000 100644 0000000... aa7d90c... A	po/ru.po
commit 00547b9e5c9226c70fed4661d5dd151858f27283
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add source files with localized strings to .po generation
:100644 100644 01627a2... 9ef4db5... M	po/POTFILES.in
commit 0c5de87b90a620b22a031c580f0de5d13d60106d
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Adjust punctuation and capitalisation of some messages
:100644 100644 5037bb0... 801d6d7... M	src/hid/gtk/gui-keyref-window.c
:100644 100644 c174cc9... 0e2a068... M	src/rats.c
commit c1942a989b1464cb909c599e53df1d5e76f38178
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add top level menu to localization
:100644 100644 0e678ad... 37e141d... M	src/gpcb-menu.res
commit bd416424854aee73aa97cb1e172359be15a8fded
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    String unification and white space cleanup
    
    String Rip up selected auto-routed tracks unified, so it can be translated
    as one string. Also some white spaces at end of line removed.
:100644 100644 1511e09... 0e678ad... M	src/gpcb-menu.res
:100644 100644 c18eb86... cbdcd2d... M	src/pcb-menu.res
commit 1dd0b04518a1aceac01e08f8d1a75618cc93fa32
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Localize need coord message before output
:100644 100644 9fa129d... d1e87f5... M	src/hid/common/actions.c
commit 4bd69a615c59a05259f60b39114a55f86f8a6d8c
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add strings to localization
:100644 100644 6bbee09... dde6484... M	src/action.c
:100644 100644 4d42bc3... 2fedc52... M	src/change.c
:100644 100644 eced68d... 1a79ae6... M	src/create.c
:100644 100644 90d1485... 05b2c91... M	src/hid/gtk/gtkhid-main.c
:100644 100644 3dfe95e... 15dd6db... M	src/hid/gtk/gui-command-window.c
:100644 100644 c9bf82b... 5e8121b... M	src/hid/gtk/gui-config.c
:100644 100644 e61c9f3... 09a29c1... M	src/hid/gtk/gui-top-window.c
:100644 100644 810ceba... 7b42b5f... M	src/hid/ps/ps.c
commit 44157eecc76efd135f9bfcdb8905644133b7d45a
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Move internationalization macros to one header
:100644 100644 1082dd1... b7c9d0f... M	src/global.h
:100644 100644 610f30e... 0a2e747... M	src/hid/gtk/gui.h
commit 3b07dcf01965e7c65a48293b00023edbd8414e96
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add rule to extract localized stings from .res files
:100755 100755 d1671fb... 3eeeca2... M	autogen.sh
=========
 Changes
=========
commit 480a9aca8ffe79ab08657f62790c41faf87f6e60
Author: Sergey Alyoshin <aly...@gm...>
Commit: Peter Clifton <pc...@ca...>
    Add Russian translation
diff --git a/po/LINGUAS b/po/LINGUAS
index 527e861..2ccede6 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1 +1,2 @@
 fr
+ru
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..aa7d90c
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,4691 @@
+# PCB PO template translation to Russian.
+# Copyright (C) 2009
+# This file is distributed under the same license as the PCB package.
+#
+# Sergey Alyoshin <aly...@gm...>, 2009
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pcb-git\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-05-23 14:25+0400\n"
+"PO-Revision-Date: 2010-04-12 23:34+0400\n"
+"Last-Translator: Sergey Alyoshin <aly...@gm...>\n"
+"Language-Team: LANGUAGE <LL...@li...>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../data/pcb.desktop.in.h:1
+msgid "Create and edit printed circuit board designs"
+msgstr "Создание и ÑедакÑиÑование пÑоекÑов пеÑаÑнÑÑ
 плаÑ"
+
+#: ../data/pcb.desktop.in.h:2
+msgid "PCB Design"
+msgstr "ÐÑÐ¾ÐµÐºÑ PCB"
+
+#: ../data/pcb.desktop.in.h:3
+msgid "PCB Designer"
+msgstr "РедакÑÐ¾Ñ PCB"
+
+#: ../data/pcb.xml.in.h:1 ../data/x-excellon.desktop.in.h:1
+msgid "Excellon drill file"
+msgstr "Файл ÑвеÑловки Excellon"
+
+#: ../data/pcb.xml.in.h:2 ../data/x-gerber.desktop.in.h:1
+msgid "Gerber file"
+msgstr "Gerber-Ñайл"
+
+#: ../data/pcb.xml.in.h:3 ../data/x-pcb-footprint.desktop.in.h:1
+msgid "PCB footprint"
+msgstr "PCB поÑадоÑное меÑÑо"
+
+#: ../data/pcb.xml.in.h:4 ../data/x-pcb-layout.desktop.in.h:1
+msgid "PCB layout"
+msgstr "PCB ÑÑаÑÑиÑовка"
+
+#: ../data/pcb.xml.in.h:5 ../data/x-pcb-netlist.desktop.in.h:1
+msgid "PCB netlist"
+msgstr "PCB ÑпиÑок Ñоединений"
+
+#: ../src/action.c:563
+#, c-format
+msgid "Unknown stroke %s\n"
+msgstr "ÐеизвеÑÑнÑй жеÑÑ %s\n"
+
+#: ../src/action.c:760
+#, c-format
+msgid "Error: function hash size too small (%d vs %lu at %s:%d)\n"
+msgstr ""
+"ÐÑибка: ÑлиÑком маленÑкий ÑÐ°Ð·Ð¼ÐµÑ Ñ
еÑа ÑÑнкÑии (%d пÑоÑив %lu в %s:%d)\n"
+
+#. Change 'char' to 'int' and remove this when we get to 256
+#. strings to hash.
+#: ../src/action.c:768
+#, c-format
+msgid "Error: function hash type too small (%d vs %lu at %s:%d)\n"
+msgstr "ÐÑибка: ÑлиÑком маленÑкий Ñип Ñ
еÑа ÑÑнкÑии (%d пÑоÑив %lu в %s:%d)\n"
+
+#: ../src/action.c:1022
+msgid ""
+"You must turn via visibility on before\n"
+"you can place vias\n"
+msgstr ""
+"ÐеобÑ
одимо вклÑÑиÑÑ Ð¾ÑобÑажение пеÑеÑ
одов\n"
+"пеÑед Ñем как иÑ
 ÑазмеÑаÑÑ\n"
+
+#: ../src/action.c:1388 ../src/change.c:2273
+msgid "Enter text:"
+msgstr "ТекÑÑ:"
+
+#: ../src/action.c:1516 ../src/action.c:1575 ../src/action.c:1629
+#: ../src/action.c:3981 ../src/action.c:6689 ../src/move.c:490
+#: ../src/move.c:581 ../src/move.c:681 ../src/move.c:758 ../src/rotate.c:434
+msgid "Sorry, the object is locked\n"
+msgstr "ÐбÑÐµÐºÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñован\n"
+
+#: ../src/action.c:1766
+#, c-format
+msgid ""
+"Rules are minspace %d.%02d, minoverlap %d.%d minwidth %d.%02d, minsilk %d.%"
+"02d\n"
+"min drill %d.%02d, min annular ring %d.%02d\n"
+msgstr ""
+"ÐоÑмÑ: мин.Ð·Ð°Ð·Ð¾Ñ %d.%02d, мин.пеÑекÑÑÑие %d.%d, мин.ÑолÑина %d.%02d,\n"
+"мин.ÑÑлкогÑаÑÐ¸Ñ %d.%02d, мин.оÑвеÑÑÑие %d.%02d, мин.колÑÑо %d.%02d\n"
+
+#: ../src/action.c:1781
+msgid "No DRC problems found.\n"
+msgstr "ÐаÑÑÑений пÑоекÑнÑÑ
 ноÑм не найдено.\n"
+
+#: ../src/action.c:1783
+#, c-format
+msgid "Found %d design rule errors.\n"
+msgstr "Ðайдено %d наÑÑÑений пÑоекÑнÑÑ
 ноÑм.\n"
+
+#: ../src/action.c:1785
+#, c-format
+msgid "Aborted DRC after %d design rule errors.\n"
+msgstr "ÐÑовеÑка пÑоекÑнÑÑ
 ноÑм пÑекÑаÑена поÑле %d наÑÑÑений.\n"
+
+#: ../src/action.c:2154
+msgid "Don't combine metric/English grids like that!\n"
+msgstr "Ðе обÑединÑйÑе Ñаким обÑазом меÑÑиÑеÑкие и дÑймовÑе ÑеÑки!\n"
+
+#: ../src/action.c:2263
+msgid "Click on a connection"
+msgstr "ЩÑлкниÑе на Ñоединении"
+
+#: ../src/action.c:2757 ../src/action.c:7694
+msgid "Click on an element"
+msgstr "ЩÑлкниÑе на ÑлеменÑе"
+
+#.
+#. * We deal with the case where name already exists in this
+#. * function so the GUI doesn't need to deal with it
+#.
+#: ../src/action.c:3195
+msgid "Save Renumber Annotation File As ..."
+msgstr "СоÑ
ÑаниÑÑ Ñайл анноÑаÑии пеÑенÑмеÑаÑии как..."
+
+#: ../src/action.c:3196
+msgid ""
+"Choose a file to record the renumbering to.\n"
+"This file may be used to back annotate the\n"
+"change to the schematics.\n"
+msgstr ""
+"ÐÑбеÑиÑе Ñайл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи пеÑенÑмеÑаÑии.\n"
+"ÐÑÐ¾Ñ Ñайл Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзован длÑ\n"
+"обÑаÑной анноÑаÑии изменений в ÑÑ
еме.\n"
+
+#: ../src/action.c:3221 ../src/action.c:6015 ../src/hid/gtk/gtkhid-main.c:1429
+msgid "File exists!  Ok to overwrite?"
+msgstr "Файл ÑÑÑеÑÑвÑеÑ! ÐеÑезапиÑаÑÑ?"
+
+#: ../src/action.c:3231
+#, c-format
+msgid "Could not open %s\n"
+msgstr "Ðевозможно оÑкÑÑÑÑ %s\n"
+
+#: ../src/action.c:3820
+msgid ""
+"Auto-placement can NOT be undone.\n"
+"Do you want to continue anyway?\n"
+msgstr ""
+"ÐвÑоÑазмеÑение не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ñменено.\n"
+"ХоÑиÑе пÑодолжиÑÑ?\n"
+
+#: ../src/action.c:4071 ../src/action.c:4140 ../src/action.c:4504
+#: ../src/action.c:4592 ../src/action.c:4647 ../src/action.c:4725
+#: ../src/action.c:4788 ../src/action.c:4848 ../src/action.c:4909
+#: ../src/action.c:4969 ../src/action.c:5032 ../src/action.c:5097
+#: ../src/action.c:5161 ../src/action.c:5211 ../src/action.c:6458
+#: ../src/action.c:7888
+msgid "Select an Object"
+msgstr "ÐÑбеÑиÑе обÑекÑ"
+
+#: ../src/action.c:4542 ../src/action.c:5824
+msgid "Enter the layout name:"
+msgstr "Ðазвание ÑÑаÑÑиÑовки:"
+
+#: ../src/action.c:4549
+msgid "Enter the layer name:"
+msgstr "Ðазвание ÑлоÑ:"
+
+#: ../src/action.c:5317 ../src/action.c:5500
+msgid "Enter pattern:"
+msgstr "ÐоÑадоÑное меÑÑо:"
+
+#: ../src/action.c:5387
+msgid "Select the Element's Mark Location"
+msgstr "ÐÑбеÑиÑе ÑаÑположение оÑмеÑки ÑлеменÑа"
+
+#: ../src/action.c:5776
+msgid "OK to override layout data?"
+msgstr "ÐамениÑÑ Ð´Ð°Ð½Ð½Ñе ÑÑаÑÑиÑовки?"
+
+#: ../src/action.c:5791
+msgid "OK to override changes?"
+msgstr "ÐамениÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ?"
+
+#: ../src/action.c:5819
+msgid "OK to clear layout data?"
+msgstr "УдалиÑÑ Ð´Ð°Ð½Ð½Ñе ÑÑаÑÑиÑовки?"
+
+#: ../src/action.c:5981
+msgid "Buffer has no elements!\n"
+msgstr "РбÑÑеÑе Ð½ÐµÑ ÑлеменÑов!\n"
+
+#: ../src/action.c:5987
+msgid "Save Paste Buffer As ..."
+msgstr "СоÑ
ÑаниÑÑ Ð±ÑÑÐµÑ Ð¾Ð±Ð¼ÐµÐ½Ð° как..."
+
+#: ../src/action.c:5988
+msgid ""
+"Choose a file to save the contents of the\n"
+"paste buffer to.\n"
+msgstr ""
+"ÐÑбеÑиÑе Ñайл Ð´Ð»Ñ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑодеÑжимого\n"
+"бÑÑеÑа обмена\n"
+
+#: ../src/action.c:6411
+msgid "Nothing found under crosshair\n"
+msgstr "Ðод кÑÑÑоÑом ниÑего не найдено\n"
+
+#: ../src/action.c:6673
+#, c-format
+msgid "%s():  Flag \"%s\" is not valid\n"
+msgstr "%s(): Ñлаг \"%s\" не дейÑÑвиÑелен\n"
+
+#: ../src/action.c:6768
+#, c-format
+msgid "Could not open actions file \"%s\".\n"
+msgstr "Ðевозможно оÑкÑÑÑÑ Ñайл дейÑÑвий \"%s\".\n"
+
+#: ../src/action.c:7073
+#, c-format
+msgid "Cannot change attribute of %s - element not found\n"
+msgstr "Ðевозможно измениÑÑ Ð°ÑÑибÑÑ Ð´Ð»Ñ %s â ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ найден\n"
+
+#. error
+#: ../src/action.c:7206
+msgid "Cannot fork!"
+msgstr "Ðевозможно ÑоздаÑÑ Ð´Ð¾ÑеÑний пÑоÑеÑÑ!"
+
+#: ../src/action.c:7353
+#, c-format
+msgid "%s():  Unable to determine temp directory name from the temp file\n"
+msgstr ""
+"%s(): невозможно опÑеделиÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ вÑеменного каÑалога по Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ "
+"вÑеменного Ñайла\n"
+
+#: ../src/action.c:7376
+#, c-format
+msgid "Failed to unlink \"%s\"\n"
+msgstr "Ðевозможно ÑдалиÑÑ \"%s\"\n"
+
+#: ../src/action.c:7475 ../src/action.c:7537
+msgid "Could not create temp file"
+msgstr "Ðевозможно ÑоздаÑÑ Ð²ÑеменнÑй Ñайл"
+
+#: ../src/action.c:7591
+#, c-format
+msgid "Unknown import mode: %s\n"
+msgstr "ÐеизвеÑÑнÑй Ñежим импоÑÑа: %s\n"
+
+#: ../src/action.c:7635
+msgid "This GUI doesn't support Attribute Editing\n"
+msgstr "ÐÑÐ¾Ñ Ð³ÑаÑиÑеÑкий инÑеÑÑÐµÐ¹Ñ Ð½Ðµ поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑедакÑиÑование аÑÑибÑÑов\n"
+
+#: ../src/action.c:7662
+#, c-format
+msgid "No layer named %s\n"
+msgstr "ÐÐµÑ ÑÐ»Ð¾Ñ Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ %s\n"
+
+#: ../src/action.c:7688
+msgid "Too many elements selected\n"
+msgstr "ÐÑбÑано ÑлиÑком много ÑлеменÑов\n"
+
+#: ../src/action.c:7701
+msgid "No element found there\n"
+msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ найден\n"
+
+#: ../src/action.c:7798
+msgid "Click on Object or Flip Point"
+msgstr "ЩÑлкниÑе на обÑекÑе или ÑоÑке пеÑеÑÑановки"
+
+#: ../src/action.c:7870
+msgid "Select item to use attributes from"
+msgstr "ÐÑбеÑиÑе ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐµÐ³Ð¾ аÑÑибÑÑов"
+
+#: ../src/autoplace.c:776 ../src/rats.c:691 ../src/rats.c:785
+msgid "Can't add rat lines because no netlist is loaded.\n"
+msgstr ""
+"Ðевозможно добавиÑÑ ÑоединениÑ, Ñак как ÑпиÑок Ñоединений не загÑÑжен.\n"
+
+#: ../src/autoplace.c:783
+msgid "No elements selected to autoplace.\n"
+msgstr "ÐлеменÑÑ Ð´Ð»Ñ Ð°Ð²ÑоÑазмеÑÐµÐ½Ð¸Ñ Ð½Ðµ вÑбÑанÑ.\n"
+
+#: ../src/buffer.c:933
+msgid "Error!  Buffer doesn't contain a single element\n"
+msgstr "ÐÑибка! РбÑÑеÑе Ð½ÐµÑ Ð½Ð¸ одного ÑлеменÑа\n"
+
+#: ../src/buffer.c:1148
+msgid ""
+"Warning: All of the pads are on the opposite\n"
+"side from the component - that's probably not what\n"
+"you wanted\n"
+msgstr ""
+"ÐÑедÑпÑеждение: вÑе плоÑадки ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ñ Ð½Ð°\n"
+"пÑоÑивоположной ÑÑоÑоне Ð¾Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа, веÑоÑÑно,\n"
+"Ð²Ñ ÑÑого не Ñ
оÑиÑе\n"
+
+#: ../src/buffer.c:1180
+msgid ""
+"There was nothing to convert!\n"
+"Elements must have some silk, pads or pins.\n"
+msgstr ""
+"ÐÑеобÑазовÑваÑÑ Ð½ÐµÑего!\n"
+"ÐлеменÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑодеÑжаÑÑ ÑÑлкогÑаÑиÑ, плоÑадки или вÑводÑ.\n"
+
+#: ../src/buffer.c:1185
+msgid ""
+"There were polygons that can't be made into pins!\n"
+"So they were not included in the element\n"
+msgstr ""
+"ÐÑÑÑ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ñ, коÑоÑÑе не могÑÑ Ð±ÑÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ñ Ð² вÑводÑ!\n"
+"ÐоÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¸ не вклÑÑÐµÐ½Ñ Ð² ÑлеменÑ\n"
+
+#: ../src/buffer.c:1478
+msgid "You can't mirror a buffer that has elements!\n"
+msgstr "Ðевозможно оÑÑазиÑÑ Ð±ÑÑÐµÑ ÑодеÑжаÑий ÑлеменÑÑ!\n"
+
+#: ../src/buffer.c:1486
+msgid "You can't mirror a buffer that has text!\n"
+msgstr "Ðевозможно оÑÑазиÑÑ Ð±ÑÑÐµÑ ÑодеÑжаÑий ÑекÑÑ!\n"
+
+#: ../src/change.c:753
+msgid ""
+"To change the clearance of objects in a polygon, change the objects, not the "
+"polygon.\n"
+"Hint: To set a minimum clearance for a group of objects, select them all "
+"then :MinClearGap(Selected,=10,mil)"
+msgstr ""
+"ÐÐ»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¾ÑÑÑÑпа Ð¾Ñ Ð¾Ð±ÑекÑов в полигоне, изменÑйÑе обÑекÑÑ, а не "
+"полигонÑ.\n"
+"ÐамеÑание: Ð´Ð»Ñ ÑÑÑановки минималÑного оÑÑÑÑпа Ð´Ð»Ñ Ð³ÑÑÐ¿Ð¿Ñ Ð¾Ð±ÑекÑов, вÑбеÑиÑе "
+"иÑ
 вÑе и вÑполниÑе :MinClearGap(Selected,=10,mil)"
+
+#: ../src/change.c:1046
+#, c-format
+msgid "Error: The name \"%s\" is not unique!\n"
+msgstr "ÐÑибка: название \"%s\" не ÑвлÑеÑÑÑ ÑникалÑнÑм!\n"
+
+#: ../src/change.c:2253
+msgid "Linename:"
+msgstr "Ðазв. линии:"
+
+#: ../src/change.c:2258
+msgid "Vianame:"
+msgstr "Ðазвание пеÑеÑ
ода:"
+
+#: ../src/change.c:2263
+#, c-format
+msgid "%s Pin Name:"
+msgstr "%s название вÑвода:"
+
+#: ../src/change.c:2268
+#, c-format
+msgid "%s Pad Name:"
+msgstr "%s название конÑ. плоÑадки:"
+
+#: ../src/change.c:2278
+msgid "Elementname:"
+msgstr "Ðазв. ÑлеменÑа:"
+
+#: ../src/create.c:240
+#, c-format
+msgid ""
+"Dropping via at (%d, %d) because it would overlap with the via at (%d, %d)\n"
+msgstr ""
+"ÐеÑеÑ
од не бÑÐ´ÐµÑ ÑÑÑановлен в (%d, %d), Ñак как он пеÑекÑÑваеÑÑÑ Ñ Ð¿ÐµÑеÑ
одом "
+"в (%d, %d)\n"
+
+#: ../src/create.c:261
+#, c-format
+msgid "Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n"
+msgstr ""
+"ÐеÑеÑ
одное оÑвеÑÑÑие пÑеобÑазовано в %.2f мил из %.2f мил по каÑÑе "
+"пÑоизводÑÑвеннÑÑ
 оÑвеÑÑÑий\n"
+
+#: ../src/create.c:279
+#, c-format
+msgid ""
+"Increased via thickness to %.2f mils to allow enough copper at (%.2f,%.2f).\n"
+msgstr "ТолÑина пеÑеÑ
ода ÑвелиÑена до %.2f мил Ð´Ð»Ñ Ð¿Ñоводника в (%.2f,%.2f).\n"
+
+#: ../src/create.c:797
+#, c-format
+msgid ""
+"Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum "
+"allowed size\n"
+msgstr ""
+"ÐÑвеÑÑÑие вÑвода â%s (%s) не пÑеобÑазовано, Ñак как оно менÑÑе минималÑно "
+"допÑÑÑимого на %6.2f мил\n"
+
+#: ../src/create.c:805
+#, c-format
+msgid ""
+"Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum "
+"allowed size\n"
+msgstr ""
+"ÐÑвеÑÑÑие вÑвода â%s (%s) не пÑеобÑазовано, Ñак как оно болÑÑе макÑималÑно "
+"допÑÑÑимого на %6.2f мил\n"
+
+#: ../src/create.c:814
+#, c-format
+msgid ""
+"Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough "
+"copper\n"
+msgstr ""
+"ÐÑвеÑÑÑие вÑвода â%s (%s) не пÑеобÑазовано, Ñак как %6.2f мил не доÑÑаÑоÑно "
+"Ð´Ð»Ñ Ð¿Ñоводника\n"
+
+#: ../src/create.c:828
+#, c-format
+msgid "Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n"
+msgstr ""
+"ÐÑвеÑÑÑие вÑвода пÑеобÑазовано в %.2f мил из %.2f мил по каÑÑе "
+"пÑоизводÑÑвеннÑÑ
 оÑвеÑÑÑий\n"
+
+#: ../src/create.c:935
+#, c-format
+msgid "Can't find font-symbol-file '%s'\n"
+msgstr "Ðевозможно найÑи Ñайл Ñимволов ÑÑиÑÑа '%s'\n"
+
+#: ../src/error.c:109 ../src/error.c:113
+#, c-format
+msgid ""
+"Can't open file\n"
+"   '%s'\n"
+"fopen() returned: '%s'\n"
+msgstr ""
+"Ðевозможно оÑкÑÑÑÑ Ñайл\n"
+"   '%s'\n"
+"ФÑнкÑÐ¸Ñ fopen() возвÑаÑила: '%s'\n"
+
+#: ../src/error.c:129 ../src/error.c:133
+#, c-format
+msgid ""
+"Can't execute command\n"
+"   '%s'\n"
+"popen() returned: '%s'\n"
+msgstr ""
+"Ðевозможно вÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\n"
+"   '%s'\n"
+"ФÑнкÑÐ¸Ñ popen() возвÑаÑила: '%s'\n"
+
+#: ../src/error.c:149 ../src/error.c:153
+#, c-format
+msgid ""
+"Can't scan directory\n"
+"   '%s'\n"
+"opendir() returned: '%s'\n"
+msgstr ""
+"Ðевозможно пÑоÑмоÑÑеÑÑ ÐºÐ°Ñалог\n"
+"   '%s'\n"
+"ФÑнкÑÐ¸Ñ opendir() возвÑаÑила: '%s'\n"
+
+#: ../src/error.c:169 ../src/error.c:173
+#, c-format
+msgid ""
+"Can't change working directory to\n"
+"   '%s'\n"
+"chdir() returned: '%s'\n"
+msgstr ""
+"Ðевозможно измениÑÑ ÑабоÑий каÑалог в\n"
+"   '%s'\n"
+"ФÑнкÑÐ¸Ñ chdir() возвÑаÑила: '%s'\n"
+
+#: ../src/file.c:226
+#, c-format
+msgid "File '%s' exists, use anyway?"
+msgstr "Файл '%s' ÑÑÑеÑÑвÑеÑ, вÑÑ Ñавно иÑполÑзоваÑÑ?"
+
+#. not used
+#. CheckAndOpenFile deals with the case where fname already exists
+#: ../src/file.c:268
+msgid "Save Connection Data As ..."
+msgstr "СоÑ
ÑаниÑÑ Ð´Ð°Ð½Ð½Ñе Ñоединений как..."
+
+#: ../src/file.c:269
+msgid "Choose a file to save all connection data to."
+msgstr "ÐÑбеÑиÑе Ñайл Ð´Ð»Ñ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
 Ñоединений."
+
+#: ../src/file.c:384
+#, c-format
+msgid "File '%s' has no font information, using default font\n"
+msgstr ""
+"Файл '%s' не ÑодеÑÐ¶Ð¸Ñ Ð¸Ð½ÑоÑмаÑии о ÑÑиÑÑе, иÑполÑзÑеÑÑÑ ÑÑиÑÑ Ð¿Ð¾ ÑмолÑаниÑ\n"
+
+#: ../src/file.c:970
+#, c-format
+msgid "Trying to save your layout in '%s'\n"
+msgstr "ÐопÑÑка ÑоÑ
ÑаниÑÑ ÑÑаÑÑиÑÐ¾Ð²ÐºÑ Ð² '%s'\n"
+
+#. nothing to do
+#: ../src/file.c:1438
+#, c-format
+msgid "Importing PCB netlist %s\n"
+msgstr "ÐмпоÑÑ ÑпиÑка Ñоединений PCB %s\n"
+
+#: ../src/file.c:1476
+#, c-format
+msgid ""
+"Line length (%i) exceeded in netlist file.\n"
+"additional characters will be ignored.\n"
+msgstr ""
+"Ðлина ÑÑÑоки (%i) пÑевÑÑена в Ñайле ÑпиÑка Ñоединений.\n"
+"ÐополниÑелÑнÑе ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð±ÑдÑÑ Ð¿ÑоигноÑиÑованÑ.\n"
+
+#: ../src/file.c:1530
+msgid "Empty netlist file!\n"
+msgstr "ÐÑÑÑой Ñайл ÑпиÑка Ñоединений!\n"
+
+#: ../src/file.c:1571
+#, c-format
+msgid "Importing edif netlist %s\n"
+msgstr "ÐмпоÑÑ ÑпиÑка Ñоединений edif %s\n"
+
+#: ../src/find.c:248
+#, c-format
+msgid "near (%.*f, %.*f)\n"
+msgstr "в облаÑÑи (%.*f, %.*f)\n"
+
+#: ../src/find.c:256
+#, c-format
+msgid "WARNING!  Design Rule error - %s\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ! ÐÑибка пÑоекÑной ноÑÐ¼Ñ - %s\n"
+
+#: ../src/find.c:257
+#, c-format
+msgid "near location (%.*f, %.*f)\n"
+msgstr "в облаÑÑи (%.*f, %.*f)\n"
+
+#.
+#. * message when asked about continuing DRC checks after next
+#. * violation is found.
+#.
+#: ../src/find.c:266
+msgid "Press Next to continue DRC checking"
+msgstr "ÐажмиÑе Ðалее Ð´Ð»Ñ Ð¿ÑÐ¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑовеÑки пÑоекÑнÑÑ
 ноÑм"
+
+#: ../src/find.c:267
+msgid "Next"
+msgstr "Ðалее"
+
+#: ../src/find.c:268 ../src/gpcb-menu.res:522 ../src/pcb-menu.res:186
+msgid "Cancel"
+msgstr "ÐÑмена"
+
+#: ../src/find.c:951
+#, c-format
+msgid "bad layer number %d max_layer=%d in find.c\n"
+msgstr "невеÑнÑй Ð½Ð¾Ð¼ÐµÑ ÑÐ»Ð¾Ñ %d, max_layer=%d в find.c\n"
+
+#: ../src/find.c:998
+msgid "WARNING: Hole too close to pin.\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ: оÑвеÑÑÑие ÑлиÑком близко к вÑводÑ.\n"
+
+#: ../src/find.c:1000
+msgid "WARNING: Hole too close to via.\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ: оÑвеÑÑÑие ÑлиÑком близко к пеÑеÑ
одÑ.\n"
+
+#: ../src/find.c:1064
+msgid "WARNING: Hole too close to line.\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ: оÑвеÑÑÑие ÑлиÑком близко к ÑÑаÑÑе.\n"
+
+#: ../src/find.c:1084
+msgid "WARNING: Hole too close to pad.\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ: оÑвеÑÑÑие ÑлиÑком близко к плоÑадке.\n"
+
+#: ../src/find.c:1104
+msgid "WARNING: Hole touches arc.\n"
+msgstr "ÐРÐÐУÐРÐÐÐÐÐÐÐ: оÑвеÑÑÑие каÑаеÑÑÑ Ð´Ñги.\n"
+
+#: ../src/find.c:3685
+msgid "Potential for broken trace"
+msgstr "ÐозможноÑÑÑ ÑазÑÑва ÑÑаÑÑÑ"
+
+#: ../src/find.c:3686
+msgid ""
+"Insufficient overlap between objects can lead to broken tracks\n"
+"due to registration errors with old wheel style photo-plotters."
+msgstr ""
+"ÐедоÑÑаÑоÑное пеÑекÑÑÑие Ð¼ÐµÐ¶Ð´Ñ Ð¾Ð±ÑекÑами Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к ÑазÑÑвам ÑÑаÑÑ\n"
+"из-за оÑибок ÑовмеÑÐµÐ½Ð¸Ñ Ð½Ð° ÑÑаÑÑÑ
 апеÑÑÑÑнÑÑ
 ÑоÑо-плоÑÑеÑаÑ
."
+
+#: ../src/find.c:3743
+msgid "Copper areas too close"
+msgstr "ÐблаÑÑи заливки ÑлиÑком близко"
+
+#: ../src/find.c:3744 ../src/find.c:3888
+msgid ""
+"Circuits that are too close may bridge during imaging, etching,\n"
+"plating, or soldering processes resulting in a direct short."
+msgstr ""
+"ÐлеменÑÑ, ÑаÑположеннÑе ÑлиÑком близко, могÑÑ Ð±ÑÑÑ Ð·Ð°ÐºÐ¾ÑоÑÐµÐ½Ñ Ð²\n"
+"пÑоÑеÑÑе ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¾Ð±ÑажениÑ, ÑÑавлениÑ, меÑаллизаÑии или пайки."
+
+#: ../src/find.c:3833
+msgid "Line with insufficient clearance inside polygon\n"
+msgstr "ТÑаÑÑа в полигоне Ñ Ð½ÐµÐ´Ð¾ÑÑаÑоÑнÑм оÑÑÑÑпом\n"
+
+#: ../src/find.c:3842
+msgid "Arc with insufficient clearance inside polygon\n"
+msgstr "ÐÑга в полигоне Ñ Ð½ÐµÐ´Ð¾ÑÑаÑоÑнÑм оÑÑÑÑпом\n"
+
+#: ../src/find.c:3852
+msgid "Pad with insufficient clearance inside polygon\n"
+msgstr "ÐлоÑадка в полигоне Ñ Ð½ÐµÐ´Ð¾ÑÑаÑоÑнÑм оÑÑÑÑпом\n"
+
+#: ../src/find.c:3861
+msgid "Pin with insufficient clearance inside polygon\n"
+msgstr "ÐÑвод в полигоне Ñ Ð½ÐµÐ´Ð¾ÑÑаÑоÑнÑм оÑÑÑÑпом\n"
+
+#: ../src/find.c:3870
+msgid "Via with insufficient clearance inside polygon\n"
+msgstr "ÐеÑеÑ
од в полигоне Ñ Ð½ÐµÐ´Ð¾ÑÑаÑоÑнÑм оÑÑÑÑпом\n"
+
+#: ../src/find.c:4010
+msgid "Line width is too thin"
+msgstr "ТолÑина ÑÑаÑÑÑ ÑлиÑком мала"
+
+#: ../src/find.c:4011 ../src/find.c:4055
+msgid ""
+"Process specifications dictate a minimum feature-width\n"
+"that can reliably be reproduced"
+msgstr ""
+"ТеÑ
нологиÑеÑкий пÑоÑеÑÑ Ð¾Ð¿ÑеделÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑнÑй ÑазмеÑ\n"
+"Ñопологии, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñоздан"
+
+#: ../src/find.c:4054
+msgid "Arc width is too thin"
+msgstr "ТолÑина дÑги ÑлиÑком мала"
+
+#: ../src/find.c:4099
+msgid "Pin annular ring too small"
+msgstr "ÐолÑÑо вÑвода ÑлиÑком мало"
+
+#: ../src/find.c:4100 ../src/find.c:4222
+msgid ""
+"Annular rings that are too small may erode during etching,\n"
+"resulting in a broken connection"
+msgstr ""
+"СлиÑком малÑе колÑÑа могÑÑ Ð±ÑÑÑ Ð¸ÑÐºÐ°Ð¶ÐµÐ½Ñ Ð¿Ñи ÑÑавлении,\n"
+"ÑÑо пÑиведÑÑ Ðº повÑÐµÐ¶Ð´ÐµÐ½Ð¸Ñ ÑоединениÑ"
+
+#: ../src/find.c:4133
+msgid "Pin drill size is too small"
+msgstr "Ð Ð°Ð·Ð¼ÐµÑ Ð¾ÑвеÑÑÑÐ¸Ñ Ð²Ñвода ÑлиÑком мал"
+
+#: ../src/find.c:4134 ../src/find.c:4256
+msgid "Process rules dictate the minimum drill size which can be used"
+msgstr ""
+"ÐоÑÐ¼Ñ Ð¿ÑоÑеÑÑа изгоÑÐ¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°ÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñно возможнÑй ÑÐ°Ð·Ð¼ÐµÑ Ð¾ÑвеÑÑÑиÑ"
+
+#: ../src/find.c:4176
+msgid "Pad is too thin"
+msgstr "ТолÑина плоÑадки ÑлиÑком мала"
+
+#: ../src/find.c:4177
+msgid ""
+"Pads which are too thin may erode during etching,\n"
+"resulting in a broken or unreliable connection"
+msgstr ""
+"СлиÑком Ñзкие плоÑадки могÑÑ Ð±ÑÑÑ ÑазÑÑÑÐµÐ½Ñ Ð¿Ñи ÑÑавлении,\n"
+"ÑÑо пÑиведÑÑ Ðº оÑÑÑÑÑÑÐ²Ð¸Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ к ненадÑÐ¶Ð½Ð¾Ð¼Ñ ÑоединениÑ"
+
+#: ../src/find.c:4221
+msgid "Via annular ring too small"
+msgstr "ÐолÑÑо пеÑеÑ
ода ÑлиÑком мало"
+
+#: ../src/find.c:4255
+msgid "Via drill size is too small"
+msgstr "ÐеÑеÑ
одное оÑвеÑÑÑие ÑлиÑком мало"
+
+#: ../src/find.c:4303
+msgid "Silk line is too thin"
+msgstr "ТолÑина линии ÑÑлкогÑаÑии ÑлиÑком мала"
+
+#: ../src/find.c:4304
+msgid ""
+"Process specifications dictate a minimum silkscreen feature-width\n"
+"that can reliably be reproduced"
+msgstr ""
+"ТеÑ
нологиÑеÑкий пÑоÑеÑÑ Ð¾Ð¿ÑеделÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑнÑÑ ÑолÑÐ¸Ð½Ñ ÑÑлкогÑаÑии,\n"
+"коÑоÑÐ°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ð°Ð½ÐµÑена"
+
+#: ../src/find.c:4358
+#, c-format
+msgid "Element %s has %i silk lines which are too thin"
+msgstr "ÐÐ»ÐµÐ¼ÐµÐ½Ñ %s ÑодеÑÐ¶Ð¸Ñ %i ÑлиÑком ÑонкиÑ
 линий ÑÑлкогÑаÑии"
+
+#: ../src/find.c:4369
+msgid ""
+"Process specifications dictate a minimum silkscreen\n"
+"feature-width that can reliably be reproduced"
+msgstr ""
+"ТеÑ
нологиÑеÑкий пÑоÑеÑÑ Ð¾Ð¿ÑеделÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑнÑÑ\n"
+"ÑолÑÐ¸Ð½Ñ Ð»Ð¸Ð½Ð¸Ð¸ ÑÑлкогÑаÑии, коÑоÑÐ°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ð°Ð½ÐµÑена"
+
+#: ../src/find.c:4409
+#, c-format
+msgid "Warning:  %d pad%s the nopaste flag set.\n"
+msgstr "ÐÑедÑпÑеждение: Ð´Ð»Ñ %d плоÑадок%s ÑÑÑановлен Ñлаг nopaste.\n"
+
+#: ../src/gpcb-menu.res:63 ../src/pcb-menu.res:46
+msgid " a single element"
+msgstr " единÑÑвенного ÑлеменÑа"
+
+#: ../src/gpcb-menu.res:64 ../src/pcb-menu.res:47
+msgid " all elements"
+msgstr " вÑеÑ
 ÑлеменÑов"
+
+#: ../src/gpcb-menu.res:65 ../src/pcb-menu.res:48
+msgid " unused pins"
+msgstr " неиÑполÑзÑемÑе вÑводÑ"
+
+#: ../src/gpcb-menu.res:303 ../src/pcb-menu.res:284
+msgid "#1"
+msgstr "â 1"
+
+#: ../src/gpcb-menu.res:304 ../src/pcb-menu.res:285
+msgid "#2"
+msgstr "â 2"
+
+#: ../src/gpcb-menu.res:305 ../src/pcb-menu.res:286
+msgid "#3"
+msgstr "â 3"
+
+#: ../src/gpcb-menu.res:306 ../src/pcb-menu.res:287
+msgid "#4"
+msgstr "â 4"
+
+#: ../src/gpcb-menu.res:307 ../src/pcb-menu.res:288
+msgid "#5"
+msgstr "â 5"
+
+#: ../src/gpcb-menu.res:202 ../src/pcb-menu.res:194
+msgid "'All-direction' lines"
+msgstr "Ðинии лÑбого напÑавлениÑ"
+
+#: ../src/gpcb-menu.res:202 ../src/pcb-menu.res:194
+msgid "."
+msgstr "."
+
+#: ../src/gpcb-menu.res:441 ../src/pcb-menu.res:409
+msgid "/"
+msgstr "/"
+
+#: ../src/gpcb-menu.res:139 ../src/pcb-menu.res:107
+msgid "0.01 mm"
+msgstr "0.01 мм"
+
+#: ../src/gpcb-menu.res:140 ../src/pcb-menu.res:108
+msgid "0.05 mm"
+msgstr "0.05 мм"
+
+#: ../src/gpcb-menu.res:131 ../src/pcb-menu.res:99
+msgid "0.1 mil"
+msgstr "0.1 мил"
+
+#: ../src/gpcb-menu.res:141 ../src/pcb-menu.res:109
+msgid "0.1 mm"
+msgstr "0.1 мм"
+
+#: ../src/gpcb-menu.res:142 ../src/pcb-menu.res:110
+msgid "0.25 mm"
+msgstr "0.25 мм"
+
+#: ../src/gpcb-menu.res:143 ../src/pcb-menu.res:111
+msgid "0.5 mm"
+msgstr "0.5 мм"
+
+#: ../src/gpcb-menu.res:132 ../src/pcb-menu.res:100
+msgid "1 mil"
+msgstr "1 мил"
+
+#: ../src/gpcb-menu.res:144 ../src/pcb-menu.res:112
+msgid "1 mm"
+msgstr "1 мм"
+
+#: ../src/gpcb-menu.res:134 ../src/pcb-menu.res:102
+msgid "10 mil"
+msgstr "10 мил"
+
+#: ../src/gpcb-menu.res:137 ../src/pcb-menu.res:105
+msgid "100 mil"
+msgstr "100 мил"
+
+#: ../src/gpcb-menu.res:135 ../src/pcb-menu.res:103
+msgid "25 mil"
+msgstr "25 мил"
+
+#: ../src/gpcb-menu.res:133 ../src/pcb-menu.res:101
+msgid "5 mil"
+msgstr "5 мил"
+
+#: ../src/gpcb-menu.res:136 ../src/pcb-menu.res:104
+msgid "50 mil"
+msgstr "50 мил"
+
+#: ../src/gpcb-menu.res:466 ../src/pcb-menu.res:188
+msgid ":"
+msgstr ":"
+
+#: ../src/gpcb-menu.res:202 ../src/pcb-menu.res:194
+msgid "<Key>."
+msgstr "<Key>."
+
+#: ../src/gpcb-menu.res:441 ../src/pcb-menu.res:409
+msgid "<Key>/"
+msgstr "<Key>/"
+
+#: ../src/gpcb-menu.res:466 ../src/pcb-menu.res:188
+msgid "<Key>:"
+msgstr "<Key>:"
+
+#: ../src/gpcb-menu.res:335 ../src/pcb-menu.res:312
+msgid "<Key>="
+msgstr "<Key>="
+
+#: ../src/gpcb-menu.res:366 ../src/pcb-menu.res:333
+msgid "<Key>BackSpace"
+msgstr "<Key>BackSpace"
+
+#: ../src/gpcb-menu.res:360 ../src/pcb-menu.res:234
+msgid "<Key>Delete"
+msgstr "<Key>Delete"
+
+#: ../src/gpcb-menu.res:447 ../src/pcb-menu.res:415
+msgid "<Key>Down"
+msgstr "<Key>Ðниз"
+
+#: ../src/gpcb-menu.res:454 ../src/pcb-menu.res:422
+msgid "<Key>Enter"
+msgstr "<Key>Enter"
+
+#: ../src/gpcb-menu.res:522 ../src/pcb-menu.res:186
+msgid "<Key>Escape"
+msgstr "<Key>Escape"
+
+#: ../src/gpcb-menu.res:507 ../src/pcb-menu.res:171
+msgid "<Key>F1"
+msgstr "<Key>F1"
+
+#: ../src/gpcb-menu.res:516 ../src/pcb-menu.res:180
+msgid "<Key>F10"
+msgstr "<Key>F10"
+
+#: ../src/gpcb-menu.res:517 ../src/pcb-menu.res:181
+msgid "<Key>F11"
+msgstr "<Key>F11"
+
+#: ../src/gpcb-menu.res:508 ../src/pcb-menu.res:172
+msgid "<Key>F2"
+msgstr "<Key>F2"
+
+#: ../src/gpcb-menu.res:509 ../src/pcb-menu.res:173
+msgid "<Key>F3"
+msgstr "<Key>F3"
+
+#: ../src/gpcb-menu.res:510 ../src/pcb-menu.res:174
+msgid "<Key>F4"
+msgstr "<Key>F4"
+
+#: ../src/gpcb-menu.res:511 ../src/pcb-menu.res:175
+msgid "<Key>F5"
+msgstr "<Key>F5"
+
+#: ../src/gpcb-menu.res:512 ../src/pcb-menu.res:176
+msgid "<Key>F6"
+msgstr "<Key>F6"
+
+#: ../src/gpcb-menu.res:513 ../src/pcb-menu.res:177
+msgid "<Key>F7"
+msgstr "<Key>F7"
+
+#: ../src/gpcb-menu.res:514 ../src/pcb-menu.res:178
+msgid "<Key>F8"
+msgstr "<Key>F8"
+
+#: ../src/gpcb-menu.res:515 ../src/pcb-menu.res:179
+msgid "<Key>F9"
+msgstr "<Key>F9"
+
+#: ../src/gpcb-menu.res:518 ../src/pcb-menu.res:182
+msgid "<Key>Insert"
+msgstr "<Key>Insert"
+
+#: ../src/gpcb-menu.res:448 ../src/pcb-menu.res:416
+msgid "<Key>Left"
+msgstr "<Key>Ðлево"
+
+#: ../src/gpcb-menu.res:449 ../src/pcb-menu.res:417
+msgid "<Key>Right"
+msgstr "<Key>ÐпÑаво"
+
+#: ../src/gpcb-menu.res:176 ../src/pcb-menu.res:55
+msgid "<Key>Tab"
+msgstr "<Key>Tab"
+
+#: ../src/gpcb-menu.res:446 ../src/pcb-menu.res:414
+msgid "<Key>Up"
+msgstr "<Key>ÐвеÑÑ
"
+
+#: ../src/gpcb-menu.res:443 ../src/pcb-menu.res:411
+msgid "<Key>["
+msgstr "<Key>["
+
+#: ../src/gpcb-menu.res:444 ../src/pcb-menu.res:412
+msgid "<Key>]"
+msgstr "<Key>]"
+
+#: ../src/gpcb-menu.res:403 ../src/pcb-menu.res:370
+msgid "<Key>a"
+msgstr "<Key>a"
+
+#: ../src/gpcb-menu.res:404 ../src/pcb-menu.res:371
+msgid "<Key>b"
+msgstr "<Key>b"
+
+#: ../src/gpcb-menu.res:180 ../src/pcb-menu.res:59
+msgid "<Key>c"
+msgstr "<Key>c"
+
+#: ../src/gpcb-menu.res:159 ../src/pcb-menu.res:212
+msgid "<Key>d"
+msgstr "<Key>d"
+
+#: ../src/gpcb-menu.res:321 ../src/pcb-menu.res:299
+msgid "<Key>e"
+msgstr "<Key>e"
+
+#: ../src/gpcb-menu.res:405 ../src/pcb-menu.res:372
+msgid "<Key>f"
+msgstr "<Key>f"
+
+#: ../src/gpcb-menu.res:147 ../src/pcb-menu.res:115
+msgid "<Key>g"
+msgstr "<Key>g"
+
+#: ../src/gpcb-menu.res:406 ../src/pcb-menu.res:373
+msgid "<Key>h"
+msgstr "<Key>h"
+
+#: ../src/gpcb-menu.res:462
+msgid "<Key>i"
+msgstr "<Key>i"
+
+#: ../src/gpcb-menu.res:409 ../src/pcb-menu.res:376
+msgid "<Key>j"
+msgstr "<Key>j"
+
+#: ../src/gpcb-menu.res:411 ../src/pcb-menu.res:378
+msgid "<Key>k"
+msgstr "<Key>k"
+
+#: ../src/gpcb-menu.res:415 ../src/pcb-menu.res:382
+msgid "<Key>l"
+msgstr "<Key>l"
+
+#: ../src/gpcb-menu.res:110 ../src/pcb-menu.res:150
+msgid "<Key>m"
+msgstr "<Key>m"
+
+#: ../src/gpcb-menu.res:100 ../src/pcb-menu.res:154
+msgid "<Key>n"
+msgstr "<Key>n"
+
+#: ../src/gpcb-menu.res:320 ../src/pcb-menu.res:298
+msgid "<Key>o"
+msgstr "<Key>o"
+
+#: ../src/gpcb-menu.res:426 ../src/pcb-menu.res:393
+msgid "<Key>p"
+msgstr "<Key>p"
+
+#: ../src/gpcb-menu.res:428 ../src/pcb-menu.res:395
+msgid "<Key>q"
+msgstr "<Key>q"
+
+#: ../src/gpcb-menu.res:429 ../src/pcb-menu.res:396
+msgid "<Key>s"
+msgstr "<Key>s"
+
+#: ../src/gpcb-menu.res:442 ../src/pcb-menu.res:410
+msgid "<Key>space"
+msgstr "<Key>пÑобел"
+
+#: ../src/gpcb-menu.res:433 ../src/pcb-menu.res:400
+msgid "<Key>t"
+msgstr "<Key>t"
+
+#: ../src/gpcb-menu.res:84 ../src/pcb-menu.res:135
+msgid "<Key>u"
+msgstr "<Key>u"
+
+#: ../src/gpcb-menu.res:164 ../src/pcb-menu.res:81
+msgid "<Key>v"
+msgstr "<Key>v"
+
+#: ../src/gpcb-menu.res:440 ../src/pcb-menu.res:407
+msgid "<Key>w"
+msgstr "<Key>w"
+
+#: ../src/gpcb-menu.res:337 ../src/pcb-menu.res:314
+msgid "<Key>y"
+msgstr "<Key>y"
+
+#: ../src/gpcb-menu.res:161 ../src/pcb-menu.res:78
+msgid "<Key>z"
+msgstr "<Key>z"
+
+#: ../src/gpcb-menu.res:218 ../src/pcb-menu.res:207
+msgid "<Key>|"
+msgstr "<Key>|"
+
+#: ../src/gpcb-menu.res:335 ../src/pcb-menu.res:312
+msgid "="
+msgstr "="
+
+#: ../src/gpcb-menu.res:403 ../src/pcb-menu.res:370
+msgid "A"
+msgstr "A"
+
+#: ../src/gpcb-menu.res:469 ../src/pcb-menu.res:31
+msgid "About..."
+msgstr "РпÑогÑамме..."
+
+#: ../src/gpcb-menu.res:440 ../src/pcb-menu.res:407
+msgid "Add All Rats"
+msgstr "ÐобавиÑÑ Ð²Ñе ÑоединениÑ"
+
+#: ../src/gpcb-menu.res:192 ../src/pcb-menu.res:129
+msgid "Add new layer"
+msgstr "ÐобавиÑÑ Ð½Ð¾Ð²Ñй Ñлой"
+
+#: ../src/gpcb-menu.res:439 ../src/pcb-menu.res:406
+msgid "AddRats Selected"
+msgstr "ÐобавиÑÑ Ð²ÑбÑаннÑе ÑоединениÑ"
+
+#: ../src/gpcb-menu.res:419 ../src/pcb-menu.res:386
+msgid "AddRats to selected pins"
+msgstr "ÐобавиÑÑ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº вÑбÑÐ°Ð½Ð½Ð¾Ð¼Ñ Ð²ÑводÑ"
+
+#: ../src/gpcb-menu.res:341 ../src/pcb-menu.res:318
+msgid "All"
+msgstr "ÐÑе"
+
+#: ../src/gpcb-menu.res:236 ../src/pcb-menu.res:224
+msgid "All objects"
+msgstr "ÐÑе обÑекÑÑ"
+
+#: ../src/gpcb-menu.res:432 ../src/pcb-menu.res:399
+msgid "Alt Shift<Key>s"
+msgstr "Alt Shift<Key>s"
+
+#: ../src/gpcb-menu.res:438 ../src/pcb-menu.res:405
+msgid "Alt Shift<Key>v"
+msgstr "Alt Shift<Key>v"
+
+#: ../src/gpcb-menu.res:97 ../src/pcb-menu.res:148
+msgid "Alt-A"
+msgstr "Alt-A"
+
+#: ../src/gpcb-menu.res:253 ../src/pcb-menu.res:238
+msgid "Alt-R"
+msgstr "Alt-R"
+
+#: ../src/gpcb-menu.res:431 ../src/pcb-menu.res:398
+msgid "Alt-S"
+msgstr "Alt-S"
+
+#: ../src/gpcb-menu.res:432 ../src/pcb-menu.res:399
+msgid "Alt-Shift-S"
+msgstr "Alt-Shift-S"
+
+#: ../src/gpcb-menu.res:438 ../src/pcb-menu.res:405
+msgid "Alt-Shift-V"
+msgstr "Alt-Shift-V"
+
+#: ../src/gpcb-menu.res:437 ../src/pcb-menu.res:404
+msgid "Alt-V"
+msgstr "Alt-V"
+
+#: ../src/gpcb-menu.res:97 ../src/pcb-menu.res:148
+msgid "Alt<Key>a"
+msgstr "Alt<Key>a"
+
+#: ../src/gpcb-menu.res:253 ../src/pcb-menu.res:238
+msgid "Alt<Key>r"
+msgstr "Alt<Key>r"
+
+#: ../src/gpcb-menu.res:431 ../src/pcb-menu.res:398
+msgid "Alt<Key>s"
+msgstr "Alt<Key>s"
+
+#: ../src/gpcb-menu.res:437 ../src/pcb-menu.res:404
+msgid "Alt<Key>v"
+msgstr "Alt<Key>v"
+
+#: ../src/gpcb-menu.res:349 ../src/pcb-menu.res:324
+msgid "Apply vendor drill mapping"
+msgstr "ÐÑимениÑÑ ÐºÐ°ÑÑÑ Ð¿ÑоизводÑÑвеннÑÑ
 оÑвеÑÑÑий"
+
+#: ../src/gpcb-menu.res:509 ../src/pcb-menu.res:173
+msgid "Arc"
+msgstr "ÐÑга"
+
+#: ../src/gpcb-menu.res:517 ../src/pcb-menu.res:410
+msgid "Arrow"
+msgstr "ÐÑбоÑ"
+
+#: ../src/gpcb-menu.res:442
+msgid "Arrow Mode"
+msgstr "Режим вÑбоÑа"
+
+#: ../src/gpcb-menu.res:207 ../src/pcb-menu.res:199
+msgid "Auto enforce DRC clearance"
+msgstr "ÐвÑоÑоблÑдение оÑÑÑÑпов пÑоекÑнÑÑ
 ноÑм"
+
+#: ../src/gpcb-menu.res:494
+msgid "Auto place selected elements"
+msgstr "ÐвÑоÑазмеÑение вÑбÑаннÑÑ
 ÑлеменÑов"
+
+#: ../src/gpcb-menu.res:203 ../src/pcb-menu.res:195
+msgid "Auto swap line start angle"
+msgstr "ÐвÑоизменение наÑалÑного Ñгла линии"
+
+#: ../src/gpcb-menu.res:329 ../src/pcb-menu.res:306
+msgid "Auto-Optimize"
+msgstr "ÐвÑоопÑимизаÑиÑ"
+
+#: ../src/gpcb-menu.res:244 ../src/pcb-menu.res:231
+msgid "Auto-place selected elements"
+msgstr "ÐвÑоÑазмеÑение вÑбÑаннÑÑ
 ÑлеменÑов"
+
+#: ../src/gpcb-menu.res:325 ../src/pcb-menu.res:303
+msgid "Auto-route all rats"
+msgstr "ÐвÑоÑÑаÑÑиÑовка вÑеÑ
 Ñоединений"
+
+#: ../src/gpcb-menu.res:324 ../src/pcb-menu.res:302
+msgid "Auto-route selected rats"
+msgstr "ÐвÑоÑÑаÑÑиÑовка вÑбÑаннÑÑ
 Ñоединений"
+
+#: ../src/gpcb-menu.res:214 ../src/pcb-menu.res:203
+msgid "Auto-zero delta measurements"
+msgstr "ÐвÑо обнÑление делÑÑа-измеÑений"
+
+#: ../src/gpcb-menu.res:495
+msgid "Autoroute selected elements"
+msgstr "ÐвÑоÑÑаÑÑиÑовка вÑбÑаннÑÑ
 ÑлеменÑов"
+
+#: ../src/gpcb-menu.res:404 ../src/pcb-menu.res:371
+msgid "B"
+msgstr "B"
+
+#: ../src/gpcb-menu.res:366 ../src/pcb-menu.res:333
+msgid "Backspace"
+msgstr "Backspace"
+
+#: ../src/gpcb-menu.res:299 ../src/pcb-menu.res:280
+msgid "Break buffer elements to pieces"
+msgstr "РазбиÑÑ ÑлеменÑÑ Ð² бÑÑеÑе на ÑаÑÑи"
+
+#: ../src/gpcb-menu.res:513 ../src/pcb-menu.res:177
+msgid "Buffer"
+msgstr "ÐÑÑеÑ"
+
+#: ../src/gpcb-menu.res:180 ../src/pcb-menu.res:59
+msgid "C"
+msgstr "C"
+
+#: ../src/gpcb-menu.res:70 ../src/pcb-menu.res:43
+msgid "Calibrate Printer..."
+msgstr "ÐалибÑоваÑÑ Ð¿ÑинÑеÑ..."
+
+#: ../src/gpcb-menu.res:180 ../src/pcb-menu.res:59
+msgid "Center cursor"
+msgstr "ÐÑÑÑÐ¾Ñ Ð² ÑенÑÑе"
+
+#: ../src/gpcb-menu.res:269 ../src/pcb-menu.res:253
+msgid "Change drilling hole of selected objects"
+msgstr "ÐзмениÑÑ Ð¾ÑвеÑÑÑие вÑбÑаннÑÑ
 обÑекÑов"
+
+#: ../src/gpcb-menu.res:256 ../src/pcb-menu.res:241
+msgid "Change size of selected objects"
+msgstr "ÐзмениÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ð²ÑбÑаннÑÑ
 обÑекÑов"
+
+#: ../src/gpcb-menu.res:276 ../src/pcb-menu.res:259
+msgid "Change square-flag of selected objects"
+msgstr "ÐзмениÑÑ Ð¿ÑÑмоÑголÑнÑÑ ÑоÑÐ¼Ñ Ð²ÑбÑаннÑÑ
 обÑекÑов"
+
+#: ../src/gpcb-menu.res:431 ../src/pcb-menu.res:398
+msgid "ChangeDrill +5 mil"
+msgstr "ÐÑвеÑÑÑие +5 мил"
+
+#: ../src/gpcb-menu.res:432 ../src/pcb-menu.res:399
+msgid "ChangeDrill -5 mil"
+msgstr "ÐÑвеÑÑÑие -5 мил"
+
+#: ../src/gpcb-menu.res:408 ../src/pcb-menu.res:375
+msgid "ChangeHole Object"
+msgstr "ÐзмениÑÑ Ð¾ÑвеÑÑÑие обÑекÑа"
+
+#: ../src/gpcb-menu.res:409 ../src/pcb-menu.res:376
+msgid "ChangeJoin Object"
+msgstr "ÐзмениÑÑ ÑÑÑк обÑекÑа"
+
+#: ../src/gpcb-menu.res:410 ../src/pcb-menu.res:377
+msgid "ChangeJoin SelectedObject"
+msgstr "ÐзмениÑÑ ÑÑÑк вÑбÑанного обÑекÑа"
+
+#: ../src/gpcb-menu.res:425 ../src/pcb-menu.res:392
+msgid "ChangeOctagon Object"
+msgstr "ÐзмениÑÑ Ð²Ð¾ÑÑмиÑголÑнÑй обÑекÑ"
+
+#: ../src/gpcb-menu.res:429 ../src/pcb-menu.res:396
+msgid "ChangeSize +5 mil"
+msgstr "Ð Ð°Ð·Ð¼ÐµÑ +5 мил"
+
+#: ../src/gpcb-menu.res:430 ../src/pcb-menu.res:397
+msgid "ChangeSize -5 mil"
+msgstr "Ð Ð°Ð·Ð¼ÐµÑ -5 мил"
+
+#: ../src/gpcb-menu.res:428 ../src/pcb-menu.res:395
+msgid "ChangeSquare Object"
+msgstr "ÐзмениÑÑ Ð¿ÑÑмоÑголÑнÑй обÑекÑ"
+
+#: ../src/gpcb-menu.res:220 ../src/pcb-menu.res:209
+msgid "Check polygons"
+msgstr "ÐÑовеÑиÑÑ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ñ"
+
+#: ../src/gpcb-menu.res:411 ../src/pcb-menu.res:378
+msgid "Clear Object +2 mil"
+msgstr "ÐÑÑÑÑп Ð¾Ñ Ð¾Ð±ÑекÑа +2 мил"
+
+#: ../src/gpcb-menu.res:412 ../src/pcb-menu.res:379
+msgid "Clear Object -2 mil"
+msgstr "ÐÑÑÑÑп Ð¾Ñ Ð¾Ð±ÑекÑа -2 мил"
+
+#: ../src/gpcb-menu.res:413 ../src/pcb-menu.res:380
+msgid "Clear Selected +2 mil"
+msgstr "ÐÑÑÑÑп Ð¾Ñ Ð²ÑбÑанного +2 мил"
+
+#: ../src/gpcb-menu.res:414 ../src/pcb-menu.res:381
+msgid "Clear Selected -2 mil"
+msgstr "ÐÑÑÑÑп Ð¾Ñ Ð²ÑбÑанного -2 мил"
+
+#: ../src/gpcb-menu.res:297 ../src/pcb-menu.res:278
+msgid "Clear buffer"
+msgstr "ÐÑиÑÑиÑÑ Ð±ÑÑеÑ"
+
+#: ../src/gpcb-menu.res:86 ../src/pcb-menu.res:137
+msgid "Clear undo-buffer"
+msgstr "ÐÑиÑÑиÑÑ Ð±ÑÑÐµÑ Ð¾Ñмен"
+
+#: ../src/gpcb-menu.res:454 ../src/pcb-menu.res:422
+msgid "Click"
+msgstr "ЩелÑок"
+
+#: ../src/gpcb-menu.res:466
+msgid "Command Entry"
+msgstr "Ðвод командÑ"
+
+#: ../src/gpcb-menu.res:313
+msgid "Connects"
+msgstr "СоединениÑ"
+
+#: ../src/gpcb-menu.res:298 ../src/pcb-menu.res:279
+msgid "Convert buffer to element"
+msgstr "ÐÑеобÑазоваÑÑ Ð±ÑÑÐµÑ Ð² ÑлеменÑ"
+
+#: ../src/gpcb-menu.res:493 ../src/pcb-menu.res:235
+msgid "Convert selection to element"
+msgstr "ÐÑеобÑазоваÑÑ Ð²ÑбÑанное в ÑлеменÑ"
+
+#: ../src/gpcb-menu.res:520 ../src/pcb-menu.res:184
+msgid "Copy"
+msgstr "ÐопиÑоваÑÑ"
+
+#: ../src/gpcb-menu.res:480 ../src/pcb-menu.res:265
+msgid "Copy selection to buffer"
+msgstr "ÐопиÑоваÑÑ Ð²ÑбÑанное в бÑÑеÑ"
+
+#: ../src/gpcb-menu.res:206 ../src/pcb-menu.res:198
+msgid "Crosshair shows DRC clearance"
+msgstr "УказаÑÐµÐ»Ñ Ð¿Ð¾ÐºÐ°Ð·ÑÐ²Ð°ÐµÑ Ð¾ÑÑÑÑп пÑоекÑнÑÑ
 ноÑм"
+
+#: ../src/gpcb-menu.res:205 ../src/pcb-menu.res:197
+msgid "Crosshair snaps to pins and pads"
+msgstr "ÐÑивÑзка ÑказаÑÐµÐ»Ñ Ðº вÑводам и плоÑадкам"
+
+#: ../src/gpcb-menu.res:179 ../src/pcb-menu.res:58
+msgid "Ctrl Shift<Key>Tab"
+msgstr "Ctrl Shift<Key>Tab"
+
+#: ../src/gpcb-menu.res:219 ../src/pcb-menu.res:208
+msgid "Ctrl Shift<Key>p"
+msgstr "Ctrl Shift<Key>p"
+
+#: ../src/gpcb-menu.res:93 ../src/pcb-menu.res:144
+msgid "Ctrl-C"
+msgstr "Ctrl-C"
+
+#: ../src/gpcb-menu.res:314 ../src/pcb-menu.res:292
+msgid "Ctrl-F"
+msgstr "Ctrl-F"
+
+#: ../src/gpcb-menu.res:149 ../src/pcb-menu.res:117
+msgid "Ctrl-G"
+msgstr "Ctrl-G"
+
+#: ../src/gpcb-menu.res:408 ../src/pcb-menu.res:375
+msgid "Ctrl-H"
+msgstr "Ctrl-H"
+
+#: ../src/gpcb-menu.res:413 ../src/pcb-menu.res:380
+msgid "Ctrl-K"
+msgstr "Ctrl-K"
+
+#: ../src/gpcb-menu.res:417 ../src/pcb-menu.res:384
+msgid "Ctrl-M"
+msgstr "Ctrl-M"
+
+#: ../src/gpcb-menu.res:425 ../src/pcb-menu.res:392
+msgid "Ctrl-O"
+msgstr "Ctrl-O"
+
+#: ../src/gpcb-menu.res:244 ../src/pcb-menu.res:231
+msgid "Ctrl-P"
+msgstr "Ctrl-P"
+
+#: ../src/gpcb-menu.res:76 ../src/pcb-menu.res:52
+msgid "Ctrl-Q"
+msgstr "Ctrl-Q"
+
+#: ../src/gpcb-menu.res:356 ../src/pcb-menu.res:328
+msgid "Ctrl-R"
+msgstr "Ctrl-R"
+
+#: ../src/gpcb-menu.res:219 ../src/pcb-menu.res:208
+msgid "Ctrl-Shift-P"
+msgstr "Ctrl-Shift-P"
+
+#: ../src/gpcb-menu.res:179 ../src/pcb-menu.res:58
+msgid "Ctrl-Shift-Tab"
+msgstr "Ctrl-Shift-Tab"
+
+#: ../src/gpcb-menu.res:178 ../src/pcb-menu.res:57
+msgid "Ctrl-Tab"
+msgstr "Ctrl-Tab"
+
+#: ../src/gpcb-menu.res:94 ../src/pcb-menu.res:145
+msgid "Ctrl-V"
+msgstr "Ctrl-V"
+
+#: ../src/gpcb-menu.res:90 ../src/pcb-menu.res:141
+msgid "Ctrl-X"
+msgstr "Ctrl-X"
+
+#: ../src/gpcb-menu.res:178 ../src/pcb-menu.res:57
+msgid "Ctrl<Key>Tab"
+msgstr "Ctrl<Key>Tab"
+
+#: ../src/gpcb-menu.res:93 ../src/pcb-menu.res:144
+msgid "Ctrl<Key>c"
+msgstr "Ctrl<Key>c"
+
+#: ../src/gpcb-menu.res:314 ../src/pcb-menu.res:292
+msgid "Ctrl<Key>f"
+msgstr "Ctrl<Key>f"
+
+#: ../src/gpcb-menu.res:149 ../src/pcb-menu.res:117
+msgid "Ctrl<Key>g"
+msgstr "Ctrl<Key>g"
+
+#: ../src/gpcb-menu.res:408 ../src/pcb-menu.res:375
+msgid "Ctrl<Key>h"
+msgstr "Ctrl<Key>h"
+
+#: ../src/gpcb-menu.res:413 ../src/pcb-menu.res:380
+msgid "Ctrl<Key>k"
+msgstr "Ctrl<Key>k"
+
+#: ../src/gpcb-menu.res:417 ../src/pcb-menu.res:384
+msgid "Ctrl<Key>m"
+msgstr "Ctrl<Key>m"
+
+#: ../src/gpcb-menu.res:425 ../src/pcb-menu.res:392
+msgid "Ctrl<Key>o"
+msgstr "Ctrl<Key>o"
+
+#: ../src/gpcb-menu.res:244 ../src/pcb-menu.res:231
+msgid "Ctrl<Key>p"
+msgstr "Ctrl<Key>p"
+
+#: ../src/gpcb-menu.res:76 ../src/pcb-menu.res:52
+msgid "Ctrl<Key>q"
+msgstr "Ctrl<Key>q"
+
+#: ../src/gpcb-menu.res:356 ../src/pcb-menu.res:328
+msgid "Ctrl<Key>r"
+msgstr "Ctrl<Key>r"
+
+#: ../src/gpcb-menu.res:94 ../src/pcb-menu.res:145
+msgid "Ctrl<Key>v"
+msgstr "Ctrl<Key>v"
+
+#: ../src/gpcb-menu.res:90 ../src/pcb-menu.res:141
+msgid "Ctrl<Key>x"
+msgstr "Ctrl<Key>x"
+
+#: ../src/gpcb-menu.res:188 ../src/pcb-menu.res:125
+msgid "Current Layer"
+msgstr "ТекÑÑий Ñлой"
+
+#: ../src/gpcb-menu.res:106
+msgid "CurrentLayer"
+msgstr "ТекÑÑий Ñлой"
+
+#: ../src/gpcb-menu.res:486 ../src/pcb-menu.res:267
+msgid "Cut selection to buffer"
+msgstr "ÐÑÑезаÑÑ Ð²ÑбÑанное в бÑÑеÑ"
+
+#: ../src/gpcb-menu.res:441 ../src/pcb-menu.res:409
+msgid "Cycle Clip"
+msgstr "ÐеÑеклÑÑиÑÑ Ð¾Ð³ÑаниÑиÑелÑ"
+
+#: ../src/gpcb-menu.res:159 ../src/pcb-menu.res:212
+msgid "D"
+msgstr "D"
+
+#: ../src/gpcb-menu.res:464
+msgid "DRC Check"
+msgstr "ÐÑовеÑка пÑоекÑнÑÑ
 ноÑм"
+
+#: ../src/gpcb-menu.res:330 ../src/pcb-menu.res:307
+msgid "Debumpify"
+msgstr "ÐодÑÑнÑÑÑ"
+
+#: ../src/gpcb-menu.res:360 ../src/pcb-menu.res:234
+msgid "Delete"
+msgstr "УдалиÑÑ"
+
+#: ../src/gpcb-menu.res:191 ../src/pcb-menu.res:128
+msgid "Delete current layer"
+msgstr "УдалиÑÑ ÑекÑÑий Ñлой"
+
+#: ../src/gpcb-menu.res:154 ../src/pcb-menu.res:63
+msgid "Description"
+msgstr "ÐпиÑание"
+
+#: ../src/gpcb-menu.res:347 ../src/pcb-menu.res:322
+msgid "Design Rule Checker"
+msgstr "ÐÑовеÑка пÑоекÑнÑÑ
 ноÑм"
+
+#: ../src/gpcb-menu.res:245 ../src/pcb-menu.res:232
+msgid "Disperse all elements"
+msgstr "РаÑпÑеделиÑÑ Ð²Ñе ÑлеменÑÑ"
+
+#: ../src/gpcb-menu.res:246
+msgid "Disperse selected elements"
+msgstr "РаÑпÑеделиÑÑ Ð²ÑбÑаннÑе ÑлеменÑÑ"
+
+#: ../src/gpcb-menu.res:153
+msgid "Displayed element name"
+msgstr "Ðазвание оÑобÑажаемого ÑлеменÑа"
+
+#: ../src/gpcb-menu.res:451 ../src/pcb-menu.res:419
+msgid "Down"
+msgstr "Ðниз"
+
+#: ../src/gpcb-menu.res:321 ../src/pcb-menu.res:299
+msgid "E"
+msgstr "E"
+
+#: ../src/gpcb-menu.res:83
+msgid "Edit"
+msgstr "ÐÑавка"
+
+#: ../src/gpcb-menu.res:186 ../src/pcb-menu.res:123
+msgid "Edit Layer Groups"
+msgstr "РедакÑиÑоваÑÑ Ð³ÑÑÐ¿Ð¿Ñ ÑлоÑв"
+
+#: ../src/gpcb-menu.res:104
+msgid "Edit attributes of"
+msgstr "ÐзмениÑÑ Ð°ÑÑибÑÑÑ"
+
+#: ../src/gpcb-menu.res:99
+msgid "Edit name of"
+msgstr "ÐзмениÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ"
+
+#: ../src/gpcb-menu.res:114 ../src/pcb-menu.res:166
+msgid "Edit..."
+msgstr "РедакÑиÑоваÑÑ..."
+
+#: ../src/gpcb-menu.res:107
+msgid "Element"
+msgstr "ÐлеменÑ"
+
+#: ../src/gpcb-menu.res:277 ../src/pcb-menu.res:260
+msgid "Elements"
+msgstr "ÐлеменÑÑ"
+
+#: ../src/gpcb-menu.res:158
+msgid "Enable Pinout shows number"
+msgstr "ÐÑмеÑаÑÐ¸Ñ Ð²Ñводов"
+
+#: ../src/gpcb-menu.res:123
+msgid "Enable visible grid"
+msgstr "ÐÑобÑажаÑÑ ÑеÑкÑ"
+
+#: ../src/gpcb-menu.res:454 ../src/pcb-menu.res:422
+msgid "Enter"
+msgstr "Enter"
+
+#: ../src/gpcb-menu.res:321
+msgid "Erase rats nest"
+msgstr "УдалиÑÑ ÑоединениÑ"
+
+#: ../src/gpcb-menu.res:322 ../src/pcb-menu.res:300
+msgid "Erase selected rats"
+msgstr "УдалиÑÑ Ð²ÑбÑаннÑе ÑоединениÑ"
+
+#: ../src/gpcb-menu.res:522 ../src/pcb-menu.res:186
+msgid "Esc"
+msgstr "Esc"
+
+#: ../src/gpcb-menu.res:69 ../src/pcb-menu.res:42
+msgid "Export layout..."
+msgstr "ÐкÑпоÑÑиÑоваÑÑ ÑÑаÑÑиÑовкÑ..."
+
+#: ../src/gpcb-menu.res:405 ../src/pcb-menu.res:372
+msgid "F"
+msgstr "F"
+
+#: ../src/gpcb-menu.res:507 ../src/pcb-menu.res:171
+msgid "F1"
+msgstr "F1"
+
+#: ../src/gpcb-menu.res:516 ../src/pcb-menu.res:180
+msgid "F10"
+msgstr "F10"
+
+#: ../src/gpcb-menu.res:517 ../src/pcb-menu.res:181
+msgid "F11"
+msgstr "F11"
+
+#: ../src/gpcb-menu.res:508 ../src/pcb-menu.res:172
+msgid "F2"
+msgstr "F2"
+
+#: ../src/gpcb-menu.res:509 ../src/pcb-menu.res:173
+msgid "F3"
+msgstr "F3"
+
+#: ../src/gpcb-menu.res:510 ../src/pcb-menu.res:174
+msgid "F4"
+msgstr "F4"
+
+#: ../src/gpcb-menu.res:511 ../src/pcb-menu.res:175
+msgid "F5"
+msgstr "F5"
+
+#: ../src/gpcb-menu.res:512 ../src/pcb-menu.res:176
+msgid "F6"
+msgstr "F6"
+
+#: ../src/gpcb-menu.res:513 ../src/pcb-menu.res:177
+msgid "F7"
+msgstr "F7"
+
+#: ../src/gpcb-menu.res:514 ../src/pcb-menu.res:178
+msgid "F8"
+msgstr "F8"
+
+#: ../src/gpcb-menu.res:515 ../src/pcb-menu.res:179
+msgid "F9"
+msgstr "F9"
+
+#: ../src/gpcb-menu.res:49
+msgid "File"
+msgstr "Файл"
+
+#: ../src/gpcb-menu.res:405 ../src/pcb-menu.res:372
+msgid "Find Connections"
+msgstr "ÐайÑи ÑоединениÑ"
+
+#: ../src/gpcb-menu.res:404 ../src/pcb-menu.res:371
+msgid "Flip Object"
+msgstr "ÐеÑеÑÑавиÑÑ Ð¾Ð±ÑекÑ"
+
+#: ../src/gpcb-menu.res:177 ../src/pcb-menu.res:56
+msgid "Flip left/right"
+msgstr "ÐÑÑазиÑÑ Ð¿Ñаво/лево"
+
+#: ../src/gpcb-menu.res:176 ../src/pcb-menu.res:55
+msgid "Flip up/down"
+msgstr "ÐÑÑазиÑÑ Ð²ÐµÑÑ
/низ"
+
+#: ../src/gpcb-menu.res:340 ../src/pcb-menu.res:317
+msgid "Found"
+msgstr "Ðайдено"
+
+#: ../src/gpcb-menu.res:147 ../src/pcb-menu.res:115
+msgid "G"
+msgstr "G"
+
+#: ../src/gpcb-menu.res:357 ../src/pcb-menu.res:329
+msgid "Generate drill summary"
+msgstr "ÐÑÑÑÑ Ð¾ ÑвеÑловке"
+
+#: ../src/gpcb-menu.res:499 ../src/pcb-menu.res:328
+msgid "Generate object report"
+msgstr "ÐÑÑÑÑ Ð¾Ð± обÑекÑаÑ
"
+
+#: ../src/gpcb-menu.res:338 ../src/pcb-menu.res:315
+msgid "Global Puller"
+msgstr "ÐлобалÑÐ½Ð°Ñ Ð²ÑÑÑжка"
+
+#: ../src/gpcb-menu.res:149 ../src/pcb-menu.res:117
+msgid "Grid +0.05mm"
+msgstr "СеÑка +0.05 мм"
+
+#: ../src/gpcb-menu.res:147 ../src/pcb-menu.res:115
+msgid "Grid +5mil"
+msgstr "СеÑка +5 мил"
+
+#: ../src/gpcb-menu.res:148 ../src/pcb-menu.res:116
+msgid "Grid -0.05mm"
+msgstr "СеÑка -0.05 мм"
+
+#: ../src/gpcb-menu.res:146 ../src/pcb-menu.res:114
+msgid "Grid -5mil"
+msgstr "СеÑка -5 мил"
+
+#: ../src/gpcb-menu.res:128
+msgid "Grid size"
+msgstr "Шаг ÑеÑки"
+
+#: ../src/gpcb-menu.res:124
+msgid "Grid units"
+msgstr "ÐдиниÑÑ Ð¸Ð·Ð¼ÐµÑÐµÐ½Ð¸Ñ ÑеÑки"
+
+#: ../src/gpcb-menu.res:406 ../src/pcb-menu.res:373
+msgid "H"
+msgstr "H"
+
+#: ../src/gpcb-menu.res:210 ../src/pcb-menu.res:68
+msgid "Hide Names"
+msgstr "СкÑÑÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ"
+
+#: ../src/gpcb-menu.res:55 ../src/pcb-menu.res:35
+msgid "Import Schematics"
+msgstr "ÐмпоÑÑиÑоваÑÑ ÑÑ
емÑ"
+
+#. -- Info tab
+#: ../src/gpcb-menu.res:355 ../src/hid/gtk/gui-config.c:1762
+msgid "Info"
+msgstr "ÐнÑоÑмаÑиÑ"
+
+#: ../src/gpcb-menu.res:518 ../src/pcb-menu.res:182
+msgid "Insert"
+msgstr "ÐÑÑавиÑÑ"
+
+#: ../src/gpcb-menu.res:518 ../src/pcb-menu.res:182
+msgid "Insert Point"
+msgstr "ТоÑка вÑÑавки"
+
+#: ../src/gpcb-menu.res:409 ../src/pcb-menu.res:376
+msgid "J"
+msgstr "J"
+
+#: ../src/gpcb-menu.res:411 ../src/pcb-menu.res:378
+msgid "K"
+msgstr "K"
+
+#: ../src/gpcb-menu.res:359 ../src/pcb-menu.res:332
+msgid "Key Bindings"
+msgstr "ÐазнаÑение клавиÑ"
+
+#: ../src/gpcb-menu.res:415 ../src/pcb-menu.res:382
+msgid "L"
+msgstr "L"
+
+#: ../src/gpcb-menu.res:105
+msgid "Layout"
+msgstr "ТÑаÑÑиÑовка"
+
+#: ../src/gpcb-menu.res:452 ../src/pcb-menu.res:420
+msgid "Left"
+msgstr "Ðлево"
+
+#: ../src/gpcb-menu.res:462 ../src/hid/gtk/gui-config.c:2227
+#: ../src/pcb-menu.res:427
+msgid "Library"
+msgstr "ÐиблиоÑека"
+
+#: ../src/gpcb-menu.res:508 ../src/pcb-menu.res:172
+msgid "Line"
+msgstr "ÐиниÑ"
+
+#: ../src/gpcb-menu.res:415 ../src/pcb-menu.res:382
+msgid "Line Tool size +5 mil"
+msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð»Ð¸Ð½Ð¸Ð¸ +5 мил"
+
+#: ../src/gpcb-menu.res:416 ../src/pcb-menu.res:383
+msgid "Line Tool size -5 mil"
+msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð»Ð¸Ð½Ð¸Ð¸ -5 мил"
+
+#: ../src/gpcb-menu.res:258 ../src/pcb-menu.res:243
+msgid "Lines +10 mil"
+msgstr "ÐÐ¸Ð½Ð¸Ñ +10 мил"
+
+#: ../src/gpcb-menu.res:257 ../src/pcb-menu.res:242
+msgid "Lines -10 mil"
+msgstr "ÐÐ¸Ð½Ð¸Ñ -10 мил"
+
+#: ../src/gpcb-menu.res:56
+msgid "Load a layout from a file"
+msgstr "ÐагÑÑзиÑÑ ÑÑаÑÑиÑÐ¾Ð²ÐºÑ Ð¸Ð· Ñайла"
+
+#: ../src/gpcb-menu.res:57 ../src/pcb-menu.res:37
+msgid "Load element data to paste-buffer"
+msgstr "ÐагÑÑзиÑÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² бÑÑÐµÑ Ð¾Ð±Ð¼ÐµÐ½Ð°"
+
+#: ../src/gpcb-menu.res:56 ../src/pcb-menu.res:36
+msgid "Load layout"
+msgstr "ÐагÑÑзиÑÑ ÑÑаÑÑиÑовкÑ"
+
+#: ../src/gpcb-menu.res:58 ../src/pcb-menu.res:38
+msgid "Load layout data to paste-buffer"
+msgstr "ÐагÑÑзиÑÑ ÑÑаÑÑиÑÐ¾Ð²ÐºÑ Ð² бÑÑÐµÑ Ð¾Ð±Ð¼ÐµÐ½Ð°"
+
+#. in case we have a dialog for loading a netlist file
+#: ../src/gpcb-menu.res:59 ../src/hid/gtk/gtkhid-main.c:1339
+#: ../src/hid/gtk/gui-dialog.c:318 ../src/pcb-menu.res:39
+msgid "Load netlist file"
+msgstr "ÐагÑÑзиÑÑ Ñайл ÑпиÑка Ñоединений"
+
+#: ../src/gpcb-menu.res:60 ../src/pcb-menu.res:40
+msgid "Load vendor resource file"
+msgstr "ÐагÑÑзиÑÑ Ñайл ÑеÑÑÑÑов пÑоизводиÑелÑ"
+
+#: ../src/gpcb-menu.res:521 ../src/pcb-menu.res:185
+msgid "Lock"
+msgstr "ÐаблокиÑоваÑÑ"
+
+#: ../src/gpcb-menu.res:208 ../src/pcb-menu.res:66
+msgid "Lock Names"
+msgstr "ÐаблокиÑоваÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ"
+
+#: ../src/gpcb-menu.res:314 ../src/pcb-menu.res:292
+msgid "Lookup connection to object"
+msgstr "ÐоиÑк Ñоединений Ñ Ð¾Ð±ÑекÑом"
+
+#: ../src/gpcb-menu.res:110 ../src/pcb-menu.res:150
+msgid "M"
+msgstr "M"
+
+#: ../src/gpcb-menu.res:417 ../src/pcb-menu.res:384
+msgid "MarkCrosshair"
+msgstr "ÐÑмеÑиÑÑ ÐºÑÑÑоÑ"
+
+#: ../src/gpcb-menu.res:463 ../src/pcb-menu.res:428
+msgid "Message Log"
+msgstr "ÐÑÑнал ÑообÑений"
+
+#: ../src/gpcb-menu.res:294 ../src/pcb-menu.res:275
+msgid "Mirror buffer (left/right)"
+msgstr "ÐÑÑазиÑÑ Ð±ÑÑÐµÑ (пÑаво/лево)"
+
+#: ../src/gpcb-menu.res:293 ../src/pcb-menu.res:274
+msgid "Mirror buffer (up/down)"
+msgstr "ÐÑÑазиÑÑ Ð±ÑÑÐµÑ (веÑÑ
/низ)"
+
+#: ../src/gpcb-menu.res:336 ../src/pcb-menu.res:313
+msgid "Miter"
+msgstr "Ðод 45°"
+
+#: ../src/gpcb-menu.res:163
+msgid "More zooms and view changes"
+msgstr "ÐзмениÑÑ Ð¼Ð°ÑÑÑаб и вид"
+
+#: ../src/gpcb-menu.res:519 ../src/pcb-menu.res:183
+msgid "Move"
+msgstr "ÐеÑемеÑÑиÑÑ"
+
+#: ../src/gpcb-menu.res:194 ../src/pcb-menu.res:131
+msgid "Move current layer down"
+msgstr "ÐеÑенеÑÑи ÑекÑÑий Ñлой вниз"
+
+#: ../src/gpcb-menu.res:193 ../src/pcb-menu.res:130
+msgid "Move current layer up"
+msgstr "ÐеÑенеÑÑи ÑекÑÑий Ñлой ввеÑÑ
"
+
+#: ../src/gpcb-menu.res:248 ../src/pcb-menu.res:233
+msgid "Move selected elements to other side"
+msgstr "ÐеÑенеÑÑи вÑбÑаннÑе ÑлеменÑÑ Ð¿ÑоÑивоположнÑÑ ÑÑоÑонÑ"
+
+#: ../src/gpcb-menu.res:111 ../src/pcb-menu.res:151
+msgid "Move selected to current layer"
+msgstr "ÐеÑенеÑÑи вÑбÑанное на ÑекÑÑий Ñлой"
+
+#: ../src/gpcb-menu.res:110 ../src/pcb-menu.res:150
+msgid "Move to current layer"
+msgstr "ÐеÑенеÑÑи на ÑекÑÑий Ñлой"
+
+#: ../src/gpcb-menu.res:100 ../src/pcb-menu.res:154
+msgid "N"
+msgstr "N"
+
+#: ../src/gpcb-menu.res:465 ../src/pcb-menu.res:429
+msgid "Netlist"
+msgstr "СпиÑок Ñоединений"
+
+#: ../src/gpcb-menu.res:215 ../src/pcb-menu.res:204
+msgid "New lines, arcs clear polygons"
+msgstr "Ð...
 
[truncated message content] | 
| 
      
      
      From: <gi...@gp...> - 2010-06-02 20:29:29
      
     | 
| The branch, master has been updated
       via  bef0dea06cc86cbca3a0b2d3c8a254b69e5027cc (commit)
      from  af2f50d4fb838de13dfbb5243e2114c66fefba7b (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/gtk/gtkhid-gdk.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
=================
 Commit Messages
=================
commit bef0dea06cc86cbca3a0b2d3c8a254b69e5027cc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    hid/gtk: Don't call gdk_draw_points() when we have no grid points to draw
    
    Fixes this warning seen when zooming close in on a course grid setting:
    
    Gdk-CRITICAL **: gdk_draw_points: assertion `(points != NULL) && (n_points > 0)' failed
:100644 100644 dc2ad98... 461b779... M	src/hid/gtk/gtkhid-gdk.c
=========
 Changes
=========
commit bef0dea06cc86cbca3a0b2d3c8a254b69e5027cc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    hid/gtk: Don't call gdk_draw_points() when we have no grid points to draw
    
    Fixes this warning seen when zooming close in on a course grid setting:
    
    Gdk-CRITICAL **: gdk_draw_points: assertion `(points != NULL) && (n_points > 0)' failed
diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index dc2ad98..461b779 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -142,6 +142,8 @@ ghid_draw_grid (void)
       points[n].x = Vx (x);
       n++;
     }
+  if (n == 0)
+    return;
   for (y = y1; y <= y2; y += PCB->Grid)
     {
       int vy = Vy (y);
 | 
| 
      
      
      From: <gi...@gp...> - 2010-06-02 20:29:05
      
     | 
| The branch, master has been updated
       via  af2f50d4fb838de13dfbb5243e2114c66fefba7b (commit)
       via  4a44c883afc56747ea95522fcbdf9dc0b6a38952 (commit)
       via  91fd6d3ea006ebc9e9189d81e0211b7c2646dfb2 (commit)
      from  3d0a8bd1dae0816d364a774bf9b958faf2983ec7 (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/polygon1.c |   58 ++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 42 insertions(+), 16 deletions(-)
=================
 Commit Messages
=================
commit af2f50d4fb838de13dfbb5243e2114c66fefba7b
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix node_label() function to work with self-intersection
    
    Rather than just giving up if we encounter our own edges in the
    CVC list at first, skip them until we either run out of edges, or
    find one belonging to the other polygon.
    
    I'm not 100% sure this is the correct fix, but it "seems to work".
    
    Test-case:
    
    Layer(1 "component")
    (
      Line[60000 70000 60000 90000 4000 2000 "clearline"]
      Line[80000 60000 80000 90000 4000 2000 "clearline"]
      Line[90000 90000 90000 50000 4000 6000 "clearline"]
      Line[60000 40000 80000 60000 4000 6000 "clearline"]
      Polygon("clearpoly")
      (
        [10000 10000] [140000 10000] [140000 140000] [10000 140000]
      )
    )
:100644 100644 6a40752... a8a8b89... M	src/polygon1.c
commit 4a44c883afc56747ea95522fcbdf9dc0b6a38952
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix the polygon touching contour test in poly_ChkContour
    
    The following test-cases were used to help verify the changes:
    
    This polygon forms a self-touching shape like this:
    
    \|  However, the right-hand edge does NOT have a node at the junction.
    /|  This previously caused it to fail the self-intersection test.
        It should be reported as good.
    
    Polygon("")
      (
        [85000 50000] [85000 90000] [83000 90000]
        [83536 63535] [85000 59999] [83535 56464]
      )
    
    
    This polygon forms a self-intersecting shape like this:
    
     |/  (The vertical section is a straight line with no node in the middle)
    /|   It must be reported as bad.
    
    Polygon("")
      (
        [85000 50000] [85000 90000] [83000 90000]
        [83536 63535] [85000 59999] [89535 56464]
      )
    
    
    This polygon self-intersects, and must be reported as bad:
    
    Polygon("")
      (
        [160000  50000] [160000  90000] [170000 100000]
        [180000 120000] [180000 150000] [160000 150000]
        [160000 120000] [170000 100000] [180000  90000]
        [180000  50000]
      )
    
    This polygon self-touches, and should be reported as good:
    
    Polygon("clearpoly")
      (
        [120000  50000] [120000  90000] [130000 100000]
        [120000 120000] [120000 150000] [140000 150000]
        [140000 120000] [130000 100000] [140000  90000]
        [140000  50000]
      )
:100644 100644 f8ed16b... 6a40752... M	src/polygon1.c
commit 91fd6d3ea006ebc9e9189d81e0211b7c2646dfb2
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix poly_ComputeInteriorPoint() to work correctly for holes
    
    The step where the algorithm finds a convex node to start from must
    take into account whether the polygon vertices are ordered as a hole
    or an outer contour. We now correctly compute a point inside the hole,
    rather than possibly outside it.
    
    This fixes an assertion on the following test-case. Prior to this
    commit, the incorrect "interior" point tested for the concave hole
    happens to lie inside the polygon's other hole, causing it to fail
    an assert during processing.
    
    Layer(2 "solder")
    (
      Line[340000 160000 183700 108000 1500 3000 "clearline"]
      Line[92000 121000 120000 90000 1500 3000 "clearline"]
      Line[270000 90000 120000 90000 1500 3000 "clearline"]
      Polygon("clearpoly")
      (
        [40000 40000] [320000 40000] [320000 200000] [40000 200000]
      )
    )
    
    The bug was created in my attempt to speed up poly_ContourInContour:
    commit 3d0a8bd1dae0816d364a774bf9b958faf2983ec7
:100644 100644 31b71f1... f8ed16b... M	src/polygon1.c
=========
 Changes
=========
commit af2f50d4fb838de13dfbb5243e2114c66fefba7b
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix node_label() function to work with self-intersection
    
    Rather than just giving up if we encounter our own edges in the
    CVC list at first, skip them until we either run out of edges, or
    find one belonging to the other polygon.
    
    I'm not 100% sure this is the correct fix, but it "seems to work".
    
    Test-case:
    
    Layer(1 "component")
    (
      Line[60000 70000 60000 90000 4000 2000 "clearline"]
      Line[80000 60000 80000 90000 4000 2000 "clearline"]
      Line[90000 90000 90000 50000 4000 6000 "clearline"]
      Line[60000 40000 80000 60000 4000 6000 "clearline"]
      Polygon("clearpoly")
      (
        [10000 10000] [140000 10000] [140000 140000] [10000 140000]
      )
    )
diff --git a/src/polygon1.c b/src/polygon1.c
index 6a40752..a8a8b89 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -387,7 +387,7 @@ node_label
 static unsigned int
 node_label (VNODE * pn)
 {
-  CVCList *l;
+  CVCList *first_l, *l;
   char this_poly;
   int region = UNKNWN;
 
@@ -400,12 +400,15 @@ node_label (VNODE * pn)
    * and check if this edge (pn -> pn->next) is found between the other poly's entry and exit
    */
   if (pn->cvc_next->angle == pn->cvc_next->prev->angle)
-    {
-      l = pn->cvc_next->prev;
-      assert (l->poly != this_poly);
-    }
+    l = pn->cvc_next->prev;
   else
     l = pn->cvc_next->next;
+
+  first_l = l;
+  while ((l->poly == this_poly) && (l != first_l->prev))
+    l = l->next;
+  assert (l->poly != this_poly);
+
   assert (l && l->angle >= 0 && l->angle <= 4.0);
   if (l->poly != this_poly)
     {
commit 4a44c883afc56747ea95522fcbdf9dc0b6a38952
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix the polygon touching contour test in poly_ChkContour
    
    The following test-cases were used to help verify the changes:
    
    This polygon forms a self-touching shape like this:
    
    \|  However, the right-hand edge does NOT have a node at the junction.
    /|  This previously caused it to fail the self-intersection test.
        It should be reported as good.
    
    Polygon("")
      (
        [85000 50000] [85000 90000] [83000 90000]
        [83536 63535] [85000 59999] [83535 56464]
      )
    
    
    This polygon forms a self-intersecting shape like this:
    
     |/  (The vertical section is a straight line with no node in the middle)
    /|   It must be reported as bad.
    
    Polygon("")
      (
        [85000 50000] [85000 90000] [83000 90000]
        [83536 63535] [85000 59999] [89535 56464]
      )
    
    
    This polygon self-intersects, and must be reported as bad:
    
    Polygon("")
      (
        [160000  50000] [160000  90000] [170000 100000]
        [180000 120000] [180000 150000] [160000 150000]
        [160000 120000] [170000 100000] [180000  90000]
        [180000  50000]
      )
    
    This polygon self-touches, and should be reported as good:
    
    Polygon("clearpoly")
      (
        [120000  50000] [120000  90000] [130000 100000]
        [120000 120000] [120000 150000] [140000 150000]
        [140000 120000] [130000 100000] [140000  90000]
        [140000  50000]
      )
diff --git a/src/polygon1.c b/src/polygon1.c
index f8ed16b..6a40752 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2504,23 +2504,45 @@ poly_ChkContour (PLINE * a)
 	      else if (vect_dist2 (i1, a1->next->point) < EPSILON)
 		hit1 = a1->next;
 	      else
-		return TRUE;
+		hit1 = NULL;
 
 	      if (vect_dist2 (i1, a2->point) < EPSILON)
 		hit2 = a2;
 	      else if (vect_dist2 (i1, a2->next->point) < EPSILON)
 		hit2 = a2->next;
 	      else
-		return TRUE;
+		hit2 = NULL;
 
-#if 1
-	      /* now check if they are inside each other */
-	      if (inside_sector (hit1, hit2->prev->point) ||
-		  inside_sector (hit1, hit2->next->point) ||
-		  inside_sector (hit2, hit1->prev->point) ||
-		  inside_sector (hit2, hit1->next->point))
-		return TRUE;
-#endif
+	      if ((hit1 == NULL) && (hit2 == NULL))
+		{
+		  /* If the intersection didn't land on an end-point of either
+		   * line, we know the lines cross and we return TRUE.
+		   */
+		  return TRUE;
+		}
+	      else if (hit1 == NULL)
+		{
+		/* An end-point of the second line touched somewhere along the
+		   length of the first line. Check where the second line leads. */
+		  if (inside_sector (hit2, a1->point) !=
+		      inside_sector (hit2, a1->next->point))
+		    return TRUE;
+		}
+	      else if (hit2 == NULL)
+		{
+		/* An end-point of the first line touched somewhere along the
+		   length of the second line. Check where the first line leads. */
+		  if (inside_sector (hit1, a2->point) !=
+		      inside_sector (hit1, a2->next->point))
+		    return TRUE;
+		}
+	      else
+		{
+		/* Both lines intersect at an end-point. Check where they lead. */
+		  if (inside_sector (hit1, hit2->prev->point) !=
+		      inside_sector (hit1, hit2->next->point))
+		    return TRUE;
+		}
 	    }
 	}
       while ((a2 = a2->next) != &a->head);
commit 91fd6d3ea006ebc9e9189d81e0211b7c2646dfb2
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix poly_ComputeInteriorPoint() to work correctly for holes
    
    The step where the algorithm finds a convex node to start from must
    take into account whether the polygon vertices are ordered as a hole
    or an outer contour. We now correctly compute a point inside the hole,
    rather than possibly outside it.
    
    This fixes an assertion on the following test-case. Prior to this
    commit, the incorrect "interior" point tested for the concave hole
    happens to lie inside the polygon's other hole, causing it to fail
    an assert during processing.
    
    Layer(2 "solder")
    (
      Line[340000 160000 183700 108000 1500 3000 "clearline"]
      Line[92000 121000 120000 90000 1500 3000 "clearline"]
      Line[270000 90000 120000 90000 1500 3000 "clearline"]
      Polygon("clearpoly")
      (
        [40000 40000] [320000 40000] [320000 200000] [40000 200000]
      )
    )
    
    The bug was created in my attempt to speed up poly_ContourInContour:
    commit 3d0a8bd1dae0816d364a774bf9b958faf2983ec7
diff --git a/src/polygon1.c b/src/polygon1.c
index 31b71f1..f8ed16b 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2333,6 +2333,7 @@ poly_ComputeInteriorPoint (PLINE *poly, Vector v)
   VNODE *min_q = NULL;
   double dist;
   double min_dist;
+  double dir = (poly->Flags.orient == PLF_DIR) ? 1. : -1;
 
   /* Find a convex node on the polygon */
   pt1 = &poly->head;
@@ -2346,7 +2347,7 @@ poly_ComputeInteriorPoint (PLINE *poly, Vector v)
       dot_product = dot_orthogonal_to_direction (pt1->point, pt2->point,
                                                  pt3->point, pt2->point);
 
-      if (dot_product > 0.)
+      if (dot_product * dir > 0.)
         break;
     }
   while ((pt1 = pt1->next) != &poly->head);
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-11 15:01:26
      
     | 
| The branch, master has been updated
       via  3d0a8bd1dae0816d364a774bf9b958faf2983ec7 (commit)
       via  bbe5aa52e540171a08f905e38468623a0d3f2e1c (commit)
       via  4ba4e750b297d860a1264a59d3e418dfc9a6c635 (commit)
      from  3a1995275e31d4211e3dc5a5c696ecb5ed42437f (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/polygon1.c |  146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 145 insertions(+), 1 deletions(-)
=================
 Commit Messages
=================
commit 3d0a8bd1dae0816d364a774bf9b958faf2983ec7
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Speed up poly_ContourInContour() test by computing interior point
    
    NB: This introduces a behaviour change in the boundary case, that two
    identical contours will now be considered to be inside each other.
    
    First perform a test on an arbitrary boundary node (proving that the
    contour being testing for "insideness" is not outside the other
    contour. (This cannot not conclusively prove the contour is inside).
    
    In many cases, this simple node test gives enough evidence to return 0
    for the ContourInContour test computing and testing an interior point.
    
    Rather than checking each exterior point, compute a strictly interior
    point (not on the boundary), and test that against the second contour.
    
    Benchmarked to improve performance over other fixes for the buggy test.
    Example board load (CPU) times for a complex board:
    
      21.50 (buggy contour_in_contour - single node point test)
      24.43 (brute-force node point tests)
      21.79 (single node test, then internal point test)
:100644 100644 57bea9c... 31b71f1... M	src/polygon1.c
commit bbe5aa52e540171a08f905e38468623a0d3f2e1c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix poly_ContourInContour() test not to return TRUE for touching contours
    
    This test could previously return true for touching contours, such as:
     __________....
    |_________ |  :
    :........ ||  :
    ::  /\  : ||  :   Note that the bounding box of A is inside that of B,
    :: /  \ :/  \ :   such that initial bounding box checks won't reject the
    ::/ A  \/  B \:   possibility of A being inside B.
    ::\    /\    /:
    :: \  / :\  / :
    ::..\/..:.\/..:
    
    When testing for insideness, the first point on A's contour is picked.
    In this case, unfortunately being the touching X point between the two
    contours. This point (correctly) returns as being inside B - and the
    false presumption is that the whole A contour is inside B.
    
    This commit introduces an unfortunately slow, but more robust test,
    where we check each node in A for whether it is inside B. We return
    as soon as we find an A node outside B, however this means the test
    is VERY much slower for the case where A _is_ inside B.
:100644 100644 b325fb5... 57bea9c... M	src/polygon1.c
commit 4ba4e750b297d860a1264a59d3e418dfc9a6c635
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Add comment explaining assumptions for poly_ContourInContour function
    
    Also, document its buggy boundary condition where the arbitrary point
    chosen to test happens to be a common node shared between two separate
    contours (which the test should return FALSE for).
:100644 100644 d9f6ce4... b325fb5... M	src/polygon1.c
=========
 Changes
=========
commit 3d0a8bd1dae0816d364a774bf9b958faf2983ec7
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Speed up poly_ContourInContour() test by computing interior point
    
    NB: This introduces a behaviour change in the boundary case, that two
    identical contours will now be considered to be inside each other.
    
    First perform a test on an arbitrary boundary node (proving that the
    contour being testing for "insideness" is not outside the other
    contour. (This cannot not conclusively prove the contour is inside).
    
    In many cases, this simple node test gives enough evidence to return 0
    for the ContourInContour test computing and testing an interior point.
    
    Rather than checking each exterior point, compute a strictly interior
    point (not on the boundary), and test that against the second contour.
    
    Benchmarked to improve performance over other fixes for the buggy test.
    Example board load (CPU) times for a complex board:
    
      21.50 (buggy contour_in_contour - single node point test)
      24.43 (brute-force node point tests)
      21.79 (single node test, then internal point test)
diff --git a/src/polygon1.c b/src/polygon1.c
index 57bea9c..31b71f1 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2254,31 +2254,156 @@ poly_M_CheckInside (POLYAREA * p, Vector v0)
   return FALSE;
 }
 
+static double
+dot (Vector A, Vector B)
+{
+  return (double)A[0] * (double)B[0] + (double)A[1] * (double)B[1];
+}
+
+/* Compute whether point is inside a triangle formed by 3 other pints */
+/* Algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html */
+static int
+point_in_triangle (Vector A, Vector B, Vector C, Vector P)
+{
+  Vector v0, v1, v2;
+  double dot00, dot01, dot02, dot11, dot12;
+  double invDenom;
+  double u, v;
+
+  /* Compute vectors */
+  v0[0] = C[0] - A[0];  v0[1] = C[1] - A[1];
+  v1[0] = B[0] - A[0];  v1[1] = B[1] - A[1];
+  v2[0] = P[0] - A[0];  v2[1] = P[1] - A[1];
+
+  /* Compute dot products */
+  dot00 = dot (v0, v0);
+  dot01 = dot (v0, v1);
+  dot02 = dot (v0, v2);
+  dot11 = dot (v1, v1);
+  dot12 = dot (v1, v2);
+
+  /* Compute barycentric coordinates */
+  invDenom = 1. / (dot00 * dot11 - dot01 * dot01);
+  u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+  v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+  /* Check if point is in triangle */
+  return (u > 0.0) && (v > 0.0) && (u + v < 1.0);
+}
+
+
+/* Returns the dot product of Vector A->B, and a vector
+ * orthogonal to Vector C->D. The result is not normalisd, so will be
+ * weighted by the magnitude of the C->D vector.
+ */
+static double
+dot_orthogonal_to_direction (Vector A, Vector B, Vector C, Vector D)
+{
+  Vector l1, l2, l3;
+  l1[0] = B[0] - A[0];  l1[1] = B[1] - A[1];
+  l2[0] = D[0] - C[0];  l2[1] = D[1] - C[1];
+
+  l3[0] = -l2[1];
+  l3[1] = l2[0];
+
+  return dot (l1, l3);
+}
+
+/* Algorithm from http://www.exaflop.org/docs/cgafaq/cga2.html
+ *
+ * "Given a simple polygon, find some point inside it. Here is a method based
+ * on the proof that there exists an internal diagonal, in [O'Rourke, 13-14].
+ * The idea is that the midpoint of a diagonal is interior to the polygon.
+ *
+ * 1.  Identify a convex vertex v; let its adjacent vertices be a and b.
+ * 2.  For each other vertex q do:
+ * 2a. If q is inside avb, compute distance to v (orthogonal to ab).
+ * 2b. Save point q if distance is a new min.
+ * 3.  If no point is inside, return midpoint of ab, or centroid of avb.
+ * 4.  Else if some point inside, qv is internal: return its midpoint."
+ *
+ * [O'Rourke]: Computational Geometry in C (2nd Ed.)
+ *             Joseph O'Rourke, Cambridge University Press 1998,
+ *             ISBN 0-521-64010-5 Pbk, ISBN 0-521-64976-5 Hbk
+ */
+static void
+poly_ComputeInteriorPoint (PLINE *poly, Vector v)
+{
+  VNODE *pt1, *pt2, *pt3, *q;
+  VNODE *min_q = NULL;
+  double dist;
+  double min_dist;
+
+  /* Find a convex node on the polygon */
+  pt1 = &poly->head;
+  do
+    {
+      double dot_product;
+
+      pt2 = pt1->next;
+      pt3 = pt2->next;
+
+      dot_product = dot_orthogonal_to_direction (pt1->point, pt2->point,
+                                                 pt3->point, pt2->point);
+
+      if (dot_product > 0.)
+        break;
+    }
+  while ((pt1 = pt1->next) != &poly->head);
+
+  /* Loop over remaining vertices */
+  q = pt3;
+  do
+    {
+      /* Is current vertex "q" outside pt1 pt2 pt3 triangle? */
+      if (!point_in_triangle (pt1->point, pt2->point, pt3->point, q->point))
+        continue;
+
+      /* NO: compute distance to pt2 (v) orthogonal to pt1 - pt3) */
+      /*     Record minimum */
+      dist = dot_orthogonal_to_direction (q->point, pt2->point, pt1->point, pt3->point);
+      if (min_q == NULL || dist < min_dist) {
+        min_dist = dist;
+        min_q = q;
+      }
+    }
+  while ((q = q->next) != pt2);
+
+  /* Were any "q" found inside pt1 pt2 pt3? */
+  if (min_q == NULL) {
+    /* NOT FOUND: Return midpoint of pt1 pt3 */
+    v[0] = (pt1->point[0] + pt3->point[0]) / 2;
+    v[1] = (pt1->point[1] + pt3->point[1]) / 2;
+  } else {
+    /* FOUND: Return mid point of min_q, pt2 */
+    v[0] = (pt2->point[0] + min_q->point[0]) / 2;
+    v[1] = (pt2->point[1] + min_q->point[1]) / 2;
+  }
+}
+
+
 /* NB: This function assumes the caller _knows_ the contours do not
  *     intersect. If the contours intersect, the result is undefined.
  *     It will return the correct result if the two contours share
  *     common points beteween their contours. (Identical contours
- *     are treated as being not inside each other).
+ *     are treated as being inside each other).
  */
 int
 poly_ContourInContour (PLINE * poly, PLINE * inner)
 {
-  VNODE *pt;
+  Vector point;
   assert (poly != NULL);
   assert (inner != NULL);
   if (cntrbox_inside (inner, poly))
-    { /* FIXME: This is SLOW!!
-       * Check all points on the contour being tested, because we don't
-       * want to falsely return that two contours are inside each other
-       * if they just touch at a few points.
+    {
+      /* We need to prove the "inner" contour is not outside
+       * "poly" contour. If it is outside, we can return.
        */
-      pt = &inner->head;
-      do
-        {
-          if (!poly_InsideContour (poly, pt->point))
-            return 0;
-        } while ((pt = pt->next) != &inner->head);
-      return 1;
+      if (!poly_InsideContour (poly, inner->head.point))
+        return 0;
+
+      poly_ComputeInteriorPoint (inner, point);
+      return poly_InsideContour (poly, point);
     }
   return 0;
 }
commit bbe5aa52e540171a08f905e38468623a0d3f2e1c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Fix poly_ContourInContour() test not to return TRUE for touching contours
    
    This test could previously return true for touching contours, such as:
     __________....
    |_________ |  :
    :........ ||  :
    ::  /\  : ||  :   Note that the bounding box of A is inside that of B,
    :: /  \ :/  \ :   such that initial bounding box checks won't reject the
    ::/ A  \/  B \:   possibility of A being inside B.
    ::\    /\    /:
    :: \  / :\  / :
    ::..\/..:.\/..:
    
    When testing for insideness, the first point on A's contour is picked.
    In this case, unfortunately being the touching X point between the two
    contours. This point (correctly) returns as being inside B - and the
    false presumption is that the whole A contour is inside B.
    
    This commit introduces an unfortunately slow, but more robust test,
    where we check each node in A for whether it is inside B. We return
    as soon as we find an A node outside B, however this means the test
    is VERY much slower for the case where A _is_ inside B.
diff --git a/src/polygon1.c b/src/polygon1.c
index b325fb5..57bea9c 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2256,16 +2256,30 @@ poly_M_CheckInside (POLYAREA * p, Vector v0)
 
 /* NB: This function assumes the caller _knows_ the contours do not
  *     intersect. If the contours intersect, the result is undefined.
- *     This function can return an incorrect (positive) result if the
- *     contours share a common node at the arbitrary point tested.
+ *     It will return the correct result if the two contours share
+ *     common points beteween their contours. (Identical contours
+ *     are treated as being not inside each other).
  */
 int
 poly_ContourInContour (PLINE * poly, PLINE * inner)
 {
+  VNODE *pt;
   assert (poly != NULL);
   assert (inner != NULL);
   if (cntrbox_inside (inner, poly))
-    return poly_InsideContour (poly, inner->head.point);
+    { /* FIXME: This is SLOW!!
+       * Check all points on the contour being tested, because we don't
+       * want to falsely return that two contours are inside each other
+       * if they just touch at a few points.
+       */
+      pt = &inner->head;
+      do
+        {
+          if (!poly_InsideContour (poly, pt->point))
+            return 0;
+        } while ((pt = pt->next) != &inner->head);
+      return 1;
+    }
   return 0;
 }
 
commit 4ba4e750b297d860a1264a59d3e418dfc9a6c635
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Add comment explaining assumptions for poly_ContourInContour function
    
    Also, document its buggy boundary condition where the arbitrary point
    chosen to test happens to be a common node shared between two separate
    contours (which the test should return FALSE for).
diff --git a/src/polygon1.c b/src/polygon1.c
index d9f6ce4..b325fb5 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2254,6 +2254,11 @@ poly_M_CheckInside (POLYAREA * p, Vector v0)
   return FALSE;
 }
 
+/* NB: This function assumes the caller _knows_ the contours do not
+ *     intersect. If the contours intersect, the result is undefined.
+ *     This function can return an incorrect (positive) result if the
+ *     contours share a common node at the arbitrary point tested.
+ */
 int
 poly_ContourInContour (PLINE * poly, PLINE * inner)
 {
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-10 22:03:16
      
     | 
| The branch, master has been updated
       via  3a1995275e31d4211e3dc5a5c696ecb5ed42437f (commit)
      from  d5b7cbd4910e71e9c8130d99664924773551e345 (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
=========
 configure.ac |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)
=================
 Commit Messages
=================
commit 3a1995275e31d4211e3dc5a5c696ecb5ed42437f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Make --enable-dbus default for the GTK and Lesstif HIDs
:100644 100644 4e9476d... a220a82... M	configure.ac
=========
 Changes
=========
commit 3a1995275e31d4211e3dc5a5c696ecb5ed42437f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Make --enable-dbus default for the GTK and Lesstif HIDs
diff --git a/configure.ac b/configure.ac
index 4e9476d..a220a82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -353,7 +353,13 @@ fi
 AC_MSG_CHECKING([for whether to use DBUS])
 AC_ARG_ENABLE([dbus],
 [  --enable-dbus           Enable DBUS IPC],
-[],[enable_dbus=no])
+[],[
+	case " $with_gui " in
+		*\ gtk\ *)     enable_dbus=yes ;;
+		*\ lesstif\ *) enable_dbus=yes ;;
+		* )            enable_dbus=no ;;
+	esac
+])
 
 AC_MSG_RESULT([$enable_dbus])
 AM_CONDITIONAL(WITH_DBUS, test x$enable_dbus = xyes)
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-10 21:52:01
      
     | 
| The branch, master has been updated
       via  d5b7cbd4910e71e9c8130d99664924773551e345 (commit)
      from  53cc7df40f934a769def0be79a2ac4fe1aa84e53 (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/main.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
=================
 Commit Messages
=================
commit d5b7cbd4910e71e9c8130d99664924773551e345
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Allow running of action scripts when running PCB as an exporter
:100644 100644 7e29d56... 8b80afe... M	src/main.c
=========
 Changes
=========
commit d5b7cbd4910e71e9c8130d99664924773551e345
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Allow running of action scripts when running PCB as an exporter
diff --git a/src/main.c b/src/main.c
index 7e29d56..8b80afe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -998,12 +998,6 @@ main (int argc, char *argv[])
       LayerStringToLayerStack (Settings.InitialLayerStack);
     }
 
-  if (gui->printer || gui->exporter)
-    {
-      gui->do_export (0);
-      exit (0);
-    }
-
   /*    FIX_ME
      LoadBackgroundImage (Settings.BackgroundImage); */
 
@@ -1036,6 +1030,12 @@ main (int argc, char *argv[])
       hid_parse_actions (Settings.ActionString);
     }
 
+  if (gui->printer || gui->exporter)
+    {
+      gui->do_export (0);
+      exit (0);
+    }
+
 #if HAVE_DBUS
   pcb_dbus_setup();
 #endif
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-10 21:51:00
      
     | 
| The branch, master has been updated
       via  53cc7df40f934a769def0be79a2ac4fe1aa84e53 (commit)
      from  d82a597eacc4475ef12e2c995acda734bd1a2e59 (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/polygon1.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
=================
 Commit Messages
=================
commit 53cc7df40f934a769def0be79a2ac4fe1aa84e53
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Improve dump_poly() output
    
    Make it print each contour of a POLYAREA, and move the NEXT PLINE
    and NEXT POLY messages inside the loops interating over these
    structures.
:100644 100644 2ffd7cb... d9f6ce4... M	src/polygon1.c
=========
 Changes
=========
commit 53cc7df40f934a769def0be79a2ac4fe1aa84e53
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    Improve dump_poly() output
    
    Make it print each contour of a POLYAREA, and move the NEXT PLINE
    and NEXT POLY messages inside the loops interating over these
    structures.
diff --git a/src/polygon1.c b/src/polygon1.c
index 2ffd7cb..d9f6ce4 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -142,20 +142,26 @@ pline_dump (VNODE * v)
 	       n->point[0], n->point[1], theState (v));
     }
   while ((v = v->next) != s);
-  fprintf (stderr, "NEXT PLINE\n");
 }
 
 static void
 poly_dump (POLYAREA * p)
 {
   POLYAREA *f = p;
+  PLINE *pl;
 
   do
     {
-      pline_dump (&p->contours->head);
+      pl = p->contours;
+      do
+        {
+          pline_dump (&pl->head);
+          fprintf (stderr, "NEXT PLINE\n");
+        }
+      while ((pl = pl->next) != NULL);
+      fprintf (stderr, "NEXT POLY\n");
     }
   while ((p = p->f) != f);
-  fprintf (stderr, "NEXT_POLY\n");
 }
 #endif
 
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-10 17:05:49
      
     | 
| The branch, master has been updated
       via  d82a597eacc4475ef12e2c995acda734bd1a2e59 (commit)
      from  1f8c04454e49981f0fa9dbb80b59532247f7113b (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/gtk/gui-output-events.c |  132 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 132 insertions(+), 0 deletions(-)
=================
 Commit Messages
=================
commit d82a597eacc4475ef12e2c995acda734bd1a2e59
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    hid/gtk: Add tool-tip to identify element, pin and net when hovering
:100644 100644 86abad2... 3912aa3... M	src/hid/gtk/gui-output-events.c
=========
 Changes
=========
commit d82a597eacc4475ef12e2c995acda734bd1a2e59
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
    hid/gtk: Add tool-tip to identify element, pin and net when hovering
diff --git a/src/hid/gtk/gui-output-events.c b/src/hid/gtk/gui-output-events.c
index 86abad2..3912aa3 100644
--- a/src/hid/gtk/gui-output-events.c
+++ b/src/hid/gtk/gui-output-events.c
@@ -44,11 +44,16 @@
 #include "error.h"
 #include "misc.h"
 #include "set.h"
+#include "find.h"
+#include "search.h"
+#include "rats.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
 #endif
 
+#define TOOLTIP_UPDATE_DELAY 200
+
 RCSID ("$Id$");
 
 static gint x_pan_speed, y_pan_speed;
@@ -742,6 +747,128 @@ ghid_port_drawing_area_expose_event_cb (GtkWidget * widget,
   return FALSE;
 }
 
+#if GTK_CHECK_VERSION(2,12,0)
+# define ENABLE_TOOLTIPS 1
+#else
+# define ENABLE_TOOLTIPS 0
+#endif
+
+#if ENABLE_TOOLTIPS
+static char *
+describe_location (LocationType X, LocationType Y)
+{
+  void *ptr1, *ptr2, *ptr3;
+  int type;
+  int Range = 0;
+  char *elename = "";
+  char *pinname;
+  char *netname = NULL;
+  char *description;
+
+  /* check if there are any pins or pads at that position */
+
+  type = SearchObjectByLocation (PIN_TYPE | PAD_TYPE,
+                                 &ptr1, &ptr2, &ptr3, X, Y, Range);
+  if (type == NO_TYPE)
+    return NULL;
+
+  /* don't mess with silk objects! */
+  if (type & SILK_TYPE &&
+      GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1) >= max_layer)
+    return NULL;
+
+  if (type == PIN_TYPE || type == PAD_TYPE)
+    elename = UNKNOWN (NAMEONPCB_NAME ((ElementTypePtr) ptr1));
+
+  pinname = ConnectionName (type, ptr1, ptr2);
+
+  if (pinname == NULL)
+    return NULL;
+
+  /* Find netlist entry */
+  MENU_LOOP (&PCB->NetlistLib);
+  {
+    if (!menu->Name)
+    continue;
+
+    ENTRY_LOOP (menu);
+    {
+      if (!entry->ListEntry)
+        continue;
+
+      if (strcmp (entry->ListEntry, pinname) == 0) {
+        netname = g_strdup (menu->Name);
+        /* For some reason, the netname has spaces in front of it, strip them */
+        g_strstrip (netname);
+        break;
+      }
+    }
+    END_LOOP;
+
+    if (netname != NULL)
+      break;
+  }
+  END_LOOP;
+
+  description = g_strdup_printf ("Element name: %s\n"
+                                 "Pinname : %s\n"
+                                 "Netname : %s",
+                                 elename,
+                                 (pinname != NULL) ? pinname : "--",
+                                 (netname != NULL) ? netname : "--");
+
+  g_free (netname);
+
+  return description;
+}
+
+
+static gboolean check_object_tooltips (GHidPort *out)
+{
+  char *description;
+
+  /* check if there are any pins or pads at that position */
+  description = describe_location (out->x_crosshair, out->y_crosshair);
+
+  if (description == NULL)
+    return FALSE;
+
+  gtk_widget_set_tooltip_text (out->drawing_area, description);
+  g_free (description);
+
+  return FALSE;
+}
+
+static int tooltip_update_timeout_id = 0;
+
+static void
+cancel_tooltip_update ()
+{
+  if (tooltip_update_timeout_id)
+    g_source_remove (tooltip_update_timeout_id);
+  tooltip_update_timeout_id = 0;
+}
+
+/* FIXME: If the GHidPort is ever destroyed, we must call
+ * cancel_tooltip_update (), otherwise the timeout might
+ * fire after the data it utilises has been free'd.
+ */
+static void
+queue_tooltip_update (GHidPort *out)
+{
+  /* Zap the old tool-tip text and force it to be removed from the screen */
+  gtk_widget_set_tooltip_text (out->drawing_area, NULL);
+  gtk_widget_trigger_tooltip_query (out->drawing_area);
+
+  cancel_tooltip_update ();
+
+  tooltip_update_timeout_id =
+      g_timeout_add (TOOLTIP_UPDATE_DELAY,
+                     (GSourceFunc) check_object_tooltips,
+                     out);
+}
+#endif
+
 gint
 ghid_port_window_motion_cb (GtkWidget * widget,
 			    GdkEventButton * ev, GHidPort * out)
@@ -764,6 +891,11 @@ ghid_port_window_motion_cb (GtkWidget * widget,
     }
   x_prev = y_prev = -1;
   moved = ghid_note_event_location (ev);
+
+#if ENABLE_TOOLTIPS
+  queue_tooltip_update (out);
+#endif
+
   ghid_show_crosshair (TRUE);
   if (moved && have_crosshair_attachments ())
     ghid_draw_area_update (gport, NULL);
 | 
| 
      
      
      From: <gi...@gp...> - 2010-05-10 03:50:51
      
     | 
| The branch, master has been updated
       via  1f8c04454e49981f0fa9dbb80b59532247f7113b (commit)
      from  9c86b37b279deb15128761cf809e94d7bb51fcd1 (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/gpcb-menu.res |   16 ++++++++--------
 src/pcb-menu.res  |   16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)
=================
 Commit Messages
=================
commit 1f8c04454e49981f0fa9dbb80b59532247f7113b
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Clarify the meaning of keys bound to SetValue()
    
    Clarifies that keys which are bound to SetValue change
    the styles, not the existing objects, so they really affect
    *new* objects.
:100644 100644 17a0fbf... 1511e09... M	src/gpcb-menu.res
:100644 100644 b326a04... c18eb86... M	src/pcb-menu.res
=========
 Changes
=========
commit 1f8c04454e49981f0fa9dbb80b59532247f7113b
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Clarify the meaning of keys bound to SetValue()
    
    Clarifies that keys which are bound to SetValue change
    the styles, not the existing objects, so they really affect
    *new* objects.
diff --git a/src/gpcb-menu.res b/src/gpcb-menu.res
index 17a0fbf..1511e09 100644
--- a/src/gpcb-menu.res
+++ b/src/gpcb-menu.res
@@ -412,8 +412,8 @@ MainMenu =
     {"Clear Object -2 mil" a={"Shift-K" "Shift<Key>k"} ChangeClearSize(Object,-2,mil)}
     {"Clear Selected +2 mil" a={"Ctrl-K" "Ctrl<Key>k"} ChangeClearSize(SelectedObjects,+2,mil)}
     {"Clear Selected -2 mil" a={"Shift-Ctrl-K" "Shift Ctrl<Key>k"} ChangeClearSize(SelectedObjects,-2,mil)}
-    {"Linesize +5 mil" a={"L" "<Key>l"} SetValue(LineSize,+5,mil)}
-    {"Linesize -5 mil" a={"Shift-L" "Shift<Key>l"} SetValue(LineSize,-5,mil)}
+    {"Line Tool size +5 mil" a={"L" "<Key>l"} SetValue(LineSize,+5,mil)}
+    {"Line Tool size -5 mil" a={"Shift-L" "Shift<Key>l"} SetValue(LineSize,-5,mil)}
     {"MarkCrosshair" a={"Ctrl-M" "Ctrl<Key>m"} MarkCrosshair()}
     {"Select shortest rat" a={"Shift-N" "Shift<Key>n"} AddRats(Close)}
     {"AddRats to selected pins" a={"Shift-O" "Shift<Key>o"}
@@ -430,12 +430,12 @@ MainMenu =
     {"ChangeSize -5 mil" a={"Shift-S" "Shift<Key>s"} ChangeSize(Object,-5,mil)}
     {"ChangeDrill +5 mil" a={"Alt-S" "Alt<Key>s"} ChangeDrillSize(Object,+5,mil)}
     {"ChangeDrill -5 mil" a={"Alt-Shift-S" "Alt Shift<Key>s"} ChangeDrillSize(Object,-5,mil)}
-    {"TextScale +10 mil" a={"T" "<Key>t"} SetValue(TextScale,+10,mil)}
-    {"TextScale -10 mil" a={"Shift-T" "Shift<Key>t"} SetValue(TextScale,-10,mil)}
-    {"ViaSize +5 mil" a={"Shift-V" "Shift<Key>v"} SetValue(ViaSize,+5,mil)}
-    {"ViaSize -5 mil" a={"Shift-Ctrl-V" "Shift Ctrl<Key>v"} SetValue(ViaSize,-5,mil)}
-    {"ViaDrill +5 mil" a={"Alt-V" "Alt<Key>v"} SetValue(ViaDrillingHole,+5,mil)}
-    {"ViaDrill -5 mil" a={"Alt-Shift-V" "Alt Shift<Key>v"} SetValue(ViaDrillingHole,-5,mil)}
+    {"Text Tool scale +10 mil" a={"T" "<Key>t"} SetValue(TextScale,+10,mil)}
+    {"Text Tool scale -10 mil" a={"Shift-T" "Shift<Key>t"} SetValue(TextScale,-10,mil)}
+    {"Via Tool size +5 mil" a={"Shift-V" "Shift<Key>v"} SetValue(ViaSize,+5,mil)}
+    {"Via Tool size -5 mil" a={"Shift-Ctrl-V" "Shift Ctrl<Key>v"} SetValue(ViaSize,-5,mil)}
+    {"Via Tool drill +5 mil" a={"Alt-V" "Alt<Key>v"} SetValue(ViaDrillingHole,+5,mil)}
+    {"Via Tool drill -5 mil" a={"Alt-Shift-V" "Alt Shift<Key>v"} SetValue(ViaDrillingHole,-5,mil)}
     {"AddRats Selected" a={"Shift-W" "Shift<Key>w"} AddRats(SelectedRats)}
     {"Add All Rats" a={"W" "<Key>w"} AddRats(AllRats)}
     {"Cycle Clip" a={"/" "<Key>/"} Display(CycleClip)}
diff --git a/src/pcb-menu.res b/src/pcb-menu.res
index b326a04..c18eb86 100644
--- a/src/pcb-menu.res
+++ b/src/pcb-menu.res
@@ -379,8 +379,8 @@ MainMenu =
     {"Clear Object -2 mil" a={"Shift-K" "Shift<Key>k"} ChangeClearSize(Object,-2,mil)}
     {"Clear Selected +2 mil" a={"Ctrl-K" "Ctrl<Key>k"} ChangeClearSize(SelectedObjects,+2,mil)}
     {"Clear Selected -2 mil" a={"Shift-Ctrl-K" "Shift Ctrl<Key>k"} ChangeClearSize(SelectedObjects,-2,mil)}
-    {"Linesize +5 mil" a={"L" "<Key>l"} SetValue(LineSize,+5,mil)}
-    {"Linesize -5 mil" a={"Shift-L" "Shift<Key>l"} SetValue(LineSize,-5,mil)}
+    {"Line Tool size +5 mil" a={"L" "<Key>l"} SetValue(LineSize,+5,mil)}
+    {"Line Tool size -5 mil" a={"Shift-L" "Shift<Key>l"} SetValue(LineSize,-5,mil)}
     {"MarkCrosshair" a={"Ctrl-M" "Ctrl<Key>m"} MarkCrosshair()}
     {"Select shortest rat" a={"Shift-N" "Shift<Key>n"} AddRats(Close)}
     {"AddRats to selected pins" a={"Shift-O" "Shift<Key>o"}
@@ -397,12 +397,12 @@ MainMenu =
     {"ChangeSize -5 mil" a={"Shift-S" "Shift<Key>s"} ChangeSize(Object,-5,mil)}
     {"ChangeDrill +5 mil" a={"Alt-S" "Alt<Key>s"} ChangeDrillSize(Object,+5,mil)}
     {"ChangeDrill -5 mil" a={"Alt-Shift-S" "Alt Shift<Key>s"} ChangeDrillSize(Object,-5,mil)}
-    {"TextScale +10 mil" a={"T" "<Key>t"} SetValue(TextScale,+10,mil)}
-    {"TextScale -10 mil" a={"Shift-T" "Shift<Key>t"} SetValue(TextScale,-10,mil)}
-    {"ViaSize +5 mil" a={"Shift-V" "Shift<Key>v"} SetValue(ViaSize,+5,mil)}
-    {"ViaSize -5 mil" a={"Shift-Ctrl-V" "Shift Ctrl<Key>v"} SetValue(ViaSize,-5,mil)}
-    {"ViaDrill +5 mil" a={"Alt-V" "Alt<Key>v"} SetValue(ViaDrillingHole,+5,mil)}
-    {"ViaDrill -5 mil" a={"Alt-Shift-V" "Alt Shift<Key>v"} SetValue(ViaDrillingHole,-5,mil)}
+    {"Text Tool scale +10 mil" a={"T" "<Key>t"} SetValue(TextScale,+10,mil)}
+    {"Text Tool scale -10 mil" a={"Shift-T" "Shift<Key>t"} SetValue(TextScale,-10,mil)}
+    {"Via Tool size +5 mil" a={"Shift-V" "Shift<Key>v"} SetValue(ViaSize,+5,mil)}
+    {"Via Tool size -5 mil" a={"Shift-Ctrl-V" "Shift Ctrl<Key>v"} SetValue(ViaSize,-5,mil)}
+    {"Via Tool drill +5 mil" a={"Alt-V" "Alt<Key>v"} SetValue(ViaDrillingHole,+5,mil)}
+    {"Via Tool drill -5 mil" a={"Alt-Shift-V" "Alt Shift<Key>v"} SetValue(ViaDrillingHole,-5,mil)}
     {"AddRats Selected" a={"Shift-W" "Shift<Key>w"} AddRats(SelectedRats)}
     {"Add All Rats" a={"W" "<Key>w"} AddRats(AllRats)}
     {"Undo" a={"Alt-Z" "Alt<Key>z"} Undo()}
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-23 20:58:08
      
     | 
| The branch, master has been updated
       via  20c22af4437f3f054e3d09a598c74630ff42d064 (commit)
      from  db06c2c7a74cdf44a3e84482ba980d1a45b7e2d4 (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/gtk/gtkhid-main.c |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)
=================
 Commit Messages
=================
commit 20c22af4437f3f054e3d09a598c74630ff42d064
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Allow for only one confirm button.
    
    The GTK confirm_dialog() hook now supports the user passing only one
    button.  Before, if you passed just "ok" it would create two OK buttons.
:100644 100644 fb2aff1... 90d1485... M	src/hid/gtk/gtkhid-main.c
=========
 Changes
=========
commit 20c22af4437f3f054e3d09a598c74630ff42d064
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Allow for only one confirm button.
    
    The GTK confirm_dialog() hook now supports the user passing only one
    button.  Before, if you passed just "ok" it would create two OK buttons.
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index fb2aff1..90d1485 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -785,9 +785,12 @@ ghid_stop_block_hook (hidval mlpoll)
 int
 ghid_confirm_dialog (char *msg, ...)
 {
-  int rv;
+  int rv = 0;
   va_list ap;
   char *cancelmsg = NULL, *okmsg = NULL;
+  static gint x = -1, y = -1;
+  GtkWidget *dialog;
+  GHidPort *out = &ghid_port;
 
   va_start (ap, msg);
   cancelmsg = va_arg (ap, char *);
@@ -799,13 +802,31 @@ ghid_confirm_dialog (char *msg, ...)
       cancelmsg = _("_Cancel");
       okmsg = _("_OK");
     }
-  if (!okmsg)
+
+  dialog = gtk_message_dialog_new (GTK_WINDOW (out->top_window),
+				   GTK_DIALOG_MODAL |
+				   GTK_DIALOG_DESTROY_WITH_PARENT,
+				   GTK_MESSAGE_QUESTION,
+				   GTK_BUTTONS_NONE,
+				   "%s", msg);
+  gtk_dialog_add_button (GTK_DIALOG (dialog), 
+			  cancelmsg, GTK_RESPONSE_CANCEL);
+  if (okmsg)
     {
-      okmsg = _("_OK");
+      gtk_dialog_add_button (GTK_DIALOG (dialog), 
+			     okmsg, GTK_RESPONSE_OK);
     }
 
-  rv = ghid_dialog_confirm (msg, cancelmsg, okmsg);
+  if(x != -1) {
+  	gtk_window_move(GTK_WINDOW (dialog), x, y);
+  }
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+    rv = 1;
+
+  gtk_window_get_position(GTK_WINDOW (dialog), &x, &y);
 
+  gtk_widget_destroy (dialog);
   return rv;
 }
 
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-23 19:28:41
      
     | 
| The branch, master has been updated
       via  db06c2c7a74cdf44a3e84482ba980d1a45b7e2d4 (commit)
      from  50d058ba2ca3403a6fbacf3885160806f448a3dc (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/change.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
=================
 Commit Messages
=================
commit db06c2c7a74cdf44a3e84482ba980d1a45b7e2d4
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Add hint about :MinClearGap(Selected,=10,mil)
    
    Add a hint to the user about how to change the clearance of a group of
    objects.
:100644 100644 f2bcd40... 4d42bc3... M	src/change.c
=========
 Changes
=========
commit db06c2c7a74cdf44a3e84482ba980d1a45b7e2d4
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Add hint about :MinClearGap(Selected,=10,mil)
    
    Add a hint to the user about how to change the clearance of a group of
    objects.
diff --git a/src/change.c b/src/change.c
index f2bcd40..4d42bc3 100644
--- a/src/change.c
+++ b/src/change.c
@@ -751,7 +751,10 @@ ChangePolygonClearSize (LayerTypePtr Layer, PolygonTypePtr poly)
   if (!shown_this_message)
     {
       gui->confirm_dialog ("To change the clearance of objects in a polygon, "
-			   "change the objects, not the polygon.", "Ok", NULL);
+			   "change the objects, not the polygon.\n"
+			   "Hint: To set a minimum clearance for a group of objects, "
+			   "select them all then :MinClearGap(Selected,=10,mil)",
+			   "Ok", NULL);
       shown_this_message = 1;
     }
 
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-23 19:07:41
      
     | 
| The branch, master has been updated
       via  50d058ba2ca3403a6fbacf3885160806f448a3dc (commit)
      from  6772dffe97136dadfb38c56e1ccbf83250e60185 (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/change.c |   20 +++++++++++++++++++-
 src/change.h |    3 ++-
 2 files changed, 21 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit 50d058ba2ca3403a6fbacf3885160806f448a3dc
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Handle attempts to change clearance on polygons.
    
    If the user attempts to change the clearance between polygons and
    objects within the polygon by pressing 'k' over the *polygon*, notice
    that attemp and tell the user how to accomplish what they want.
:100644 100644 8cbd384... f2bcd40... M	src/change.c
:100644 100644 bd7749a... fc577a0... M	src/change.h
=========
 Changes
=========
commit 50d058ba2ca3403a6fbacf3885160806f448a3dc
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
    Handle attempts to change clearance on polygons.
    
    If the user attempts to change the clearance between polygons and
    objects within the polygon by pressing 'k' over the *polygon*, notice
    that attemp and tell the user how to accomplish what they want.
diff --git a/src/change.c b/src/change.c
index 8cbd384..f2bcd40 100644
--- a/src/change.c
+++ b/src/change.c
@@ -82,6 +82,7 @@ static void *ChangeViaClearSize (PinTypePtr);
 static void *ChangeViaMaskSize (PinTypePtr);
 static void *ChangeLineSize (LayerTypePtr, LineTypePtr);
 static void *ChangeLineClearSize (LayerTypePtr, LineTypePtr);
+static void *ChangePolygonClearSize (LayerTypePtr, PolygonTypePtr);
 static void *ChangeArcSize (LayerTypePtr, ArcTypePtr);
 static void *ChangeArcClearSize (LayerTypePtr, ArcTypePtr);
 static void *ChangeTextSize (LayerTypePtr, TextTypePtr);
@@ -175,7 +176,7 @@ static ObjectFunctionType ChangeThermalFunctions = {
 static ObjectFunctionType ChangeClearSizeFunctions = {
   ChangeLineClearSize,
   NULL,
-  NULL,
+  ChangePolygonClearSize, /* just to tell the user not to :-) */
   ChangeViaClearSize,
   NULL,
   NULL,
@@ -741,6 +742,23 @@ ChangeLineClearSize (LayerTypePtr Layer, LineTypePtr Line)
 }
 
 /* ---------------------------------------------------------------------------
+ * Handle attepts to change the clearance of a polygon.
+ */
+static void *
+ChangePolygonClearSize (LayerTypePtr Layer, PolygonTypePtr poly)
+{
+  static int shown_this_message = 0;
+  if (!shown_this_message)
+    {
+      gui->confirm_dialog ("To change the clearance of objects in a polygon, "
+			   "change the objects, not the polygon.", "Ok", NULL);
+      shown_this_message = 1;
+    }
+
+  return (NULL);
+}
+
+/* ---------------------------------------------------------------------------
  * changes the size of an arc
  * returns TRUE if changed
  */
diff --git a/src/change.h b/src/change.h
index bd7749a..fc577a0 100644
--- a/src/change.h
+++ b/src/change.h
@@ -46,8 +46,9 @@
 #define	CHANGE2NDSIZE_TYPES     \
 	(VIA_TYPE | PIN_TYPE | ELEMENT_TYPE)
 
+/* We include polygons here only to inform the user not to do it that way.  */
 #define CHANGECLEARSIZE_TYPES	\
-	(PIN_TYPE | PAD_TYPE | VIA_TYPE | LINE_TYPE | ARC_TYPE)
+	(PIN_TYPE | PAD_TYPE | VIA_TYPE | LINE_TYPE | ARC_TYPE | POLYGON_TYPE)
 
 #define	CHANGESQUARE_TYPES     \
 	(ELEMENT_TYPE | PIN_TYPE | PAD_TYPE)
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-18 18:52:56
      
     | 
| The branch, master has been updated
       via  6772dffe97136dadfb38c56e1ccbf83250e60185 (commit)
      from  363f4908a4af44a6cf007709bd093cc9ea0ae2aa (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
=========
 doc/extract-docs |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit 6772dffe97136dadfb38c56e1ccbf83250e60185
Author: Kai-Martin Knaak <km...@li...>
Commit: DJ Delorie <dj...@de...>
    expand the syntax of documentating comments
    
    This is part of the effort to derive the command line option entries in the
    manual dynamically from the source. The expanded syntax allows for more control on
    the actual headings rendered in the manual.
    
    1) accept keys enclosed in quotation marks ("). This allows for multiple word
    nodes in the documentation.
    
    2) strip leading digits of the key after sort. This allows to control the order
    of nodes from the source.
:100755 100755 cf23c6c... a25de8e... M	doc/extract-docs
=========
 Changes
=========
commit 6772dffe97136dadfb38c56e1ccbf83250e60185
Author: Kai-Martin Knaak <km...@li...>
Commit: DJ Delorie <dj...@de...>
    expand the syntax of documentating comments
    
    This is part of the effort to derive the command line option entries in the
    manual dynamically from the source. The expanded syntax allows for more control on
    the actual headings rendered in the manual.
    
    1) accept keys enclosed in quotation marks ("). This allows for multiple word
    nodes in the documentation.
    
    2) strip leading digits of the key after sort. This allows to control the order
    of nodes from the source.
diff --git a/doc/extract-docs b/doc/extract-docs
index cf23c6c..a25de8e 100755
--- a/doc/extract-docs
+++ b/doc/extract-docs
@@ -3,7 +3,11 @@
 #
 # $Id$
 #
-
+#################################################################
+# This script extracts special comments from the source. It assembles
+# them in texinfo files that are included in the manual.  
+#################################################################
+#
 # The general format of what this script looks for is thusly:
 #
 #  %start-doc category sort-key
@@ -18,6 +22,10 @@
 # file according to the category.  Each unique sort-key causes a @node
 # to be created, unless that sort-key's text already has a @node in
 # it.
+# If the sort-key contains space characters, it should be enclosed by
+# quotation marks ("). Leading digits in the sort key optionally followed
+# by space are removed after sort but before creation of nodes. This
+# allows to manipulate the order of nodes in the manual.
 #
 # Note that we synthesize a special @syntax command, which should be
 # used for all things syntax.  We change those to whatever the current
@@ -145,6 +153,8 @@ for $cat (sort keys %text) {
 	    }
 	    next if $key =~ /^00/;
 	    $k2 = $title{$cat}{$key};
+	    # strip leading digits from the key string
+	    $k2 =~ s/\A\d+\s*//g;
 	    $k2 = sprintf($nodename, $k2);
 	    if ($text{$cat}{$key} !~ /\@node/) {
 		$new .="* ${k2}::\n";
@@ -161,6 +171,8 @@ for $cat (sort keys %text) {
 	    }
 	    next if $key =~ /^00/;
 	    $k2 = $title{$cat}{$key};
+	    # strip leading digits from the key string
+	    $k2 =~ s/\A\d+\s*//g;
 	    $k2n = sprintf($nodename, $k2);
 	    $new .= "\@c $cat $k2\n";
 	    if ($text{$cat}{$key} !~ /\@node/) {
@@ -261,9 +273,20 @@ sub scan_file {
 	    next;
 	}
 
-	if (/%start-doc\s+(\S+)\s+(\S+)(\s+(.*))?/) {
+	if (/%start-doc\s+(\S+)\s+([^"^\s]+|".*?")(\s+(.*))?/) {
+	# pattern to look for:
+	# start-doc -> "%start-doc"
+	# \s+ -> one ore more whitespace
+	# (\S+) -> string with no whitespace, goes to $1
+	# \s+ -> one ore more whitespace
+	# ([^"^\s]+|".*?") -> a space-less string, or a string delimited by ", goes to $2
+	# (\s+(.*))? -> zero or more space separated strings
+	
 	    $cat = $1;
 	    $key = $2;
+	    # strip leading and trailing quotation marks from the key string
+	    $key =~ s/\A"//g;
+	    $key =~ s/"\Z//g;
 	    $title = $4;
 	    if ($title) {
 		$title{$cat}{"$key\0$hid"} = $title;
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-16 21:40:28
      
     | 
| The branch, master has been updated
       via  363f4908a4af44a6cf007709bd093cc9ea0ae2aa (commit)
      from  3126e746bfe6bc4f93e17699c32a3bd8938a243d (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
=========
 doc/pcb.texi    |   16 ++++++++++++----
 doc/thermal.pcb |   32 +++++++++++++++++++-------------
 2 files changed, 31 insertions(+), 17 deletions(-)
=================
 Commit Messages
=================
commit 363f4908a4af44a6cf007709bd093cc9ea0ae2aa
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Fix pr2136131. Clarify image of thermal in doc.
    
    Also added some text about changing the style of thermal using
    shift-click in the sections that talk about it.
:100644 100644 51989ee... cf3ceb1... M	doc/pcb.texi
:100644 100644 6a26561... bce2f09... M	doc/thermal.pcb
=========
 Changes
=========
commit 363f4908a4af44a6cf007709bd093cc9ea0ae2aa
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Fix pr2136131. Clarify image of thermal in doc.
    
    Also added some text about changing the style of thermal using
    shift-click in the sections that talk about it.
diff --git a/doc/pcb.texi b/doc/pcb.texi
index 51989ee..cf3ceb1 100644
--- a/doc/pcb.texi
+++ b/doc/pcb.texi
@@ -623,7 +623,9 @@ clicking @emph{Btn1} with the thermal tool over the pin or via.
 The thermal tool always
 places a thermal to polygons on the active layer, so if the tool doesn't
 seem to work, it's probably because the polygon you want to touch is not
-on the active layer.
+on the active layer.  You can change the style of thermal used or make
+a solid connection by holding down @emph{Shift} while clicking
+@emph{Btn1} with the thermal tool over the pin or via.
 
 @pcb{} is capable of handling complex polygons, but
 using a number of simpler ones improves performance of the connection tracing code.
@@ -1204,8 +1206,10 @@ they are not electrically connected. Use the Thermal tool to make
 the via connect to the plane. Thermals allow the via or pin to
 be heated by a soldering iron without having to heat the entire
 plane. If solid connections were made to the plane, it could be
-nearly impossible to solder. Click on the via again with the
-Thermal tool to remove the connection to the plane.
+nearly impossible to solder. Shift-click on the via with the Thermal
+tool to change the style of thermal used or to make the connection
+solid.  Click on the via again with the Thermal tool to remove the
+connection to the plane.
 
 The Insert-point tool is an editing tool that allows you to add
 points into lines and polygons.  The
@@ -5917,7 +5921,11 @@ or power plane.  Instead of directly connecting to the plane, small "spokes"
 are used to increase the thermal resistance between the pin and the plane.
 Often times these connections are refered to as simply a thermal.  By increasing
 the thermal resistance to the plane, it becomes easier to solder to the
-pin.  The drawing below shows an example of a thermal relief.
+pin.  In the drawing below, the pin on the left is connected to the
+polygon using a solid connection with no thermal relief, the middle
+pin is connected using a thermal, while the pin on the right has no
+connection to the polygon.  In PCB, the ``Thermal'' Tool is used to
+make both a solid connection and one with thermal relief (see @ref{Polygon Objects}).
 
 @center @image{thermal,,,Example of a thermal relief,png}
 
diff --git a/doc/thermal.pcb b/doc/thermal.pcb
index 6a26561..bce2f09 100644
--- a/doc/thermal.pcb
+++ b/doc/thermal.pcb
@@ -793,13 +793,14 @@ Symbol['~' 1200]
 	SymbolLine[1500 3500 2000 3500 800]
 	SymbolLine[2000 3500 2500 3000 800]
 )
-Via[195000 135000 30000 10000 0 10000 "" ""]
-Via[95000 135000 30000 10000 0 10000 "" "thermal(0)"]
+Via[45000 135000 30000 10000 0 10000 "" "thermal(0S)"]
+Via[255000 135000 30000 10000 0 10000 "" ""]
+Via[150000 135000 30000 10000 0 10000 "" "thermal(0)"]
 Layer(1 "component")
 (
 	Polygon("clearpoly")
 	(
-		[55000 95000] [235000 95000] [235000 175000] [55000 175000] 
+		[5000 95000] [290000 95000] [290000 175000] [5000 175000] 
 	)
 )
 Layer(2 "solder")
@@ -828,14 +829,19 @@ Layer(9 "silk")
 )
 Layer(10 "silk")
 (
-	Line[95000 160000 100000 165000 2500 10000 "clearline"]
-	Line[95000 160000 90000 165000 2500 10000 "clearline"]
-	Line[195000 180000 195000 160000 2500 10000 "clearline"]
-	Line[195000 160000 200000 165000 2500 10000 "clearline"]
-	Line[195000 160000 190000 165000 2500 10000 "clearline"]
-	Line[95000 180000 95000 160000 2500 10000 "clearline"]
-	Text[65000 180000 0 200 "Via/Pin With " ""]
-	Text[175000 195000 0 200 "Thermal" ""]
-	Text[160000 180000 0 200 "Via/Pin Without" ""]
-	Text[75000 195000 0 200 "Thermal" ""]
+	Line[255000 180000 255000 160000 2500 10000 "clearline"]
+	Line[255000 160000 260000 165000 2500 10000 "clearline"]
+	Line[45000 160000 50000 165000 2500 10000 "clearline"]
+	Line[45000 160000 40000 165000 2500 10000 "clearline"]
+	Line[45000 180000 45000 160000 2500 10000 "clearline"]
+	Line[255000 160000 250000 165000 2500 10000 "clearline"]
+	Line[150000 160000 155000 165000 2500 10000 "clearline"]
+	Line[150000 160000 145000 165000 2500 10000 "clearline"]
+	Line[150000 180000 150000 160000 2500 10000 "clearline"]
+	Text[220000 190000 0 200 "no connection" ""]
+	Text[15000 180000 0 200 "Via/Pin with " ""]
+	Text[5000 190000 0 200 "solid connection " ""]
+	Text[225000 180000 0 200 "Via/Pin with" ""]
+	Text[120000 180000 0 200 "Via/Pin with " ""]
+	Text[130000 190000 0 200 "thermal" ""]
 )
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-09 02:39:34
      
     | 
| The branch, master has been updated
       via  3126e746bfe6bc4f93e17699c32a3bd8938a243d (commit)
       via  83a5eb93ba68ad2161ee72bc23939d28788e7f62 (commit)
      from  2e0849b339504000c47772851b4262e08609f13e (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
=========
 doc/pcb.texi                     |   35 +++++++---
 src/action.c                     |    2 +-
 src/hid.h                        |   16 +++--
 src/hid/batch/batch.c            |   44 +------------
 src/hid/common/actions.c         |  139 ++++++++++++++++++++++++++------------
 src/hid/common/hid_resource.c    |    6 +-
 src/hid/gtk/gui-command-window.c |    6 +-
 src/hid/gtk/gui-top-window.c     |    4 +-
 src/hid/lesstif/main.c           |   48 +-------------
 src/hid/lesstif/menu.c           |   51 +-------------
 src/main.c                       |    2 +-
 11 files changed, 146 insertions(+), 207 deletions(-)
=================
 Commit Messages
=================
commit 3126e746bfe6bc4f93e17699c32a3bd8938a243d
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Check action name at registration.
    
    Prevent actions with spaces and '(' in their names from being
    registered; these will cause ambiguity and problems in
    hid_parse_actionstring.
:100644 100644 42e1e08... 9fa129d... M	src/hid/common/actions.c
commit 83a5eb93ba68ad2161ee72bc23939d28788e7f62
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Consolidate hid action parsing.
    
    - Create a common routine hid_parse_command, which handles both action
    script style "action(arg1, arg2);" and command entry style "action
    arg1 arg2".  This is done by making a static hid_parse_actionstring
    function, which takes a boolean to determine whether or not it should
    accept command entry style strings.  hid_parse_actions functions as it
    currently does, only accepting action script style, but does so by
    calling hid_parse_actionstring with TRUE.
    
    - Use hid_parse_command across all hids for user command entry,
    removing command_parse in lesstif/main.c and batch/batch.c.
    
    - Added extra error handling to common hid_actionv to match
    lesstif_call_action and remove lesstif_call_action.
:100644 100644 2f4c374... 51989ee... M	doc/pcb.texi
:100644 100644 a81c142... 6bbee09... M	src/action.c
:100644 100644 7b30022... dd34b8e... M	src/hid.h
:100644 100644 f26321d... 3129466... M	src/hid/batch/batch.c
:100644 100644 a2ad612... 42e1e08... M	src/hid/common/actions.c
:100644 100644 8802070... d5ba274... M	src/hid/common/hid_resource.c
:100644 100644 8bfd853... 3dfe95e... M	src/hid/gtk/gui-command-window.c
:100644 100644 a594330... e61c9f3... M	src/hid/gtk/gui-top-window.c
:100644 100644 51c52fe... 1613547... M	src/hid/lesstif/main.c
:100644 100644 44edaba... f88664d... M	src/hid/lesstif/menu.c
:100644 100644 3026f8d... 7e29d56... M	src/main.c
=========
 Changes
=========
commit 3126e746bfe6bc4f93e17699c32a3bd8938a243d
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Check action name at registration.
    
    Prevent actions with spaces and '(' in their names from being
    registered; these will cause ambiguity and problems in
    hid_parse_actionstring.
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index 42e1e08..9fa129d 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -28,16 +28,33 @@ static int n_actions = 0;
 
 HID_Action *current_action = NULL;
 
+static const char *
+check_action_name (const char *s)
+{
+  while (*s)
+    if (isspace ((int) *s++) || *s == '(')
+      return (s-1);
+  return NULL;
+}
+
 void
 hid_register_actions (HID_Action * a, int n)
 {
-  int i;
+  int i, count = 0;
   
   all_actions = realloc (all_actions,
                          (n_actions + n) * sizeof (HID_Action*));
   for (i = 0; i < n; i++)
-    all_actions[n_actions + i] = a + i;
-  n_actions += n;
+    {
+      if (check_action_name (a[i].name))
+        {
+          Message (_("ERROR! Invalid action name, "
+                     "action \"%s\" not registered.\n"), a[i].name);
+          continue;
+        }
+      all_actions[n_actions + count++] = a + i;
+    }
+  n_actions += count;
   all_actions_sorted = 0;
 }
 
commit 83a5eb93ba68ad2161ee72bc23939d28788e7f62
Author: Jared Casper <jar...@gm...>
Commit: DJ Delorie <dj...@de...>
    Consolidate hid action parsing.
    
    - Create a common routine hid_parse_command, which handles both action
    script style "action(arg1, arg2);" and command entry style "action
    arg1 arg2".  This is done by making a static hid_parse_actionstring
    function, which takes a boolean to determine whether or not it should
    accept command entry style strings.  hid_parse_actions functions as it
    currently does, only accepting action script style, but does so by
    calling hid_parse_actionstring with TRUE.
    
    - Use hid_parse_command across all hids for user command entry,
    removing command_parse in lesstif/main.c and batch/batch.c.
    
    - Added extra error handling to common hid_actionv to match
    lesstif_call_action and remove lesstif_call_action.
diff --git a/doc/pcb.texi b/doc/pcb.texi
index 2f4c374..51989ee 100644
--- a/doc/pcb.texi
+++ b/doc/pcb.texi
@@ -2405,20 +2405,35 @@ the trace optimizer.
 @cindex user commands
 @cindex entering user commands
 The entering of user-commands is initiated by the action routine
-@emph{Command()} (the @code{(":")} character) and finished by either
-@emph{<Key>Return}
-or @emph{<Key>Escape} to confirm or to abort. These two key-bindings
-cannot be changed from the resource file.
-The triggering event, normally a key press, is ignored.
-The input area will replace the bottom statusline. It pops
-up when @emph{Command()} is called. The arguments of the user-commands
-are passed to the external commands without modification.
-See also, the resource @emph{saveInTMP}.
+@emph{Command()} (normally bound to the @code{(":")} character) which
+replaces the bottom statusline with an input area or opens a separate
+command window.  It is finished by either @emph{<Key>Return} or
+@emph{<Key>Escape} to confirm or to abort. These two key-bindings
+cannot be changed from the resource file.  The triggering event,
+normally a key press, is ignored.
+
+Commands can be entered in one of two styles, command entry syntax:
+``@emph{Command arg1 arg2}'' or action script syntax ``@emph{Action1(arg1,
+arg2); Action2(arg1, arg2);}''.  Quoting arguments works similar to
+bash quoting:
+
+@itemize
+@item A backslash (\) is the escape character.  It preserves the literal
+value of the next character that follows.  To get a literal '\' use
+"\\".
+
+@item Enclosing characters in single quotes preserves the literal value of
+each character within the quotes.  A single quote may not occur
+between single quotes, even when preceded by a blackslash.
+
+@item Enclosing characters in double quotes preserves the literal value of
+all characters within the quotes, with the exception of '\' which
+maintains its special meaning as an escape character.
+@end itemize
 
 There are simple @emph{usage} dialogs for each command and one for the
 complete set of commands.
 
-
 @table @samp
 
 @findex :l
diff --git a/src/action.c b/src/action.c
index a81c142..6bbee09 100644
--- a/src/action.c
+++ b/src/action.c
@@ -6794,7 +6794,7 @@ ActionExecuteFile (int argc, char **argv, int x, int y)
       if (*sp && *sp != '#')
 	{
 	  /*Message ("%s : line %-3d : \"%s\"\n", fname, n, sp);*/
-	  hid_parse_actions (sp, 0);
+	  hid_parse_actions (sp);
 	}
     }
 
diff --git a/src/hid.h b/src/hid.h
index 7b30022..dd34b8e 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -119,11 +119,17 @@ extern "C"
   void hid_save_settings (int);
   void hid_load_settings (void);
 
-/* Parse the given string into action calls, and call `f' for each
-   action found.  Returns nonzero if the action handler(s) return
-   nonzero.  If f is NULL, hid_actionv is called.  */
-  int hid_parse_actions (const char *str_,
-			 int (*_f) (const char *, int, char **));
+/* Parse the given command string into action calls, and call
+   hid_actionv for each action found.  Accepts both "action(arg1,
+   arg2)" and command-style "action arg1 arg2", allowing only one
+   action in the later case.  Returns nonzero if the action handler(s)
+   return nonzero. */
+  int hid_parse_command (const char *str_);
+
+/* Parse the given string into action calls, and call
+   hid_actionv for each action found.  Accepts only
+   "action(arg1, arg2)" */
+  int hid_parse_actions (const char *str_);
 
   typedef struct
   {
diff --git a/src/hid/batch/batch.c b/src/hid/batch/batch.c
index f26321d..3129466 100644
--- a/src/hid/batch/batch.c
+++ b/src/hid/batch/batch.c
@@ -114,45 +114,6 @@ REGISTER_ACTIONS (batch_action_list)
 /* ----------------------------------------------------------------------------- */
 
 static void
-command_parse (char *s)
-{
-  int n = 0, ws = 1;
-  char *cp;
-  char **argv;
-
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	ws = 1;
-      else
-	{
-	  n += ws;
-	  ws = 0;
-	}
-    }
-  argv = (char **) malloc ((n + 1) * sizeof (char *));
-
-  n = 0;
-  ws = 1;
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	{
-	  ws = 1;
-	  *cp = 0;
-	}
-      else
-	{
-	  if (ws)
-	    argv[n++] = cp;
-	  ws = 0;
-	}
-    }
-  argv[n] = 0;
-  hid_actionv (argv[0], n - 1, argv + 1);
-}
-
-static void
 batch_do_export (HID_Attr_Val * options)
 {
   int interactive;
@@ -177,10 +138,7 @@ batch_do_export (HID_Attr_Val * options)
 	}
       if (fgets(line, sizeof(line)-1, stdin) == NULL)
 	return;
-      if (strchr (line, '('))
-	hid_parse_actions (line, 0);
-      else
-	command_parse (line);
+      hid_parse_command (line);
     }
 }
 
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index a2ad612..42e1e08 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -11,6 +11,7 @@
 
 #include "global.h"
 #include "data.h"
+#include "error.h"
 
 #include "hid.h"
 #include "../hidint.h"
@@ -198,19 +199,30 @@ hid_actionv (const char *name, int argc, char **argv)
   int x = 0, y = 0, i, ret;
   HID_Action *a, *old_action;
 
-  if (Settings.verbose && name)
+  if (!name)
+    return 1;
+
+  a = hid_find_action (name);
+  if (!a)
     {
-      printf ("Action: \033[34m%s(", name);
+      int i;
+      Message ("no action %s(", name);
       for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? "," : "", argv[i]);
-      printf (")\033[0m\n");
+        Message ("%s%s", i ? ", " : "", argv[i]);
+      Message (")\n");
+      return 1;
     }
 
-  a = hid_find_action (name);
-  if (!a)
-    return 1;
   if (a->need_coord_msg)
     gui->get_coords (a->need_coord_msg, &x, &y);
+
+  if (Settings.verbose)
+    {
+      printf ("Action: \033[34m%s(", name);
+      for (i = 0; i < argc; i++)
+	printf ("%s%s", i ? "," : "", argv[i]);
+      printf (")\033[0m\n");
+    }
   
   old_action     = current_action;
   current_action = a;
@@ -220,9 +232,8 @@ hid_actionv (const char *name, int argc, char **argv)
   return ret;
 }
 
-int
-hid_parse_actions (const char *rstr,
-		   int (*function) (const char *, int, char **))
+static int
+hid_parse_actionstring (const char *rstr, char require_parens)
 {
   char **list = NULL;
   int max = 0;
@@ -232,11 +243,9 @@ hid_parse_actions (const char *rstr,
   char *cp, *aname, *cp2;
   int maybe_empty = 0;
   char in_quotes = 0;
+  char parens = 0;
   int retcode = 0;
 
-  if (function == NULL)
-    function = hid_actionv;
-
   /*fprintf(stderr, "invoke: `%s'\n", rstr);*/
 
   sp = rstr;
@@ -257,52 +266,65 @@ another:
     }
   
   aname = cp;
-  
-  /* search for the leading ( */
-  while (*sp && *sp != '(')
+
+  /* copy the action name, assumes name does not have a space or '('
+   * in its name */
+  while (*sp && !isspace ((int) *sp) && *sp != '(')
     *cp++ = *sp++;
   *cp++ = 0;
-  if (*sp)
+
+  /* skip whitespace */
+  while (*sp && isspace ((int) *sp))
     sp++;
 
   /*
-   * we didn't find a leading ( so invoke the action
+   * we only have an action name, so invoke the action
    * with no parameters or event.
    */
   if (!*sp)
     {
-      if (function (aname, 0, 0))
-        {
-          retcode = 1;
-          goto cleanup;
-        }
-      goto another;
+      retcode = hid_actionv (aname, 0, 0);
+      goto cleanup;
+    }
+
+  /* are we using parenthesis? */
+  if (*sp == '(')
+    {
+      parens = 1;
+      sp++;
+    }
+  else if (require_parens)
+    {
+      Message (_("Syntax error: %s\n"), rstr);
+      Message (_("    expected: Action(arg1, arg2)"));
+      retcode = 1;
+      goto cleanup;
     }
   
-  /* 
-   * we found a leading ( so see if we have parameters to pass to the
-   * action 
-   */
+  /* get the parameters to pass to the action */
   while (1)
     {
       /* 
        * maybe_empty == 0 means that the last char examined was not a
-       * "," 
+       * ","
        */
-      if (*sp == ')' && !maybe_empty)
+      if (!maybe_empty && ((parens && *sp == ')') || (!parens && !*sp)))
 	{
-	  if (function (aname, num, list))
-	    {
-	      retcode = 1;
-	      goto cleanup;
-	    }
-	  sp++;
+          retcode = hid_actionv (aname, num, list);
+          if (retcode)
+            goto cleanup;
+
+          /* strip any white space or ';' following the action */
+          if (parens)
+            sp++;
+          while (*sp && (isspace ((int) *sp) || *sp == ';'))
+            sp++;
 	  goto another;
 	}
       else if (*sp == 0 && !maybe_empty)
 	break;
       else
-	{
+        {
 	  maybe_empty = 0;
 	  in_quotes = 0;
 	  /* 
@@ -322,8 +344,12 @@ another:
 	    sp++;
 	  list[num++] = cp;
 	  
-	  /* search for a "," or a ")" */
-	  while (*sp && (in_quotes || (*sp != ',' && *sp != ')')))
+	  /* search for the end of the argument, we want to keep going
+           * if we are in quotes or the char is not a delimiter
+           */
+	  while (*sp && (in_quotes || ((*sp != ',')
+                                       && (!parens || *sp != ')')
+                                       && (parens || !isspace ((int) *sp)))))
 	    {
 	      /*
 	       * single quotes give literal value inside, including '\'. 
@@ -343,7 +369,7 @@ another:
 	    }
 	  cp2 = cp - 1;
 	  *cp++ = 0;
-	  if (*sp == ',')
+	  if (*sp == ',' || (!parens && isspace ((int) *sp)))
 	    {
 	      maybe_empty = 1;
 	      sp++;
@@ -365,6 +391,16 @@ another:
   return retcode;
 }
 
+int hid_parse_command (const char *str_)
+{
+  return hid_parse_actionstring (str_, FALSE);
+}
+
+int hid_parse_actions (const char *str_)
+{
+  return hid_parse_actionstring (str_, TRUE);
+}
+
 /* trick for the doc extractor */
 #define static
 
diff --git a/src/hid/common/hid_resource.c b/src/hid/common/hid_resource.c
index 8802070..d5ba274 100644
--- a/src/hid/common/hid_resource.c
+++ b/src/hid/common/hid_resource.c
@@ -198,8 +198,6 @@ do_mouse_action (int button, int mod_mask)
 
   for (i = 0; i < action->c; i++)
     if (action->v[i].value)
-      if (hid_parse_actions (action->v[i].value, hid_actionv))
-	return;
+      if (hid_parse_actions (action->v[i].value))
+        return;
 }
-
-
diff --git a/src/hid/gtk/gui-command-window.c b/src/hid/gtk/gui-command-window.c
index 8bfd853..3dfe95e 100644
--- a/src/hid/gtk/gui-command-window.c
+++ b/src/hid/gtk/gui-command-window.c
@@ -212,7 +212,7 @@ command_entry_activate_cb (GtkWidget * widget, gpointer data)
   if (ghidgui->use_command_window)
     {
       HideCrosshair (True);
-      hid_parse_actions (command, NULL);
+      hid_parse_command (command);
       RestoreCrosshair (True);
       g_free (command);
     }
@@ -473,13 +473,13 @@ ghid_handle_user_command (gboolean raise)
 	  /* copy new comand line to save buffer */
 	  g_free (previous);
 	  previous = g_strdup (command);
-	  hid_parse_actions (command, NULL);
+	  hid_parse_command (command);
 	  g_free (command);
 	}
       else if (previous)
 	{
 	  command = g_strdup (previous);
-	  hid_parse_actions (command, NULL);
+	  hid_parse_command (command);
 	  g_free (command);
 	}
       RestoreCrosshair (True);
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index a594330..e61c9f3 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -631,7 +631,7 @@ ghid_menu_cb (GtkAction * action, gpointer data)
 #ifdef DEBUG_MENUS
 	    printf ("    %s\n", node->v[vi].value);
 #endif
-	    hid_parse_actions (node->v[vi].value, NULL);
+	    hid_parse_actions (node->v[vi].value);
 	  }
     }
   else {
@@ -2544,7 +2544,7 @@ ghid_listener_cb (GIOChannel *source,
       switch (status)
 	{
 	case G_IO_STATUS_NORMAL:
-	  hid_parse_actions (str, NULL);
+	  hid_parse_actions (str);
 	  g_free (str);
 	  break;
 
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 51c52fe..1613547 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -627,47 +627,6 @@ SwapSides (int argc, char **argv, int x, int y)
 static Widget m_cmd = 0, m_cmd_label;
 
 static void
-command_parse (char *s)
-{
-  int n = 0, ws = 1;
-  char *cp;
-  char **argv;
-
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	ws = 1;
-      else
-	{
-	  n += ws;
-	  ws = 0;
-	}
-    }
-  argv = (char **) malloc ((n + 1) * sizeof (char *));
-
-  n = 0;
-  ws = 1;
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	{
-	  ws = 1;
-	  *cp = 0;
-	}
-      else
-	{
-	  if (ws)
-	    argv[n++] = cp;
-	  ws = 0;
-	}
-    }
-  if (n == 0)
-    return;
-  argv[n] = 0;
-  lesstif_call_action (argv[0], n - 1, argv + 1);
-}
-
-static void
 command_callback (Widget w, XtPointer uptr, XmTextVerifyCallbackStruct * cbs)
 {
   char *s;
@@ -676,10 +635,7 @@ command_callback (Widget w, XtPointer uptr, XmTextVerifyCallbackStruct * cbs)
     case XmCR_ACTIVATE:
       s = XmTextGetString (w);
       lesstif_show_crosshair (0);
-      if (strchr (s, '('))
-	hid_parse_actions (s, lesstif_call_action);
-      else
-	command_parse (s);
+      hid_parse_command (s);
       XtFree (s);
       XmTextSetString (w, "");
     case XmCR_LOSING_FOCUS:
@@ -1966,7 +1922,7 @@ lesstif_listener_cb (XtPointer client_data, int *fid, XtInputId *id)
   if (nbytes)
     {
       buf[nbytes] = '\0';
-      hid_parse_actions (buf, NULL);
+      hid_parse_actions (buf);
     }
 }
 
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index 44edaba..f88664d 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -812,53 +812,6 @@ lesstif_get_coords (const char *msg, int *px, int *py)
     lesstif_coords_to_pcb (action_x, action_y, px, py);
 }
 
-int
-lesstif_call_action (const char *aname, int argc, char **argv)
-{
-  int px, py, ret;
-  HID_Action *a, *old_action;
-
-  if (!aname)
-    return 1;
-  a = hid_find_action (aname);
-  if (!a)
-    {
-      int i;
-      printf ("no action %s(", aname);
-      for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? ", " : "", argv[i]);
-      printf (")\n");
-      return 1;
-    }
-
-  if (a->need_coord_msg && !have_xy)
-    {
-      const char *msg;
-      if (strcmp (aname, "GetXY") == 0)
-	msg = argv[0];
-      else
-	msg = a->need_coord_msg;
-      lesstif_get_xy (msg);
-    }
-  lesstif_coords_to_pcb (action_x, action_y, &px, &py);
-
-  if (Settings.verbose)
-    {
-      int i;
-      printf ("Action: \033[34m%s(", aname);
-      for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? "," : "", argv[i]);
-      printf (")\033[0m\n");
-    }
-
-  old_action     = current_action;
-  current_action = a;
-  ret = current_action->trigger_cb (argc, argv, px, py);
-  current_action = old_action;
-
-  return ret;
-}
-
 static void
 callback (Widget w, Resource * node, XmPushButtonCallbackStruct * pbcs)
 {
@@ -893,7 +846,7 @@ callback (Widget w, Resource * node, XmPushButtonCallbackStruct * pbcs)
   lesstif_need_idle_proc ();
   for (vi = 1; vi < node->c; vi++)
     if (resource_type (node->v[vi]) == 10)
-      if (hid_parse_actions (node->v[vi].value, lesstif_call_action))
+      if (hid_parse_actions (node->v[vi].value))
 	return;
 }
 
@@ -1254,7 +1207,7 @@ lesstif_key_event (XKeyEvent * e)
   for (vi = 1; vi < cur_table[i].u.a.node->c; vi++)
     if (resource_type (cur_table[i].u.a.node->v[vi]) == 10)
       if (hid_parse_actions
-	  (cur_table[i].u.a.node->v[vi].value, lesstif_call_action))
+	  (cur_table[i].u.a.node->v[vi].value))
 	break;
   cur_table = 0;
   return 1;
diff --git a/src/main.c b/src/main.c
index 3026f8d..7e29d56 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1033,7 +1033,7 @@ main (int argc, char *argv[])
   if (Settings.ActionString)
     {
       Message (_("Executing startup action %s\n"), Settings.ActionString);
-      hid_parse_actions (Settings.ActionString, 0);
+      hid_parse_actions (Settings.ActionString);
     }
 
 #if HAVE_DBUS
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-05 23:39:44
      
     | 
| The branch, master has been updated
       via  2e0849b339504000c47772851b4262e08609f13e (commit)
      from  84086a10b39f6d524fb2cf2bae7751766a77d0f7 (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/toporouter.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
=================
 Commit Messages
=================
commit 2e0849b339504000c47772851b4262e08609f13e
Author: Dan McMahill <da...@mc...>
Commit: Dan McMahill <da...@mc...>
    Fix some "mixed declarations and code" issues.
:100644 100644 50195d3... e820677... M	src/toporouter.c
=========
 Changes
=========
commit 2e0849b339504000c47772851b4262e08609f13e
Author: Dan McMahill <da...@mc...>
Commit: Dan McMahill <da...@mc...>
    Fix some "mixed declarations and code" issues.
diff --git a/src/toporouter.c b/src/toporouter.c
index 50195d3..e820677 100644
--- a/src/toporouter.c
+++ b/src/toporouter.c
@@ -2406,10 +2406,11 @@ check_cons_continuation:
       toporouter_vertex_t *c2v2 = tedge_v2(c2);
 
       if(gts_segments_are_intersecting(GTS_SEGMENT(c1), GTS_SEGMENT(c2)) == GTS_IN) {
+        toporouter_vertex_t *v;
         unconstrain(l, c1); unconstrain(l, c2); 
         rem = 1;
         // proper intersection
-        toporouter_vertex_t *v = TOPOROUTER_VERTEX(vertex_intersect(
+        v = TOPOROUTER_VERTEX(vertex_intersect(
               GTS_VERTEX(c1v1),
               GTS_VERTEX(c1v2),
               GTS_VERTEX(c2v1),
@@ -2625,8 +2626,9 @@ check_cons_continuation:
   
   {
     char buffer[64];
+    FILE *fout2;
     sprintf(buffer, "surface%d.gts", l - r->layers);
-    FILE *fout2 = fopen(buffer, "w");
+    fout2 = fopen(buffer, "w");
     gts_surface_write(l->surface, fout2);
   }
 
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-04 16:54:29
      
     | 
| The branch, master has been updated
       via  84086a10b39f6d524fb2cf2bae7751766a77d0f7 (commit)
      from  ff41950800e5d92048e53ce5cdd52efb4f67cc1c (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/misc.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
=================
 Commit Messages
=================
commit 84086a10b39f6d524fb2cf2bae7751766a77d0f7
Author: Ineiev <in...@gm...>
Commit: DJ Delorie <dj...@de...>
    Fix "Request for bounding box of unsupported type 1024"
    
    Tracker bug # 2893717
    https://sourceforge.net/tracker/?func=detail&atid=538811&aid=2893717&group_id=73743
:100644 100644 d19970b... 20048db... M	src/misc.c
=========
 Changes
=========
commit 84086a10b39f6d524fb2cf2bae7751766a77d0f7
Author: Ineiev <in...@gm...>
Commit: DJ Delorie <dj...@de...>
    Fix "Request for bounding box of unsupported type 1024"
    
    Tracker bug # 2893717
    https://sourceforge.net/tracker/?func=detail&atid=538811&aid=2893717&group_id=73743
diff --git a/src/misc.c b/src/misc.c
index d19970b..20048db 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1225,6 +1225,7 @@ GetObjectBoundingBox (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
     case POLYGON_TYPE:
     case PAD_TYPE:
     case PIN_TYPE:
+    case ELEMENTNAME_TYPE:
       return (BoxType *)Ptr2;
     case VIA_TYPE:
     case ELEMENT_TYPE:
 | 
| 
      
      
      From: <gi...@gp...> - 2010-04-03 22:31:32
      
     | 
| The branch, master has been updated
       via  ff41950800e5d92048e53ce5cdd52efb4f67cc1c (commit)
      from  57573ccab81b7125526bd4b311bbc61569e7ea35 (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/lesstif/dialogs.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
=================
 Commit Messages
=================
commit ff41950800e5d92048e53ce5cdd52efb4f67cc1c
Author: DJ Delorie <dj...@du...>
Commit: DJ Delorie <dj...@du...>
    Fix doc typo
:100644 100644 72b41ee... ac61c7c... M	src/hid/lesstif/dialogs.c
=========
 Changes
=========
commit ff41950800e5d92048e53ce5cdd52efb4f67cc1c
Author: DJ Delorie <dj...@du...>
Commit: DJ Delorie <dj...@du...>
    Fix doc typo
diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index 72b41ee..ac61c7c 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -2021,7 +2021,7 @@ Displays a dialog that lets the user select the schematic(s) to import
 from, then saves that information in the layout's attributes for
 future imports.
 
-*/
+%end-doc */
 
 static int
 ImportGUI (int argc, char **argv, int x, int y)
 |