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

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



The branch, master has been updated
       via  97b3260ecf977dcaa959e51fbd39c6b0d7b414b7 (commit)
       via  a420e4ba801eb7b9f12b528ec8930ec4d51935a5 (commit)
       via  62f17fa6c48449e36101167d9a3a26455f568721 (commit)
       via  be678ec6a077fa12ebb18ec0ee32156f2170b5f6 (commit)
       via  ebaf330e660455a877acaa4877d988244f0aa7c8 (commit)
       via  32c731f1edb62a6e4ed455084e9900ae94e522f9 (commit)
       via  6d7ab8297a73fd8ccc01e7e81ba82e2b49ae598c (commit)
       via  fa2a0e35a644646b400cba4c075710c0f0742771 (commit)
       via  0803816da4460d0bb25b92a4fd67400873da5907 (commit)
       via  4cc668bb98e986cb16c28e3dac9e71130b814c82 (commit)
       via  e46c9ef9505e88e446f003e5d89df0547c65b3f4 (commit)
       via  c73e0ee01e6b348aa772919225afaab31ee2f1df (commit)
       via  7822af60f7b28648eb41b2a2ae1aa5d55dd54182 (commit)
       via  ec8937d84ef409007438d78f8d9b6b8bd1440119 (commit)
       via  be98cd59b2fb3e027c2b9f441603dc6d799899f0 (commit)
       via  48cea1ad5e8b183d769d762ce98498ae3d1f907c (commit)
       via  736c3f2987c8d394140446455913c25a9d5b90b3 (commit)
       via  4dcbf39a2531705a2f8b2e40c52e3bbdebcae8da (commit)
       via  da403312d4c45b3d286b1b836affe2d002cfba7c (commit)
       via  4f0ce31aecdadc65d79fa4838b32d8312086c64c (commit)
       via  7b8f7840a1247a3523a0a26ad06cb5fc3638fdf8 (commit)
       via  affb432342fe81557c6427ed87da0da611b70c41 (commit)
       via  4632e403310efaef0b8bb3e48f5d5a839398f6e7 (commit)
       via  f97d92bfbb9580a54a6d1770ffa3973420fb49ab (commit)
       via  2217294268a1d5dee74ab96f059eeba5ed7c9995 (commit)
       via  732d85dd996d352b19dee8c3232688b38b7819b4 (commit)
       via  dfbd2188bb9dadc5efbea8871e3ba49ccb79d3ff (commit)
       via  5456171cbd9129402acfc6596d1cd7b742880324 (commit)
       via  8c1777bf0e9fbcbb06d448847dcc09052fd030e6 (commit)
       via  3d0d2c0a0edd60ec445a64e1be53cd7c6628dcea (commit)
       via  44db9c716a572748a7f5fc5f1bc7e5c1d84bb8fe (commit)
       via  2c737bfc51c420b9ef173860c31ef57ccde6edf6 (commit)
       via  06f059a973d4320f078de7a0e75023e1690baaee (commit)
       via  4545d537e6db4bf418ffecaf9bdfecd3ec22854f (commit)
       via  656f5925148e5a747bc55c618ff3843eddc65d07 (commit)
       via  5ff5b13ab3cd84247281190492dd834f24226893 (commit)
       via  1f802a7f01378217d519d2da25234fa0e105ddda (commit)
       via  b59ab044afe3ac362f8cb4da10ea410280b4323a (commit)
       via  a2af8aa83d106a9f0800ea5fe502e8d0e99ac651 (commit)
       via  27de2a3b9075415d6664bdb39c6e59cba970c441 (commit)
       via  6d08a5996f48dece369b278b1ca41cd8250b4e3c (commit)
       via  912ce4d8601d2cb81eabc41629cb1645ee8ded9a (commit)
       via  8de8bc583834d843933b78db1b2c39540e5008f4 (commit)
       via  08587e0e972d52df43944204b13fa242c8686da8 (commit)
       via  5c08fc27cfc2f3b2f0f99ce45726eb7c5536d5a2 (commit)
       via  71ee8544e95d216e80871e154bd4dd8a7deef553 (commit)
       via  dc150b8b6b45d6db26d33ec07fe639b78d4e3980 (commit)
       via  59d0f4e4813b91dd0ff514a0e7897182f5b35ff9 (commit)
       via  9b95139e8eac7755349d05c36e7e3d3ca61d23d1 (commit)
       via  b0951b40055c914c8717322b20478f3f68e99814 (commit)
       via  e671936b613d47e2c52da5ac599e832b00abbc2d (commit)
       via  83cf329e2bb26514f6c0c53d3fc20498a9805218 (commit)
       via  461825d9a84dc5abe78618b83662afea3fbd44f5 (commit)
       via  84f6074fbfd11392f93ad53318a735355bae2864 (commit)
       via  0a3182d50e4960531c26f306e76434eefea1c099 (commit)
       via  b605120493b2d8fab063ef11bf74d40bf80dd018 (commit)
      from  4932e8d78447c6e4d74c7c87865caf2fec7fe5b1 (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
=========

 globalconst.h                     |    2 +-
 src/Makefile.am                   |    2 +
 src/action.c                      |  282 ++++++++----------
 src/autoplace.c                   |  101 +++----
 src/autoroute.c                   |  100 +++---
 src/box.h                         |   26 +-
 src/buffer.c                      |   33 +--
 src/buffer.h                      |    4 +-
 src/change.c                      |   58 ++--
 src/change.h                      |   20 +-
 src/command.c                     |   18 +-
 src/const.h                       |   10 +-
 src/copy.c                        |   10 +-
 src/copy.h                        |    6 +-
 src/create.c                      |  157 +++++------
 src/create.h                      |   63 ++---
 src/crosshair.c                   |   95 ++++---
 src/crosshair.h                   |   16 +-
 src/djopt.c                       |   10 +-
 src/djopt.h                       |    4 +-
 src/draw.c                        |   17 +-
 src/draw.h                        |    2 +-
 src/file.c                        |   63 ++--
 src/find.c                        |  593 +++++++++++++-----------------------
 src/find.h                        |    2 +-
 src/flags.c                       |   20 +-
 src/fontmode.c                    |   34 +-
 src/global.h                      |   36 +--
 src/gpcb-menu.res.in              |   44 ++--
 src/hid.h                         |   28 +-
 src/hid/batch/batch.c             |    2 +-
 src/hid/bom/bom.c                 |   53 ++--
 src/hid/common/actions.c          |    3 +-
 src/hid/common/draw_helpers.c     |   84 +++---
 src/hid/common/extents.c          |   16 +-
 src/hid/common/hidgl.c            |   30 +-
 src/hid/common/hidgl.h            |   12 +-
 src/hid/common/hidinit.c          |   68 ++++-
 src/hid/common/hidnogui.c         |   18 +-
 src/hid/gcode/gcode.c             |   70 ++---
 src/hid/gerber/gerber.c           |   72 +++---
 src/hid/gtk/gtk-pcb-coord-entry.c |  279 +++++++++++++++++
 src/hid/gtk/gtk-pcb-coord-entry.h |   35 +++
 src/hid/gtk/gtkhid-gdk.c          |   43 ++--
 src/hid/gtk/gtkhid-gl.c           |   18 +-
 src/hid/gtk/gtkhid-main.c         |   72 +++--
 src/hid/gtk/gui-config.c          |  276 +++++++-----------
 src/hid/gtk/gui-dialog-print.c    |   66 ++++-
 src/hid/gtk/gui-dialog-size.c     |  169 +++--------
 src/hid/gtk/gui-drc-window.c      |   73 ++----
 src/hid/gtk/gui-drc-window.h      |   14 +-
 src/hid/gtk/gui-log-window.c      |   61 +----
 src/hid/gtk/gui-misc.c            |   90 +-----
 src/hid/gtk/gui-netlist-window.c  |    6 +-
 src/hid/gtk/gui-output-events.c   |    6 +-
 src/hid/gtk/gui-top-window.c      |   16 +-
 src/hid/gtk/gui-utils.c           |  105 +++++++-
 src/hid/gtk/gui.h                 |   78 +++---
 src/hid/lesstif/dialogs.c         |  109 +++----
 src/hid/lesstif/lesstif.h         |    6 +-
 src/hid/lesstif/library.c         |    4 +-
 src/hid/lesstif/main.c            |  224 ++++++++-------
 src/hid/lesstif/menu.c            |   17 +-
 src/hid/lesstif/netlist.c         |    6 +-
 src/hid/lesstif/styles.c          |   46 ++--
 src/hid/lpr/lpr.c                 |    2 +-
 src/hid/nelma/nelma.c             |   55 ++--
 src/hid/png/png.c                 |   81 ++----
 src/hid/ps/eps.c                  |   56 ++--
 src/hid/ps/ps.c                   |   70 +++---
 src/insert.c                      |   31 +--
 src/insert.h                      |    4 +-
 src/intersect.c                   |   24 +-
 src/line.c                        |   26 +-
 src/line.h                        |    2 +-
 src/main.c                        |   93 ++++---
 src/mirror.c                      |    2 +-
 src/mirror.h                      |    2 +-
 src/misc.c                        |  311 ++++++-------------
 src/misc.h                        |    9 +-
 src/move.c                        |   21 +-
 src/move.h                        |    9 +-
 src/mtspace.c                     |   36 ++--
 src/mtspace.h                     |    6 +-
 src/netlist.c                     |    2 +-
 src/parse_y.y                     |   18 +-
 src/pcb-menu.res.in               |   44 ++--
 src/pcb-printf.c                  |  200 +++++++++++--
 src/pcb-printf.h                  |   62 ++++-
 src/polyarea.h                    |   11 +-
 src/polygon.c                     |   42 ++--
 src/polygon.h                     |   25 +-
 src/polygon1.c                    |    2 +-
 src/puller.c                      |    4 +-
 src/report.c                      |   39 ++--
 src/rotate.c                      |   41 +--
 src/rotate.h                      |   21 +-
 src/rubberband.c                  |   16 +-
 src/search.c                      |  351 ++++++++++-------------
 src/search.h                      |   25 +-
 src/set.c                         |   20 +-
 src/set.h                         |   18 +-
 src/thermal.c                     |   21 +-
 src/toporouter.c                  |    4 +-
 src/undo.c                        |   26 +-
 src/undo.h                        |    6 +-
 src/vendor.c                      |   12 +-
 107 files changed, 2993 insertions(+), 2960 deletions(-)
 create mode 100644 src/hid/gtk/gtk-pcb-coord-entry.c
 create mode 100644 src/hid/gtk/gtk-pcb-coord-entry.h


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

commit 97b3260ecf977dcaa959e51fbd39c6b0d7b414b7
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    *** CONVERT PCB'S BASE UNITS TO NANOMETERS ***
    
    Convert base units to nm, change Coord from int to long,
    change LARGE_VALUE from a magic number to (LONG_MAX / 2 - 1).
    
    Fixes-bug: lp-772027

:100755 100755 605d909... 6599823... M	globalconst.h
:100644 100644 4f4534c... 0885871... M	src/const.h
:100644 100644 731742d... a3a4ac1... M	src/global.h
:100644 100644 cd6ccfa... 5dc761d... M	src/main.c

commit a420e4ba801eb7b9f12b528ec8930ec4d51935a5
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Make MARK_SIZE base-unit-agnostic

:100644 100644 1575b09... 4f4534c... M	src/const.h

commit 62f17fa6c48449e36101167d9a3a26455f568721
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement "change unit" submenu of GtkPcbCoordEntry context menu

:100644 100644 3606b70... b7037cd... M	src/hid/gtk/gtk-pcb-coord-entry.c

commit be678ec6a077fa12ebb18ec0ee32156f2170b5f6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use GtkPcbCoordEntry in gui-dialog-print.c
    
    Also set ps-bloat to HID_Coord from HID_Integer in ps.c

:100644 100644 16fa132... a0d28f3... M	src/hid/gtk/gui-dialog-print.c
:100644 100644 fa0835f... fb9b8cc... M	src/hid/ps/ps.c

commit ebaf330e660455a877acaa4877d988244f0aa7c8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use GtkPcbCoordEntry in gui-dialog-size.c

:100644 100644 b57438f... 3606b70... M	src/hid/gtk/gtk-pcb-coord-entry.c
:100644 100644 e97f391... 3827ccf... M	src/hid/gtk/gtk-pcb-coord-entry.h
:100644 100644 54d294b... 1505635... M	src/hid/gtk/gui-config.c
:100644 100644 1cc59ad... 27c0336... M	src/hid/gtk/gui-dialog-size.c
:100644 100644 5df42af... 422b761... M	src/pcb-printf.c
:100644 100644 f86d4d9... 453b6ef... M	src/pcb-printf.h

commit 32c731f1edb62a6e4ed455084e9900ae94e522f9
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce GtkPcbCoordEntry widget, use it in gui-config.c
    
    The GtkPcbCoordEntry is a modified spinbox that handles
    pcb units internally and outputs them as human units. It
    uses the step sizes given in pcb-printf and adjusts
    automatically when units are changed.
    
    If you manually change the unit suffix, it will change
    its interal unit, so that if you change "10mil" to "10mm"
    it will do the right thing.
    
    TODO: handle overflows
          add a unit selector to the context menu

:100644 100644 75c6886... 9df4a50... M	src/Makefile.am
:000000 100644 0000000... b57438f... A	src/hid/gtk/gtk-pcb-coord-entry.c
:000000 100644 0000000... e97f391... A	src/hid/gtk/gtk-pcb-coord-entry.h
:100644 100644 e4127cb... 54d294b... M	src/hid/gtk/gui-config.c
:100644 100644 d6e42d2... a36057b... M	src/hid/gtk/gui-utils.c
:100644 100644 807afce... 752c184... M	src/hid/gtk/gui.h

commit 6d7ab8297a73fd8ccc01e7e81ba82e2b49ae598c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit hidgl stuff, implement Coord
    
    I did not touch any code, only change 'int' to Coord where
    appropriate (and in a couple cases 'double' to Coord), under
    the assumption that any real changes should be done by Peter
    C.

:100644 100644 2ba295e... 6bd48c3... M	src/hid/common/hidgl.c
:100644 100644 3af338d... 858270a... M	src/hid/common/hidgl.h
:100644 100644 71ab0fa... 95ab93d... M	src/hid/gtk/gtkhid-gl.c

commit fa2a0e35a644646b400cba4c075710c0f0742771
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce HID_Coord type and related changes
    
    Give measure-specific HID options their own datatype,
    so that things like the --grid option can support suffixes
    instead of exposing the base unit. (In fact, since they
    use GetValue, they will keep right on pretending the base
    unit is cmil.)
    
    This gives us the opportunity to write measure-entry GUI
    widgets that will handle units correctly and whatnot, though
    I have not yet done this.
    
    Fixes-bug: lp-699640
    Fixes-bug: lp-699641

:100644 100644 505b4f2... b1f532f... M	src/hid.h
:100644 100644 120dffd... 0bdd395... M	src/hid/common/hidinit.c
:100644 100644 1b1e93e... e4127cb... M	src/hid/gtk/gui-config.c
:100644 100644 ee8b282... 16fa132... M	src/hid/gtk/gui-dialog-print.c
:100644 100644 b7e6c16... 75e4a20... M	src/hid/lesstif/dialogs.c
:100644 100644 e81c3e4... 1ca229d... M	src/hid/lesstif/lesstif.h
:100644 100644 d079d0c... ad10772... M	src/hid/lesstif/main.c
:100644 100644 a54896a... cd6ccfa... M	src/main.c

commit 0803816da4460d0bb25b92a4fd67400873da5907
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change lesstif_logv to use pcb-printf [rebase-after: audit lesstif]

:100644 100644 0460a4e... b7e6c16... M	src/hid/lesstif/dialogs.c

commit 4cc668bb98e986cb16c28e3dac9e71130b814c82
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit lesstif HID
    
    We can now remove LocationType and BDimension! This marks the
    completion of the code audit. Remaining to do is the conversion
    and test.

:100644 100644 666d0cf... 731742d... M	src/global.h
:100644 100644 7449d50... a715ffd... M	src/gpcb-menu.res.in
:100644 100644 5606e5b... 0460a4e... M	src/hid/lesstif/dialogs.c
:100644 100644 ef0b164... d079d0c... M	src/hid/lesstif/main.c
:100644 100644 ee07273... b6e3b51... M	src/hid/lesstif/styles.c
:100644 100644 fc3008a... 7e6e8bd... M	src/pcb-menu.res.in

commit e46c9ef9505e88e446f003e5d89df0547c65b3f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit Gtk HID

:100644 100644 99472cd... c38cbc5... M	src/hid/gtk/gtkhid-gdk.c
:100644 100644 5c554fa... 71ab0fa... M	src/hid/gtk/gtkhid-gl.c
:100644 100644 e964b8e... 5f6d58f... M	src/hid/gtk/gui-log-window.c
:100644 100644 396abe1... 3ed276c... M	src/hid/gtk/gui-misc.c
:100644 100644 2bb3dd7... 527945a... M	src/hid/gtk/gui-output-events.c
:100644 100644 2f63b57... 807afce... M	src/hid/gtk/gui.h

commit c73e0ee01e6b348aa772919225afaab31ee2f1df
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit HID nogui/common code

:100644 100644 d7ef716... 03e82d8... M	src/hid/common/draw_helpers.c
:100644 100644 2de34ac... 6cdc135... M	src/hid/common/extents.c
:100644 100644 55e6dca... 9d88086... M	src/hid/common/hidnogui.c

commit 7822af60f7b28648eb41b2a2ae1aa5d55dd54182
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit nelma HID

:100644 100644 6e1e9cd... e91594b... M	src/hid/nelma/nelma.c

commit ec8937d84ef409007438d78f8d9b6b8bd1440119
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit png HID

:100644 100644 583b165... 61437a0... M	src/hid/png/png.c

commit be98cd59b2fb3e027c2b9f441603dc6d799899f0
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit gcode HID

:100644 100644 2a3cff6... 07e3d35... M	src/hid/gcode/gcode.c

commit 48cea1ad5e8b183d769d762ce98498ae3d1f907c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit ps.c

:100644 100644 307a89a... fa0835f... M	src/hid/ps/ps.c

commit 736c3f2987c8d394140446455913c25a9d5b90b3
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit eps.c

:100644 100644 8916507... 903270e... M	src/hid/ps/eps.c

commit 4dcbf39a2531705a2f8b2e40c52e3bbdebcae8da
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit gerber HID

:100644 100644 44fbe40... 8829527... M	src/hid/gerber/gerber.c

commit da403312d4c45b3d286b1b836affe2d002cfba7c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement new unit selector in BOM HID, audit bom.c

:100644 100644 e49c157... 70b0567... M	src/hid/bom/bom.c

commit 4f0ce31aecdadc65d79fa4838b32d8312086c64c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce HID_Unit option type

:100644 100644 6bc89c5... 505b4f2... M	src/hid.h
:100644 100644 89bd6eb... e49c157... M	src/hid/bom/bom.c
:100644 100644 58d1880... 120dffd... M	src/hid/common/hidinit.c
:100644 100644 bae327d... 2a3cff6... M	src/hid/gcode/gcode.c
:100644 100644 5a4d84c... 44fbe40... M	src/hid/gerber/gerber.c
:100644 100644 083ce25... 1b1e93e... M	src/hid/gtk/gui-config.c
:100644 100644 4a2fb85... ee8b282... M	src/hid/gtk/gui-dialog-print.c
:100644 100644 5db7b42... d6e42d2... M	src/hid/gtk/gui-utils.c
:100644 100644 6cd85e5... 2f63b57... M	src/hid/gtk/gui.h
:100644 100644 3d46fec... 65f0491... M	src/hid/lpr/lpr.c
:100644 100644 4f5f748... 6e1e9cd... M	src/hid/nelma/nelma.c
:100644 100644 bfa98ad... 583b165... M	src/hid/png/png.c
:100644 100644 8fe5d82... 8916507... M	src/hid/ps/eps.c
:100644 100644 201b721... 307a89a... M	src/hid/ps/ps.c
:100644 100644 8d6509a... a54896a... M	src/main.c

commit 7b8f7840a1247a3523a0a26ad06cb5fc3638fdf8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change drawing function coords in hid.h to Coord from int
    
    Note that this causes a slew of compilation warnings about
    mismatched pointer types, since the HIDs themselves are still
    using int-taking functions. These warnings will be cleaned up
    over the next few commits.

:100644 100644 efa2dfd... 6bc89c5... M	src/hid.h

commit affb432342fe81557c6427ed87da0da611b70c41
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit crosshair.[ch], implement Coord

:100644 100644 2b0e9b8... d927cf8... M	src/crosshair.c
:100644 100644 3fbd998... 8c42067... M	src/crosshair.h

commit 4632e403310efaef0b8bb3e48f5d5a839398f6e7
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit parse_y.y, implement Coord

:100644 100644 9c1bb6a... 8cf1888... M	src/parse_y.y

commit f97d92bfbb9580a54a6d1770ffa3973420fb49ab
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit mtspace.[ch], implement Coord

:100644 100644 40f5413... a4bb314... M	src/mtspace.c
:100644 100644 b2872cd... c169170... M	src/mtspace.h

commit 2217294268a1d5dee74ab96f059eeba5ed7c9995
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit report.c, implement Coord
    
    Includes fixes for the original pcb-printf conversion:
      Fix drill report spacing in report.c
      Use %ma spec outputting angles in report.c

:100644 100644 ed81060... f86d4d9... M	src/pcb-printf.h
:100644 100644 dbcf776... 56e1fa9... M	src/report.c

commit 732d85dd996d352b19dee8c3232688b38b7819b4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit autoroute.[ch], implement Coord
    
    There are many magic numbers in this file. It is likely
    they will be skewed by base-unit changes, though I have
    worked to mitigate this.

:100644 100644 63ab15c... 34e01dc... M	src/autoroute.c

commit dfbd2188bb9dadc5efbea8871e3ba49ccb79d3ff
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit autoplace.c, implement Coord
    
    Note that there are -many- magic numbers in this file.
    I believe I've caught all of them that are supposed to
    be unit conversions and used macros instead.

:100644 100644 991cf9e... 0e74b66... M	src/autoplace.c

commit 5456171cbd9129402acfc6596d1cd7b742880324
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit create.[ch], implement Coord

:100644 100644 f33ca43... 93c17a2... M	src/action.c
:100644 100644 b5081fa... b57f4a5... M	src/create.c
:100644 100644 ec964fa... ccab272... M	src/create.h

commit 8c1777bf0e9fbcbb06d448847dcc09052fd030e6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit line.[ch], intersect.c, implement Coord

:100644 100644 e7612e9... a3ee03f... M	src/intersect.c
:100644 100644 7da09dc... 22efc2b... M	src/line.c
:100644 100644 a59f1bb... 82db33a... M	src/line.h

commit 3d0d2c0a0edd60ec445a64e1be53cd7c6628dcea
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit find.[ch], implement Coord
    
    Note that this commits brings major simplifications to some
    DRC functions. My tests show everything okay, but there will
    likely be some bugs (or bug fixes) as a result of this
    commit.

:100644 100644 a3fbc1c... 2b47874... M	src/find.c
:100644 100644 9560bd9... d2be7ac... M	src/find.h

commit 44db9c716a572748a7f5fc5f1bc7e5c1d84bb8fe
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove fBloat from find.c
    
    fBloat does nothing except act as a floating point copy
    of the integer Bloat variable. It should not be (and is
    not) necessary.

:100644 100644 b7ab673... a3fbc1c... M	src/find.c

commit 2c737bfc51c420b9ef173860c31ef57ccde6edf6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Fix g_string_free (NULL) error

:100644 100644 5cd0df1... b7ab673... M	src/find.c

commit 06f059a973d4320f078de7a0e75023e1690baaee
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove coord suffix/precision from DRC error struct
    
    Display units for DRC errors are now handled by the UI,
    rather than in the error struct. The struct now stores
    everything in Coord's, and pcb-printf worries about how
    to display them.

:100644 100644 5b7ac4c... 666d0cf... M	src/global.h
:100644 100644 6d50d16... 65e64a2... M	src/hid/gtk/gui-drc-window.c
:100644 100644 9bd26cf... 8b3558a... M	src/hid/gtk/gui-drc-window.h

commit 4545d537e6db4bf418ffecaf9bdfecd3ec22854f
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit file.c, implement Coord

:100644 100644 8f9bee5... 1c68abc... M	src/file.c

commit 656f5925148e5a747bc55c618ff3843eddc65d07
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use pcb-printf in DRC code in find.c
    
    Also, expose pcb_vprintf in pcb_printf.h.

:100644 100644 5b30e93... 5cd0df1... M	src/find.c
:100644 100644 7baffbb... 5df42af... M	src/pcb-printf.c
:100644 100644 6534945... ed81060... M	src/pcb-printf.h

commit 5ff5b13ab3cd84247281190492dd834f24226893
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit draw.[ch], implement Coord

:100644 100644 ef465cb... 8950539... M	src/draw.c
:100644 100644 bda02f8... 484ae98... M	src/draw.h

commit 1f802a7f01378217d519d2da25234fa0e105ddda
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit change.[ch], box.h, implement Coord

:100644 100644 3dc779e... 1c8311a... M	src/box.h
:100644 100644 70e5470... fb6e62c... M	src/change.c
:100644 100644 94a0e21... 64c44ff... M	src/change.h

commit b59ab044afe3ac362f8cb4da10ea410280b4323a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit copy.[ch], insert.[ch], mirror.[ch], implement Coord

:100644 100644 4091389... 29ac62f... M	src/copy.c
:100644 100644 bd2ea80... e65c272... M	src/copy.h
:100644 100644 9313807... 514754f... M	src/insert.c
:100644 100644 51c75e4... 0476e8d... M	src/insert.h
:100644 100644 7ef7d41... c48ebf3... M	src/mirror.c
:100644 100644 94d17c1... da61744... M	src/mirror.h

commit a2af8aa83d106a9f0800ea5fe502e8d0e99ac651
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit misc.[ch], implement Coord

:100644 100644 97937aa... 7c6f958... M	src/misc.c
:100644 100644 21fec7e... deaca84... M	src/misc.h

commit 27de2a3b9075415d6664bdb39c6e59cba970c441
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit move.[ch], implement Coord

:100644 100644 3477af1... 6b6359a... M	src/move.c
:100644 100644 2b41bce... e617eca... M	src/move.h

commit 6d08a5996f48dece369b278b1ca41cd8250b4e3c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit polygon*, polyarea.h, implement Coord

:100644 100644 413f519... 43fd93d... M	src/polyarea.h
:100644 100644 72a9299... 7367968... M	src/polygon.c
:100644 100644 e3b31c0... bdbef46... M	src/polygon.h
:100644 100644 ffb1542... 9da353e... M	src/polygon1.c

commit 912ce4d8601d2cb81eabc41629cb1645ee8ded9a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit rotate.[ch], implement Coord

:100644 100644 1667985... 11b8fd9... M	src/rotate.c
:100644 100644 c9c78b8... 7748b19... M	src/rotate.h

commit 8de8bc583834d843933b78db1b2c39540e5008f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit search.[ch], implement Coord unit
    
    This does not affect the "IsPointOnArc assumes circular
    arc" bug; it is just more obvious now with the cleaner
    code.
    
    Affects-bug: lp-815527

:100644 100644 ef9b9a7... f12f473... M	src/search.c
:100644 100644 b6ddaa2... b1a6196... M	src/search.h

commit 08587e0e972d52df43944204b13fa242c8686da8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit undo.[ch], thermal.c, set.[ch], rubberband.c, introduce Coord

:100644 100644 31ed1b7... 4fe166c... M	src/rubberband.c
:100644 100644 074a6ac... 1f86adb... M	src/set.c
:100644 100644 af6115a... 4bfe6ec... M	src/set.h
:100644 100644 d1df1fc... 03fee24... M	src/thermal.c
:100644 100644 971c771... 576b9cb... M	src/undo.c
:100644 100644 9b088ff... a6cd324... M	src/undo.h

commit 5c08fc27cfc2f3b2f0f99ce45726eb7c5536d5a2
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change get_coord and action signatures to use Coord

:100644 100644 f1083f7... f33ca43... M	src/action.c
:100644 100644 0943f1a... ac2aa54... M	src/buffer.c
:100644 100644 2ff9496... e589fd4... M	src/buffer.h
:100644 100644 5c2b985... 4c3a419... M	src/command.c
:100644 100644 80fa3c1... 1d8332d... M	src/djopt.c
:100644 100644 76ee3b6... bc337af... M	src/djopt.h
:100644 100644 04b230d... 8130b59... M	src/fontmode.c
:100644 100644 477798b... 5b7ac4c... M	src/global.h
:100644 100644 b2725ac... efa2dfd... M	src/hid.h
:100644 100644 962c594... f486ef3... M	src/hid/batch/batch.c
:100644 100644 43c50f8... da3bbfd... M	src/hid/common/actions.c
:100644 100644 aef38b8... 55e6dca... M	src/hid/common/hidnogui.c
:100644 100644 a9c994e... 68775c1... M	src/hid/gtk/gtkhid-main.c
:100644 100644 a91f346... e964b8e... M	src/hid/gtk/gui-log-window.c
:100644 100644 bc3fc69... 28d0ff2... M	src/hid/gtk/gui-netlist-window.c
:100644 100644 bc47214... 2bb3dd7... M	src/hid/gtk/gui-output-events.c
:100644 100644 7b210f8... aaab38e... M	src/hid/gtk/gui-top-window.c
:100644 100644 e8123d9... 6cd85e5... M	src/hid/gtk/gui.h
:100644 100644 27d312c... 5606e5b... M	src/hid/lesstif/dialogs.c
:100644 100644 c4a2df4... e81c3e4... M	src/hid/lesstif/lesstif.h
:100644 100644 5ce77f7... 029a023... M	src/hid/lesstif/library.c
:100644 100644 1c4d8b9... ef0b164... M	src/hid/lesstif/main.c
:100644 100644 fe45b32... 8c71c61... M	src/hid/lesstif/menu.c
:100644 100644 e5575d2... ce28539... M	src/hid/lesstif/netlist.c
:100644 100644 9442849... ee07273... M	src/hid/lesstif/styles.c
:100644 100644 8db434a... 97937aa... M	src/misc.c
:100644 100644 49177e9... 3477af1... M	src/move.c
:100644 100644 0c004f9... 06f0e77... M	src/netlist.c
:100644 100644 2fd37bc... 959ac54... M	src/puller.c
:100644 100644 e0ae113... dbcf776... M	src/report.c
:100644 100644 3b52f24... e5310b0... M	src/toporouter.c
:100644 100644 aa766bb... 2abcca0... M	src/vendor.c

commit 71ee8544e95d216e80871e154bd4dd8a7deef553
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce PCB::grid::unit attribute
    
    This is PCB's first use of the Attribute() field in the
    file format. It is a unit suffix string denoting the unit
    setting used by pcb when loading the file.
    
    Note the namespacing: as Attributes are persistent across
    file-saves, other programs may use them in future for
    purposes unknown and irrelevant to pcb. Therefore we will
    put all pcb attributes under the PCB namespace.
    
    If this attribute is missing or invalid (i.e., the unit
    given is unsupported by pcb-printf), PCB will then use the
    --grid-units command-line option. Failing that, it will
    use the grid-units entry in ~/.pcb/preferences. Failing
    that, it will use mils.
    
    Fixes-bug: lp-811393

:100644 100644 e5eb93f... 8f9bee5... M	src/file.c
:100644 100644 7699cf9... a9c994e... M	src/hid/gtk/gtkhid-main.c
:100644 100644 9108f2c... 1c4d8b9... M	src/hid/lesstif/main.c

commit dc150b8b6b45d6db26d33ec07fe639b78d4e3980
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Modify get_unit_struct()'s bad-unit forgiveness
    
    Suffixes passed to get_unit_struct() may now start or end
    with whitespace, without affecting the result. However,
    incomplete units will NOT be matched.
    
    This means that "mi" will no longer return the "mil" struct,
    for example.
    
    The reasons for this change are:
      1. The old behavior returned the first potential match,
         regardless of other matches: "c" is always "cm", never
         "cmil".
      2. Prevent surprises (due to point #1, or typos).
      3. Prevent user dependence on behavior that will change
         as units are added or removed.
    
    It still supports plural units, like "inches" or "mils".
    However, it will read "miles" as "mil" because of this. ;)

:100644 100644 0203e32... 7baffbb... M	src/pcb-printf.c

commit 59d0f4e4813b91dd0ff514a0e7897182f5b35ff9
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add alias support, get_unit_list() to pcb-printf
    
    Add pcb-printf support for unit aliases (just one per unit
    for now, we will fix this if the need arises). Map "inch"
    to "in" and "pcb" to "cmil" for backward compatibility.
    
    Move initialize_units() call to main.c to ensure it is called
    before any other unit-handling code.
    
    Also, add the functions
      get_unit_list ();
      get_n_units ();
    which do exactly what they look like. These will be used
    to build HID-export unit selectors.

:100644 100644 d007f87... 8d6509a... M	src/main.c
:100644 100644 82c9492... 0203e32... M	src/pcb-printf.c
:100644 100644 07cd80a... 6534945... M	src/pcb-printf.h

commit 9b95139e8eac7755349d05c36e7e3d3ca61d23d1
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use suffixed units in gpcb-menu.res and pcb-menu.res

:100644 100644 bb5b8bf... 7449d50... M	src/gpcb-menu.res.in
:100644 100644 22847e9... fc3008a... M	src/pcb-menu.res.in

commit b0951b40055c914c8717322b20478f3f68e99814
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Make file.c use %mr pcb-printf spec
    
    I have changed the %mr spec to always output cmils,
    no suffix, and changed file.c to use this. The reason
    is that the %mc spec (cmils, no suffix) is locale-
    dependent, while %mr is not.
    
    When we change the actual file format, file.c can be
    left alone and the relevant changes should be done to
    the %mr spec in pcb-printf.

:100644 100644 6ff6132... 0943f1a... M	src/buffer.c
:100644 100644 7182a9d... 2ff9496... M	src/buffer.h
:100644 100644 cd31935... b5081fa... M	src/create.c
:100644 100644 b7349bb... e5eb93f... M	src/file.c
:100644 100644 ec388a9... 477798b... M	src/global.h
:100644 100644 83e2bb7... 8db434a... M	src/misc.c
:100644 100644 2f2ccec... 21fec7e... M	src/misc.h
:100644 100644 895ae12... 82c9492... M	src/pcb-printf.c
:100644 100644 65c9e5a... 07cd80a... M	src/pcb-printf.h
:100644 100644 017eb0c... 1667985... M	src/rotate.c

commit e671936b613d47e2c52da5ac599e832b00abbc2d
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Update hid/gtk/gui-config.c with new grid preferences

:100644 100644 9443a0f... 083ce25... M	src/hid/gtk/gui-config.c

commit 83cf329e2bb26514f6c0c53d3fc20498a9805218
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove mm/mil dichotomy, support arbitrary user units
    
    Currently, pcb assumes the user's display units are either mm
    or mil, and uses the Settings.grid_unit_mm boolean (and flag
    "grid_unit_mm") to determine which is which.
    
    This patch removes the boolean and replaces it with the new
    Settings.grid_unit, which can be set to any unit supported by
    pcb-printf. The user-visible interface has not changed (there
    is still a mm/mil toggle in Gtk and the menus only contain mm
    and mil units), but new units can be accessed though the
    :SetUnits command.
    
    The flag is still there and can be used in pcb-menu.res as
    usual. However, the new flag "grid_unit_mil" should be checked
    to see if mils are selected, since this is no longer implied
    by grid_unit_mm == 0.
    
    There will be some user-visible changes to the precision of
    displayed values, since I have removed a lot of special-case
    code for this sort of this thing and use the default_prec
    of applicable units instead.
    
    Because of the new flexibility, some idioms have been changed:
    
      Settings.grid_unit_mm ? COORD_TO_MM (x) : COORD_TO_MIL (x)
    becomes
      coord_to_unit (Settings.grid_unit, x)
    
      Settings.grid_unit_mm ? "mm" : "mil"
    becomes
      Settings.grid_unit->suffix
    
      Settings.grid_unit_mm = 1;
    becomes
      Settings.grid_unit = get_unit_struct ("mm");
    
    For GUI use, the Unit structure returned by get_unit_struct
    exposes certain members:
    
      suffix       : "mm"/"mil"/etc
      in_suffix    : i18n version of the above
      default_prec : precision used for spinboxes, labels, etc
    
      step_tiny    :
      step_small   :
      step_medium  : step sizes for various spinboxes
      step_large   :
      step_huge    :
    
    Additionally, the *_increment_mm and *_increment_mil variables
    have their own structure containing default, min and max values.
    These can no longer be set on the command line.

:100644 100644 ef37641... b7349bb... M	src/file.c
:100644 100644 43dee33... 5b30e93... M	src/find.c
:100644 100644 a167663... a4e5fe5... M	src/flags.c
:100644 100644 9341940... ec388a9... M	src/global.h
:100644 100644 dc594c4... bb5b8bf... M	src/gpcb-menu.res.in
:100644 100644 a4cd443... 7699cf9... M	src/hid/gtk/gtkhid-main.c
:100644 100644 685e4b2... 9443a0f... M	src/hid/gtk/gui-config.c
:100644 100644 0c0f8ef... 1cc59ad... M	src/hid/gtk/gui-dialog-size.c
:100644 100644 00791e3... 396abe1... M	src/hid/gtk/gui-misc.c
:100644 100644 e9c2669... 7b210f8... M	src/hid/gtk/gui-top-window.c
:100644 100644 bc15628... e8123d9... M	src/hid/gtk/gui.h
:100644 100644 2f956a9... 27d312c... M	src/hid/lesstif/dialogs.c
:100644 100644 d275af0... 9108f2c... M	src/hid/lesstif/main.c
:100644 100644 91e8c79... 9442849... M	src/hid/lesstif/styles.c
:100644 100644 1e88e52... 22847e9... M	src/pcb-menu.res.in
:100644 100644 b941c4d... 65c9e5a... M	src/pcb-printf.h
:100644 100644 53b8b41... e0ae113... M	src/report.c

commit 461825d9a84dc5abe78618b83662afea3fbd44f5
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Cleanup default values in main.c

:100644 100644 2754864... d007f87... M	src/main.c

commit 84f6074fbfd11392f93ad53318a735355bae2864
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce new structures (unit, increment) to pcb-printf
    
    Constants for gui spinbox steps are now in pcb-printf.h:
      Unit.step_tiny
      Unit.step_small
      Unit.step_medium
      Unit.step_large
      Unit.step_huge
    
    Additionally, the default/max/min values for the preferences
    Increments tab are in their own structure in pcb-printf.h.
    
    These changes are needed to bring all unit-specific constants
    into one place. The spinbox values can be shared by gtk and
    lesstif.

:100644 100644 a0aa5e3... 83e2bb7... M	src/misc.c
:100644 100644 8b086a1... 895ae12... M	src/pcb-printf.c
:100644 100644 c41fe7b... b941c4d... M	src/pcb-printf.h

commit 0a3182d50e4960531c26f306e76434eefea1c099
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add scale factor lookups to pcb_printf.c, tell GetValue to use them
    
    GetValue and pcb-printf have their own lookup tables to determine
    scale factors. To unify them, this patch adds two functions to pcb-
    printf, coord_to_unit and unit_to_coord.
    
    These a const char *suffix and return an appropriate scale factor.
    
    I have also added a NO_PRINT entry to the allow_mask array for
    suffixes like "inch" that we can read but never output.
    
    The definitive unit lookup table should now be in pcb_printf.c. Any
    other tables used in the code should be merged into this.

:100644 100644 e1dff74... a0aa5e3... M	src/misc.c
:100644 100644 4410691... 8b086a1... M	src/pcb-printf.c
:100644 100644 31346f4... c41fe7b... M	src/pcb-printf.h

commit b605120493b2d8fab063ef11bf74d40bf80dd018
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Convert grid/increments from double to Coord
    
    Since Coord is an integer unit, there will be (often
    severe) precision errors until we convert the base unit
    to nm.

:100644 100644 30d9745... f1083f7... M	src/action.c
:100644 100644 65eef92... 991cf9e... M	src/autoplace.c
:100644 100644 76b072b... 2b0e9b8... M	src/crosshair.c
:100644 100644 15b3470... 3fbd998... M	src/crosshair.h
:100644 100644 d25d621... 80fa3c1... M	src/djopt.c
:100644 100644 abdb444... ef37641... M	src/file.c
:100644 100644 499e59e... a167663... M	src/flags.c
:100644 100644 2575a33... 04b230d... M	src/fontmode.c
:100644 100644 0ae5d22... 9341940... M	src/global.h
:100644 100644 992f3e3... 2ba295e... M	src/hid/common/hidgl.c
:100644 100644 e9b5b3e... 99472cd... M	src/hid/gtk/gtkhid-gdk.c
:100644 100644 79d543d... 685e4b2... M	src/hid/gtk/gui-config.c
:100644 100644 cadd2aa... 00791e3... M	src/hid/gtk/gui-misc.c
:100644 100644 c4da30f... bc15628... M	src/hid/gtk/gui.h
:100644 100644 ff6d8cd... d275af0... M	src/hid/lesstif/main.c
:100644 100644 4647fea... fe45b32... M	src/hid/lesstif/menu.c
:100644 100644 8b51609... 2754864... M	src/main.c
:100644 100644 0188404... e1dff74... M	src/misc.c
:100644 100644 f904e19... 2f2ccec... M	src/misc.h
:100644 100644 c77129e... 074a6ac... M	src/set.c
:100644 100644 4985f9d... af6115a... M	src/set.h

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

commit 97b3260ecf977dcaa959e51fbd39c6b0d7b414b7
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    *** CONVERT PCB'S BASE UNITS TO NANOMETERS ***
    
    Convert base units to nm, change Coord from int to long,
    change LARGE_VALUE from a magic number to (LONG_MAX / 2 - 1).
    
    Fixes-bug: lp-772027

diff --git a/globalconst.h b/globalconst.h
index 605d909..6599823 100755
--- a/globalconst.h
+++ b/globalconst.h
@@ -60,7 +60,7 @@
 /* ---------------------------------------------------------------------------
  * some limit specifications
  */
-#define LARGE_VALUE		10000000 /* maximum extent of board and elements */
+#define LARGE_VALUE		(LONG_MAX / 2 - 1) /* maximum extent of board and elements */
  
 #define	MAX_LAYER		16	/* max number of layer, check source */
 					/* code for more changes, a *lot* more changes */
diff --git a/src/const.h b/src/const.h
index 4f4534c..0885871 100644
--- a/src/const.h
+++ b/src/const.h
@@ -68,10 +68,10 @@
 #define LN_2_OVER_2		0.346573590
 
 /* PCB/physical unit conversions */
-#define COORD_TO_MIL(n)	((n) / 100.0)
-#define MIL_TO_COORD(n)	((n) * 100.0)
-#define COORD_TO_MM(n)	((n) * 0.000254)
-#define MM_TO_COORD(n)	((n) / 0.000254)
+#define COORD_TO_MIL(n)	((n) / 25400.0)
+#define MIL_TO_COORD(n)	((n) * 25400.0)
+#define COORD_TO_MM(n)	((n) / 1000000.0)
+#define MM_TO_COORD(n)	((n) * 1000000.0)
 #define COORD_TO_INCH(n)	(COORD_TO_MIL(n) / 1000.0)
 #define INCH_TO_COORD(n)	(MIL_TO_COORD(n) * 1000.0)
 
diff --git a/src/global.h b/src/global.h
index 731742d..a3a4ac1 100644
--- a/src/global.h
+++ b/src/global.h
@@ -64,7 +64,7 @@ typedef struct AttributeListType AttributeListType, *AttributeListTypePtr;
 typedef struct unit Unit;
 typedef struct increments Increments;
 
-typedef int Coord;		/* pcb base unit */
+typedef long Coord;		/* pcb base unit */
 typedef double Angle;		/* degrees */
 
 #include "hid.h"
diff --git a/src/main.c b/src/main.c
index cd6ccfa..5dc761d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -637,8 +637,8 @@ REGISTER_ATTRIBUTES (main_attribute_list)
     Settings.ViaDrillingHole =
       DEFAULT_DRILLINGHOLE * Settings.ViaThickness / 100;
 
-  Settings.MaxWidth = MIN (MAX_COORD, MAX (Settings.MaxWidth, MIN_SIZE));
-  Settings.MaxHeight = MIN (MAX_COORD, MAX (Settings.MaxHeight, MIN_SIZE));
+  Settings.MaxWidth  = CLAMP (Settings.MaxWidth, MIN_SIZE, MAX_COORD);
+  Settings.MaxHeight = CLAMP (Settings.MaxHeight, MIN_SIZE, MAX_COORD);
 
   ParseRouteString (Settings.Routes, &Settings.RouteStyle[0], "cmil");
 

commit a420e4ba801eb7b9f12b528ec8930ec4d51935a5
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Make MARK_SIZE base-unit-agnostic

diff --git a/src/const.h b/src/const.h
index 1575b09..4f4534c 100644
--- a/src/const.h
+++ b/src/const.h
@@ -46,7 +46,7 @@
 /* ---------------------------------------------------------------------------
  * misc constants
  */
-#define	MARK_SIZE		5000	/* relative marker size */
+#define	MARK_SIZE		MIL_TO_COORD(50)	/* relative marker size */
 #define	UNDO_WARNING_SIZE	(1024*1024)	/* warning limit of undo */
 #define	USERMEDIANAME		"user defined"	/* label of default media */
 

commit 62f17fa6c48449e36101167d9a3a26455f568721
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement "change unit" submenu of GtkPcbCoordEntry context menu

diff --git a/src/hid/gtk/gtk-pcb-coord-entry.c b/src/hid/gtk/gtk-pcb-coord-entry.c
index 3606b70..b7037cd 100644
--- a/src/hid/gtk/gtk-pcb-coord-entry.c
+++ b/src/hid/gtk/gtk-pcb-coord-entry.c
@@ -37,9 +37,44 @@ struct _GtkPcbCoordEntryClass
 
 /* SIGNAL HANDLERS */
 static void
-gtk_pcb_coord_entry_popup_cb (GtkPcbCoordEntry *ce, gpointer data)
+menu_item_activate_cb (GtkMenuItem *item, GtkPcbCoordEntry *ce)
 {
-  /* TODO: Add unit chooser to menu */
+  const char *text = gtk_menu_item_get_label (item);
+  const Unit *unit = get_unit_struct (text);
+  
+  g_signal_emit (ce, gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, unit);
+}
+
+static void
+gtk_pcb_coord_entry_popup_cb (GtkPcbCoordEntry *ce, GtkMenu *menu, gpointer data)
+{
+  int i, n;
+  const Unit *unit_list;
+  GtkWidget *menu_item, *submenu;
+
+  /* Build submenu */
+  n = get_n_units ();
+  unit_list = get_unit_list ();
+
+  submenu = gtk_menu_new ();
+  for (i = 0; i < n; ++i)
+    {
+      menu_item = gtk_menu_item_new_with_label (unit_list[i].suffix);
+      g_signal_connect (G_OBJECT (menu_item), "activate",
+                        G_CALLBACK (menu_item_activate_cb), ce);
+      gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menu_item);
+      gtk_widget_show (menu_item);
+    }
+
+  /* Add submenu to menu */
+  menu_item = gtk_separator_menu_item_new ();
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+  gtk_widget_show (menu_item);
+
+  menu_item = gtk_menu_item_new_with_label (_("Change Units"));
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+  gtk_widget_show (menu_item);
 }
 
 static gboolean

commit be678ec6a077fa12ebb18ec0ee32156f2170b5f6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use GtkPcbCoordEntry in gui-dialog-print.c
    
    Also set ps-bloat to HID_Coord from HID_Integer in ps.c

diff --git a/src/hid/gtk/gui-dialog-print.c b/src/hid/gtk/gui-dialog-print.c
index 16fa132..a0d28f3 100644
--- a/src/hid/gtk/gui-dialog-print.c
+++ b/src/hid/gtk/gui-dialog-print.c
@@ -175,7 +175,9 @@ ghid_attribute_dialog (HID_Attribute * attrs,
 	  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
 	  /* FIXME: need to write a coord-entry widget for this */
-	  entry = gtk_entry_new ();
+	  entry = gtk_pcb_coord_entry_new (attrs[j].min_val, attrs[j].max_val,
+	                                   attrs[j].default_val.coord_value,
+	                                   Settings.grid_unit, CE_SMALL);
 	  gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
 	  if(attrs[j].default_val.str_value != NULL)
 	    gtk_entry_set_text (GTK_ENTRY (entry),
diff --git a/src/hid/ps/ps.c b/src/hid/ps/ps.c
index fa0835f..fb9b8cc 100644
--- a/src/hid/ps/ps.c
+++ b/src/hid/ps/ps.c
@@ -169,8 +169,8 @@ HID_Attribute ps_attribute_list[] = {
   {"ps-color", "Prints in color",
    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
 #define HA_color 7
-  {"ps-bloat", "Amount to add to trace/pad/pin edges (1 = 1/100 mil)",
-   HID_Integer, -10000, 10000, {0, 0, 0}, 0, 0},
+  {"ps-bloat", "Amount to add to trace/pad/pin edges",
+   HID_Coord, -MIL_TO_COORD (100), MIL_TO_COORD (100), {0, 0, 0}, 0, 0},
 #define HA_psbloat 8
   {"ps-invert", "Draw images as white-on-black",
    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},

commit ebaf330e660455a877acaa4877d988244f0aa7c8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use GtkPcbCoordEntry in gui-dialog-size.c

diff --git a/src/hid/gtk/gtk-pcb-coord-entry.c b/src/hid/gtk/gtk-pcb-coord-entry.c
index b57438f..3606b70 100644
--- a/src/hid/gtk/gtk-pcb-coord-entry.c
+++ b/src/hid/gtk/gtk-pcb-coord-entry.c
@@ -113,8 +113,7 @@ gtk_pcb_coord_entry_change_unit (GtkPcbCoordEntry *ce, const Unit *new_unit)
     case CE_MEDIUM: climb_rate = new_unit->step_medium; break;
     case CE_LARGE: climb_rate = new_unit->step_large; break;
     }
-  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj,
-                             coord_to_unit (new_unit, climb_rate),
+  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, climb_rate,
                              new_unit->default_prec + strlen (new_unit->suffix));
 }
 
@@ -199,20 +198,20 @@ gtk_pcb_coord_entry_new (Coord min_val, Coord max_val, Coord value,
   switch (step_size)
     {
     case CE_TINY:
-      small_step = coord_to_unit (unit, unit->step_tiny);
-      big_step   = coord_to_unit (unit, unit->step_small);
+      small_step = unit->step_tiny;
+      big_step   = unit->step_small;
       break;
     case CE_SMALL:
-      small_step = coord_to_unit (unit, unit->step_small);
-      big_step   = coord_to_unit (unit, unit->step_medium);
+      small_step = unit->step_small;
+      big_step   = unit->step_medium;
       break;
     case CE_MEDIUM:
-      small_step = coord_to_unit (unit, unit->step_medium);
-      big_step   = coord_to_unit (unit, unit->step_large);
+      small_step = unit->step_medium;
+      big_step   = unit->step_large;
       break;
     case CE_LARGE:
-      small_step = coord_to_unit (unit, unit->step_large);
-      big_step   = coord_to_unit (unit, unit->step_huge);
+      small_step = unit->step_large;
+      big_step   = unit->step_huge;
       break;
     default:
       small_step = big_step = 0;
@@ -236,3 +235,10 @@ gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce)
   return ce->value;
 }
 
+void
+gtk_pcb_coord_entry_set_value (GtkPcbCoordEntry *ce, Coord val)
+{
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (ce),
+                             coord_to_unit (ce->unit, val));
+}
+
diff --git a/src/hid/gtk/gtk-pcb-coord-entry.h b/src/hid/gtk/gtk-pcb-coord-entry.h
index e97f391..3827ccf 100644
--- a/src/hid/gtk/gtk-pcb-coord-entry.h
+++ b/src/hid/gtk/gtk-pcb-coord-entry.h
@@ -29,6 +29,7 @@ void gtk_pcb_coord_entry_add_entry (GtkPcbCoordEntry *ce, const gchar *name, con
 gchar *gtk_pcb_coord_entry_get_last_command (GtkPcbCoordEntry *ce);
 
 Coord gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce);
+void gtk_pcb_coord_entry_set_value (GtkPcbCoordEntry *ce, Coord val);
 
 G_END_DECLS  /* keep c++ happy */
 #endif
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 54d294b..1505635 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -956,11 +956,6 @@ config_general_apply (void)
 
   /* -------------- The Sizes config page ----------------
    */
-#define	STEP0_SMALL_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_tiny)
-#define	STEP1_SMALL_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_small)
-#define	STEP0_SIZE		FROM_PCB_UNITS (Settings.grid_unit->step_large)
-#define	STEP1_SIZE		FROM_PCB_UNITS (Settings.grid_unit->step_huge)
-#define	SPIN_DIGITS		(Settings.grid_unit->default_prec)
 
 static GtkWidget *config_sizes_vbox,
   *config_sizes_tab_vbox, *config_text_spin_button;
diff --git a/src/hid/gtk/gui-dialog-size.c b/src/hid/gtk/gui-dialog-size.c
index 1cc59ad..27c0336 100644
--- a/src/hid/gtk/gui-dialog-size.c
+++ b/src/hid/gtk/gui-dialog-size.c
@@ -53,17 +53,13 @@
 
 RCSID ("$Id$");
 
-#define STEP0_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_small)
-#define STEP1_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_medium)
-#define SPIN_DIGITS	(Settings.grid_unit->default_prec)
-
 typedef struct
 {
   GtkWidget *name_entry,
-    *line_width_spin_button,
-    *via_hole_spin_button,
-    *via_size_spin_button,
-    *clearance_spin_button, *set_temp1_button, *set_temp2_button;
+    *line_width_coord_entry,
+    *via_hole_coord_entry,
+    *via_size_coord_entry,
+    *clearance_coord_entry, *set_temp1_button, *set_temp2_button;
 }
 SizesDialog;
 
@@ -88,84 +84,36 @@ make_route_string(RouteStyleType * rs)
   return str;
 }
 
-/* static void */
-/* via_hole_cb (GtkWidget * widget, SizesDialog * sd) */
-/* { */
-/*   gdouble via_hole_size, via_size; */
-
-/*   via_hole_size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget)); */
-/*   via_size = */
-/*     gtk_spin_button_get_value (GTK_SPIN_BUTTON (sd->via_size_spin_button)); */
-
-/*   if (via_size < via_hole_size + FROM_PCB_UNITS (MIN_PINORVIACOPPER)) */
-/*     gtk_spin_button_set_value (GTK_SPIN_BUTTON (sd->via_size_spin_button), */
-/* 			       via_hole_size + */
-/* 			       FROM_PCB_UNITS (MIN_PINORVIACOPPER)); */
-/* } */
-
-/* static void */
-/* via_size_cb (GtkWidget * widget, SizesDialog * sd) */
-/* { */
-/*   gdouble via_hole_size, via_size; */
-
-/*   via_size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget)); */
-/*   via_hole_size = */
-/*     gtk_spin_button_get_value (GTK_SPIN_BUTTON (sd->via_hole_spin_button)); */
-
-/*   if (via_hole_size > via_size - FROM_PCB_UNITS (MIN_PINORVIACOPPER)) */
-/*     gtk_spin_button_set_value (GTK_SPIN_BUTTON (sd->via_hole_spin_button), */
-/* 			       via_size - */
-/* 			       FROM_PCB_UNITS (MIN_PINORVIACOPPER)); */
-/* } */
-
 static void
-via_hole_cb (GtkSpinButton * spinbutton, gpointer data)//SizesDialog * sd)
+via_hole_cb (GtkPcbCoordEntry * entry, gpointer data)
 {
   SizesDialog * sd = (SizesDialog *)data;
   gdouble via_hole_size, via_size;
 
-  via_hole_size = gtk_spin_button_get_value (spinbutton);
-  via_size =
-    gtk_spin_button_get_value (GTK_SPIN_BUTTON (sd->via_size_spin_button));
+  via_hole_size = gtk_pcb_coord_entry_get_value (entry);
+  via_size = gtk_pcb_coord_entry_get_value
+               (GTK_PCB_COORD_ENTRY (sd->via_size_coord_entry));
 
-  if (via_size < via_hole_size + FROM_PCB_UNITS (MIN_PINORVIACOPPER))
-    gtk_spin_button_set_value (GTK_SPIN_BUTTON (sd->via_size_spin_button),
-			       via_hole_size +
-			       FROM_PCB_UNITS (MIN_PINORVIACOPPER));
+  if (via_size < via_hole_size + MIN_PINORVIACOPPER)
+    gtk_pcb_coord_entry_set_value (GTK_PCB_COORD_ENTRY (sd->via_size_coord_entry),
+			           via_hole_size + MIN_PINORVIACOPPER);
 }
 
 static void
-via_size_cb (GtkSpinButton * spinbutton, gpointer data)//SizesDialog * sd)
+via_size_cb (GtkPcbCoordEntry * entry, gpointer data)
 {
   SizesDialog * sd = (SizesDialog *)data;
   gdouble via_hole_size, via_size;
 
-  via_size = gtk_spin_button_get_value (spinbutton);
-  via_hole_size =
-    gtk_spin_button_get_value (GTK_SPIN_BUTTON (sd->via_hole_spin_button));
+  via_size = gtk_pcb_coord_entry_get_value (entry);
+  via_hole_size = gtk_pcb_coord_entry_get_value
+                    (GTK_PCB_COORD_ENTRY (sd->via_hole_coord_entry));
 
-  if (via_hole_size > via_size - FROM_PCB_UNITS (MIN_PINORVIACOPPER))
-    gtk_spin_button_set_value (GTK_SPIN_BUTTON (sd->via_hole_spin_button),
-			       via_size -
-			       FROM_PCB_UNITS (MIN_PINORVIACOPPER));
+  if (via_hole_size > via_size - MIN_PINORVIACOPPER)
+    gtk_pcb_coord_entry_set_value (GTK_PCB_COORD_ENTRY (sd->via_hole_coord_entry),
+			           via_size - MIN_PINORVIACOPPER);
 }
 
-
-/* static void */
-/* use_temp_cb (GtkWidget * button, gpointer data) */
-/* { */
-/*   gint which = GPOINTER_TO_INT (data); */
-/*   gboolean active; */
-
-/*   active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); */
-/*   if (which == 1 && active) */
-/*     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON */
-/* 				  (route_sizes.set_temp2_button), FALSE); */
-/*   else if (which == 2 && active) */
-/*     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON */
-/* 				  (route_sizes.set_temp1_button), FALSE); */
-/* } */
-
 static void
 use_temp_cb (GtkToggleButton * button, gpointer data)
 {
@@ -218,14 +166,6 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
 
-  s = g_strdup_printf (_("<b>%s</b> grid units are selected"), 
-                       Settings.grid_unit->in_suffix);
-  label = gtk_label_new ("");
-  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-  gtk_label_set_markup (GTK_LABEL (label), s);
-  g_free (s);
-  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 4);
-
   hbox = gtk_hbox_new (FALSE, 4);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
   label = gtk_label_new (_("Route style name"));
@@ -238,32 +178,23 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
 
-  ghid_table_spin_button (table, 0, 0,
-			  &sd->line_width_spin_button,
-			  FROM_PCB_UNITS (rst->Thick),
-			  FROM_PCB_UNITS (MIN_LINESIZE),
-			  FROM_PCB_UNITS (MAX_LINESIZE), STEP0_SIZE,
-			  STEP1_SIZE, SPIN_DIGITS, 0, NULL, sd, TRUE,
+  ghid_table_coord_entry (table, 0, 0, &sd->line_width_coord_entry,
+			  rst->Thick, MIN_LINESIZE, MAX_LINESIZE,
+			  CE_SMALL, 0, NULL, sd, TRUE,
 			  _("Line width"));
-  ghid_table_spin_button (table, 1, 0, &sd->via_hole_spin_button,
-			  FROM_PCB_UNITS (rst->Hole),
-			  FROM_PCB_UNITS (MIN_PINORVIAHOLE),
-			  FROM_PCB_UNITS (MAX_PINORVIASIZE -
-					  MIN_PINORVIACOPPER), STEP0_SIZE,
-			  STEP1_SIZE, SPIN_DIGITS, 0, via_hole_cb, sd, TRUE,
+  ghid_table_coord_entry (table, 1, 0, &sd->via_hole_coord_entry,
+			  rst->Hole, MIN_PINORVIAHOLE,
+			  MAX_PINORVIASIZE - MIN_PINORVIACOPPER,
+			  CE_SMALL, 0, via_hole_cb, sd, TRUE,
 			  _("Via hole"));
-  ghid_table_spin_button (table, 2, 0, &sd->via_size_spin_button,
-			  FROM_PCB_UNITS (rst->Diameter),
-			  FROM_PCB_UNITS (MIN_PINORVIAHOLE +
-					  MIN_PINORVIACOPPER),
-			  FROM_PCB_UNITS (MAX_PINORVIASIZE), STEP0_SIZE,
-			  STEP1_SIZE, SPIN_DIGITS, 0, via_size_cb, sd, TRUE,
+  ghid_table_coord_entry (table, 2, 0, &sd->via_size_coord_entry,
+			  rst->Diameter, MIN_PINORVIAHOLE + MIN_PINORVIACOPPER,
+			  MAX_PINORVIASIZE,
+			  CE_SMALL, 0, via_size_cb, sd, TRUE,
 			  _("Via size"));
-  ghid_table_spin_button (table, 3, 0, &sd->clearance_spin_button,
-			  FROM_PCB_UNITS (rst->Keepaway),
-			  FROM_PCB_UNITS (MIN_LINESIZE),
-			  FROM_PCB_UNITS (MAX_LINESIZE), STEP0_SIZE,
-			  STEP1_SIZE, SPIN_DIGITS, 0, NULL, sd, true,
+  ghid_table_coord_entry (table, 3, 0, &sd->clearance_coord_entry,
+			  rst->Keepaway, MIN_LINESIZE, MAX_LINESIZE,
+			  CE_SMALL, 0, NULL, sd, true,
 			  _("Clearance"));
   gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, FALSE, 0);
 
@@ -311,7 +242,6 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
 
   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
     {
-      gdouble value;
       gchar *string;
       RouteStyleType rst_buf;
 
@@ -330,25 +260,18 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
       if (set_temp1 || set_temp2)
 	rst = &rst_buf;
 
-      value =
-	gtk_spin_button_get_value (GTK_SPIN_BUTTON
-				   (sd->line_width_spin_button));
-      rst->Thick = TO_PCB_UNITS (value);
-
-      value =
-	gtk_spin_button_get_value (GTK_SPIN_BUTTON
-				   (sd->via_hole_spin_button));
-      rst->Hole = TO_PCB_UNITS (value);
-
-      value =
-	gtk_spin_button_get_value (GTK_SPIN_BUTTON
-				   (sd->via_size_spin_button));
-      rst->Diameter = TO_PCB_UNITS (value);
-
-      value =
-	gtk_spin_button_get_value (GTK_SPIN_BUTTON
-				   (sd->clearance_spin_button));
-      rst->Keepaway = TO_PCB_UNITS (value);
+      rst->Thick =
+	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+				        (sd->line_width_coord_entry));
+      rst->Hole =
+	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+				        (sd->via_hole_coord_entry));
+      rst->Diameter =
+	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+				        (sd->via_size_coord_entry));
+      rst->Keepaway =
+	gtk_pcb_coord_entry_get_value (GTK_PCB_COORD_ENTRY
+				        (sd->clearance_coord_entry));
 
       if (index < NUM_STYLES && !set_temp1 && !set_temp2)
 	{
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 5df42af..422b761 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -45,32 +45,32 @@
  * the best scale to use for a group of measures */
 static Unit Units[] = {
   { 0, "km", NULL, 'k', 0.000001, METRIC, ALLOW_KM, 5,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             0.00005, 0.0005, 0.0025, 0.05, 0.25,
              { "" } },
   { 0, "m",  NULL, 'f', 0.001,    METRIC, ALLOW_M,  5,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             0.0005, 0.005, 0.025, 0.5, 2.5,
              { "" } },
   { 0, "cm", NULL, 'e', 0.1,      METRIC, ALLOW_CM, 5,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             0.005, 0.05, 0.25, 5, 25,
              { "" } },
   { 0, "mm", NULL, 'm', 1,        METRIC, ALLOW_MM, 4,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             0.005, 0.05, 0.25, 5, 25,
              { "" } },
   { 0, "um", NULL, 'u', 1000,     METRIC, ALLOW_UM, 2,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             0.005, 0.05, 0.25, 5, 25,
              { "" } },
   { 0, "nm", NULL, 'n', 1000000,  METRIC, ALLOW_NM, 0,
-             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             5, 50, 2500, 5000, 25000,
              { "" } },
 
   { 0, "in",   NULL, 'i', 0.001, IMPERIAL, ALLOW_IN,   5,
-               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               0.1, 1.0, 5.0, 25, 100,
                { "inch" } },
   { 0, "mil",  NULL, 'l', 1,     IMPERIAL, ALLOW_MIL,  2,
-               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               0.1, 1.0, 10, 100, 1000,
                { "" } },
   { 0, "cmil", NULL, 'c', 100,   IMPERIAL, ALLOW_CMIL, 0,
-               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               1, 10, 100, 1000, 10000,
                { "pcb" } }
 };
 #define N_UNITS ((int) (sizeof Units / sizeof Units[0]))
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index f86d4d9..453b6ef 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -108,11 +108,11 @@ struct unit {
   enum e_allow  allow;
   int default_prec;
   /* used for gui spinboxes */
-  Coord step_tiny;
-  Coord step_small;
-  Coord step_medium;
-  Coord step_large;
-  Coord step_huge;
+  double step_tiny;
+  double step_small;
+  double step_medium;
+  double step_large;
+  double step_huge;
   /* aliases -- right now we only need 1 ("inch"->"in"), add as needed */
   const char *alias[1];
 };

commit 32c731f1edb62a6e4ed455084e9900ae94e522f9
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce GtkPcbCoordEntry widget, use it in gui-config.c
    
    The GtkPcbCoordEntry is a modified spinbox that handles
    pcb units internally and outputs them as human units. It
    uses the step sizes given in pcb-printf and adjusts
    automatically when units are changed.
    
    If you manually change the unit suffix, it will change
    its interal unit, so that if you change "10mil" to "10mm"
    it will do the right thing.
    
    TODO: handle overflows
          add a unit selector to the context menu

diff --git a/src/Makefile.am b/src/Makefile.am
index 75c6886..9df4a50 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -270,6 +270,8 @@ libgtk_a_CPPFLAGS = -I./hid/gtk
 LIBGTK_SRCS = \
 	dolists.h \
 	hid/hidint.h \
+	hid/gtk/gtk-pcb-coord-entry.c \
+	hid/gtk/gtk-pcb-coord-entry.h \
 	hid/gtk/gtkhid-main.c \
 	hid/gtk/gtkhid.h \
 	hid/gtk/gui.h \
diff --git a/src/hid/gtk/gtk-pcb-coord-entry.c b/src/hid/gtk/gtk-pcb-coord-entry.c
new file mode 100644
index 0000000..b57438f
--- /dev/null
+++ b/src/hid/gtk/gtk-pcb-coord-entry.c
@@ -0,0 +1,238 @@
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gtkhid.h"
+#include "gui.h"
+#include "pcb-printf.h"
+
+#include "gtk-pcb-coord-entry.h"
+
+enum {
+  UNIT_CHANGE_SIGNAL,
+  LAST_SIGNAL
+};
+
+static guint gtk_pcb_coord_entry_signals[LAST_SIGNAL] = { 0 };
+
+struct _GtkPcbCoordEntry
+{
+  GtkSpinButton parent;
+
+  Coord min_value;
+  Coord max_value;
+  Coord value;
+
+  enum ce_step_size step_size;
+  const Unit *unit;
+};
+
+struct _GtkPcbCoordEntryClass
+{
+  GtkSpinButtonClass parent_class;
+
+  void (* change_unit) (GtkPcbCoordEntry *, const Unit *);
+};
+
+/* SIGNAL HANDLERS */
+static void
+gtk_pcb_coord_entry_popup_cb (GtkPcbCoordEntry *ce, gpointer data)
+{
+  /* TODO: Add unit chooser to menu */
+}
+
+static gboolean
+gtk_pcb_coord_entry_output_cb (GtkPcbCoordEntry *ce, gpointer data)
+{
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+  double value = gtk_adjustment_get_value (adj);
+  gchar *text;
+
+  text = pcb_g_strdup_printf ("%.*f %s", ce->unit->default_prec, value, ce->unit->suffix);
+  gtk_entry_set_text (GTK_ENTRY (ce), text);
+  g_free (text);
+   
+  return TRUE;
+}
+
+static gboolean
+gtk_pcb_coord_text_changed_cb (GtkPcbCoordEntry *entry, gpointer data)
+{
+  const char *text;
+  char *suffix;
+  const Unit *new_unit;
+  double value;
+
+  /* Check if units have changed */
+  text = gtk_entry_get_text (GTK_ENTRY (entry));
+  value = strtod (text, &suffix);
+  new_unit = get_unit_struct (suffix);
+  if (new_unit && new_unit != entry->unit)
+    {
+      entry->value = unit_to_coord (new_unit, value);
+      g_signal_emit (entry, gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL], 0, new_unit);
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gtk_pcb_coord_value_changed_cb (GtkPcbCoordEntry *ce, gpointer data)
+{
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+
+  /* Re-calculate internal value */
+  double value = gtk_adjustment_get_value (adj);
+  ce->value = unit_to_coord (ce->unit, value);
+  /* Handle potential unit changes */
+  gtk_pcb_coord_text_changed_cb (ce, data);
+
+  return FALSE;
+}
+
+static void
+gtk_pcb_coord_entry_change_unit (GtkPcbCoordEntry *ce, const Unit *new_unit)
+{
+  double climb_rate = 0.0;
+  GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (ce));
+
+  ce->unit = new_unit;
+  /* Re-calculate min/max values for spinbox */
+  gtk_adjustment_configure (adj, coord_to_unit (new_unit, ce->value),
+                                 coord_to_unit (new_unit, ce->min_value),
+                                 coord_to_unit (new_unit, ce->max_value),
+                                 coord_to_unit (new_unit, ce->unit->step_small),
+                                 coord_to_unit (new_unit, ce->unit->step_medium),
+                                 0.0);
+
+  switch (ce->step_size)
+    {
+    case CE_TINY: climb_rate = new_unit->step_tiny; break;
+    case CE_SMALL: climb_rate = new_unit->step_small; break;
+    case CE_MEDIUM: climb_rate = new_unit->step_medium; break;
+    case CE_LARGE: climb_rate = new_unit->step_large; break;
+    }
+  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj,
+                             coord_to_unit (new_unit, climb_rate),
+                             new_unit->default_prec + strlen (new_unit->suffix));
+}
+
+/* CONSTRUCTOR */
+static void
+gtk_pcb_coord_entry_init (GtkPcbCoordEntry *ce)
+{
+  /* Hookup signal handlers */
+  g_signal_connect (G_OBJECT (ce), "focus_out_event",
+                    G_CALLBACK (gtk_pcb_coord_text_changed_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "value_changed",
+                    G_CALLBACK (gtk_pcb_coord_value_changed_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "populate_popup",
+                    G_CALLBACK (gtk_pcb_coord_entry_popup_cb), NULL);
+  g_signal_connect (G_OBJECT (ce), "output",
+                    G_CALLBACK (gtk_pcb_coord_entry_output_cb), NULL);
+}
+
+static void
+gtk_pcb_coord_entry_class_init (GtkPcbCoordEntryClass *klass)
+{
+  klass->change_unit = gtk_pcb_coord_entry_change_unit;
+
+  /* GtkAutoComplete *ce : the object acted on */
+  /* const Unit *new_unit: the new unit that was set */
+  gtk_pcb_coord_entry_signals[UNIT_CHANGE_SIGNAL] =
+    g_signal_new ("change-unit",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GtkPcbCoordEntryClass, change_unit),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE,
+                  1, G_TYPE_POINTER);
+
+}
+
+/* PUBLIC FUNCTIONS */
+GType
+gtk_pcb_coord_entry_get_type (void)
+{
+  static GType ce_type = 0;
+
+  if (!ce_type)
+    {
+      const GTypeInfo ce_info =
+      {
+	sizeof (GtkPcbCoordEntryClass),
+	NULL, /* base_init */
+	NULL, /* base_finalize */
+	(GClassInitFunc) gtk_pcb_coord_entry_class_init,
+	NULL, /* class_finalize */
+	NULL, /* class_data */
+	sizeof (GtkPcbCoordEntry),
+	0,    /* n_preallocs */
+	(GInstanceInitFunc) gtk_pcb_coord_entry_init,
+      };
+
+      ce_type = g_type_register_static (GTK_TYPE_SPIN_BUTTON,
+                                        "GtkPcbCoordEntry",
+                                        &ce_info,
+                                        0);
+    }
+
+  return ce_type;
+}
+
+GtkWidget *
+gtk_pcb_coord_entry_new (Coord min_val, Coord max_val, Coord value,
+                         const Unit *unit, enum ce_step_size step_size)
+{
+  /* Setup spinbox min/max values */
+  double small_step, big_step;
+  GtkAdjustment *adj;
+  GtkPcbCoordEntry *ce = g_object_new (GTK_PCB_COORD_ENTRY_TYPE, NULL);
+
+  ce->unit = unit;
+  ce->min_value = min_val;
+  ce->max_value = max_val;
+  ce->value = value;
+
+  ce->step_size = step_size;
+  switch (step_size)
+    {
+    case CE_TINY:
+      small_step = coord_to_unit (unit, unit->step_tiny);
+      big_step   = coord_to_unit (unit, unit->step_small);
+      break;
+    case CE_SMALL:
+      small_step = coord_to_unit (unit, unit->step_small);
+      big_step   = coord_to_unit (unit, unit->step_medium);
+      break;
+    case CE_MEDIUM:
+      small_step = coord_to_unit (unit, unit->step_medium);
+      big_step   = coord_to_unit (unit, unit->step_large);
+      break;
+    case CE_LARGE:
+      small_step = coord_to_unit (unit, unit->step_large);
+      big_step   = coord_to_unit (unit, unit->step_huge);
+      break;
+    default:
+      small_step = big_step = 0;
+      break;
+    }
+
+  adj = GTK_ADJUSTMENT (gtk_adjustment_new (coord_to_unit (unit, value),
+                                            coord_to_unit (unit, min_val),
+                                            coord_to_unit (unit, max_val),
+                                            small_step, big_step, 0.0));
+  gtk_spin_button_configure (GTK_SPIN_BUTTON (ce), adj, small_step,
+                             unit->default_prec + strlen (unit->suffix));
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (ce), FALSE);
+
+  return GTK_WIDGET (ce);
+}
+
+Coord
+gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce)
+{
+  return ce->value;
+}
+
diff --git a/src/hid/gtk/gtk-pcb-coord-entry.h b/src/hid/gtk/gtk-pcb-coord-entry.h
new file mode 100644
index 0000000..e97f391
--- /dev/null
+++ b/src/hid/gtk/gtk-pcb-coord-entry.h
@@ -0,0 +1,34 @@
+/* This is the modified GtkSpinbox used for entering Coords.
+ * Hopefully it can be used as a template whenever we migrate the
+ * rest of the Gtk HID to use GObjects and GtkWidget subclassing.
+ */
+#ifndef GTK_PCB_COORD_ENTRY_H__
+#define GTK_PCB_COORD_ENTRY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS  /* keep c++ happy */
+
+#define GTK_PCB_COORD_ENTRY_TYPE            (gtk_pcb_coord_entry_get_type ())
+#define GTK_PCB_COORD_ENTRY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_PCB_COORD_ENTRY_TYPE, GtkPcbCoordEntry))
+#define GTK_PCB_COORD_ENTRY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_PCB_COORD_ENTRY_TYPE, GtkPcbCoordEntryClass))
+#define IS_GTK_PCB_COORD_ENTRY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_PCB_COORD_ENTRY_TYPE))
+#define IS_GTK_PCB_COORD_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_PCB_COORD_ENTRY_TYPE))
+
+typedef struct _GtkPcbCoordEntry       GtkPcbCoordEntry;
+typedef struct _GtkPcbCoordEntryClass  GtkPcbCoordEntryClass;
+
+/* Step sizes */
+enum ce_step_size { CE_TINY, CE_SMALL, CE_MEDIUM, CE_LARGE };
+
+GType gtk_pcb_coord_entry_get_type (void);
+GtkWidget* gtk_pcb_coord_entry_new (Coord min_val, Coord max_val, Coord value,
+                                    const Unit *unit, enum ce_step_size step_size);
+void gtk_pcb_coord_entry_add_entry (GtkPcbCoordEntry *ce, const gchar *name, const gchar *desc);
+gchar *gtk_pcb_coord_entry_get_last_command (GtkPcbCoordEntry *ce);
+
+Coord gtk_pcb_coord_entry_get_value (GtkPcbCoordEntry *ce);
+
+G_END_DECLS  /* keep c++ happy */
+#endif
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index e4127cb..54d294b 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -968,7 +968,7 @@ static GtkWidget *config_sizes_vbox,
 static GtkWidget *use_board_size_default_button,
   *use_drc_sizes_default_button;
 
-static gint new_board_width, new_board_height;
+static Coord new_board_width, new_board_height;
 
 static void
 config_sizes_apply (void)
@@ -1012,22 +1012,17 @@ text_spin_button_cb (GtkSpinButton * spin, void * dst)
   ghid_set_status_line_label ();
 }
 
-
 static void
-size_spin_button_cb (GtkSpinButton * spin, void * dst)
+coord_entry_cb (GtkPcbCoordEntry * ce, void * dst)
 {
-  gdouble value;
-
-  value = gtk_spin_button_get_value (spin);
-  *(gint *)dst = TO_PCB_UNITS (value);
+  *(Coord *) dst = gtk_pcb_coord_entry_get_value (ce);
   ghidgui->config_modified = TRUE;
 }
 
 static void
 config_sizes_tab_create (GtkWidget * tab_vbox)
 {
-  GtkWidget *table, *vbox, *hbox, *label;
-  gchar *str;
+  GtkWidget *table, *vbox, *hbox;
 
   /* Need a vbox we can destroy if user changes grid units.
    */
@@ -1040,16 +1035,6 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
       config_sizes_tab_vbox = tab_vbox;
     }
 
-  str = g_strdup_printf (_("<b>%s</b> grid units are selected"),
-                         Settings.grid_unit->in_suffix);
-  label = gtk_label_new ("");
-  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-  gtk_label_set_markup (GTK_LABEL (label), str);
-  g_free (str);
-
-  gtk_box_pack_start (GTK_BOX (config_sizes_vbox), label, FALSE, FALSE, 4);
-
-
   /* ---- Board Size ---- */
   vbox = ghid_category_vbox (config_sizes_vbox, _("Board Size"),
 			     4, 2, TRUE, TRUE);
@@ -1062,18 +1047,14 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
 
   new_board_width = PCB->MaxWidth;
   new_board_height = PCB->MaxHeight;
-  ghid_table_spin_button (table, 0, 0, NULL,
-			  FROM_PCB_UNITS (PCB->MaxWidth),
-			  FROM_PCB_UNITS (MIN_SIZE),
-			  FROM_PCB_UNITS (MAX_COORD), STEP0_SIZE, STEP1_SIZE,
-			  SPIN_DIGITS, 0, size_spin_button_cb,
+  ghid_table_coord_entry (table, 0, 0, NULL,
+			  PCB->MaxWidth, MIN_SIZE, MAX_COORD,
+			  CE_LARGE, 0, coord_entry_cb,
 			  &new_board_width, FALSE, _("Width"));
 
-  ghid_table_spin_button (table, 1, 0, NULL,
-			  FROM_PCB_UNITS (PCB->MaxHeight),
-			  FROM_PCB_UNITS (MIN_SIZE),
-			  FROM_PCB_UNITS (MAX_COORD), STEP0_SIZE, STEP1_SIZE,
-			  SPIN_DIGITS, 0, size_spin_button_cb,
+  ghid_table_coord_entry (table, 1, 0, NULL,
+			  PCB->MaxHeight, MIN_SIZE, MAX_COORD,
+			  CE_LARGE, 0, coord_entry_cb,
 			  &new_board_height, FALSE, _("Height"));
   ghid_check_button_connected (vbox, &use_board_size_default_button, FALSE,
 			       TRUE, FALSE, FALSE, 0, NULL, NULL,
@@ -1107,52 +1088,40 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
 
-  ghid_table_spin_button (table, 0, 0, NULL,
-			  FROM_PCB_UNITS (PCB->Bloat),
-			  FROM_PCB_UNITS (MIN_DRC_VALUE),
-			  FROM_PCB_UNITS (MAX_DRC_VALUE), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->Bloat, FALSE,
+  ghid_table_coord_entry (table, 0, 0, NULL,
+			  PCB->Bloat, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->Bloat, FALSE,
 			  _("Minimum copper spacing"));
 
-  ghid_table_spin_button (table, 1, 0, NULL,
-			  FROM_PCB_UNITS (PCB->minWid),
-			  FROM_PCB_UNITS (MIN_DRC_VALUE),
-			  FROM_PCB_UNITS (MAX_DRC_VALUE), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->minWid, FALSE,
+  ghid_table_coord_entry (table, 1, 0, NULL,
+			  PCB->minWid, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->minWid, FALSE,
 			  _("Minimum copper width"));
 
-  ghid_table_spin_button (table, 2, 0, NULL,
-			  FROM_PCB_UNITS (PCB->Shrink),
-			  FROM_PCB_UNITS (MIN_DRC_VALUE),
-			  FROM_PCB_UNITS (MAX_DRC_VALUE), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->Shrink, FALSE,
+  ghid_table_coord_entry (table, 2, 0, NULL,
+			  PCB->Shrink, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->Shrink, FALSE,
 			  _("Minimum touching copper overlap"));
 
-  ghid_table_spin_button (table, 3, 0, NULL,
-			  FROM_PCB_UNITS (PCB->minSlk),
-			  FROM_PCB_UNITS (MIN_DRC_SILK),
-			  FROM_PCB_UNITS (MAX_DRC_SILK), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->minSlk, FALSE,
+  ghid_table_coord_entry (table, 3, 0, NULL,
+			  PCB->minSlk, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->minSlk, FALSE,
 			  _("Minimum silk width"));
 
-  ghid_table_spin_button (table, 4, 0, NULL,
-			  FROM_PCB_UNITS (PCB->minDrill),
-			  FROM_PCB_UNITS (MIN_DRC_DRILL),
-			  FROM_PCB_UNITS (MAX_DRC_DRILL), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->minDrill, FALSE,
+  ghid_table_coord_entry (table, 4, 0, NULL,
+			  PCB->minDrill, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->minDrill, FALSE,
 			  _("Minimum drill diameter"));
 
-  ghid_table_spin_button (table, 5, 0, NULL,
-			  FROM_PCB_UNITS (PCB->minRing),
-			  FROM_PCB_UNITS (MIN_DRC_RING),
-			  FROM_PCB_UNITS (MAX_DRC_RING), STEP0_SMALL_SIZE,
-			  STEP1_SMALL_SIZE, SPIN_DIGITS, 0,
-			  size_spin_button_cb, &PCB->minRing, FALSE,
+  ghid_table_coord_entry (table, 5, 0, NULL,
+			  PCB->minRing, MIN_DRC_VALUE, MAX_DRC_VALUE,
+			  CE_SMALL, 0, coord_entry_cb,
+			  &PCB->minRing, FALSE,
 			  _("Minimum annular ring"));
 
   ghid_check_button_connected (vbox, &use_drc_sizes_default_button, FALSE,
@@ -1172,23 +1141,17 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
 static GtkWidget *config_increments_vbox, *config_increments_tab_vbox;
 
 static void
-increment_spin_button_cb (GtkSpinButton * spin, void * dst)
+increment_spin_button_cb (GtkPcbCoordEntry * ce, void * dst)
 {
-  gdouble value;
-
-  value = gtk_spin_button_get_value (spin);
-  *(Coord *)dst = TO_PCB_UNITS (value);
-
-
+  *(Coord *)dst = gtk_pcb_coord_entry_get_value (ce);
   ghidgui->config_modified = TRUE;
 }
 
 static void
 config_increments_tab_create (GtkWidget * tab_vbox)
 {
-  GtkWidget *vbox, *label;
+  GtkWidget *vbox;
   Coord *target;
-  gchar *str;
 
   /* Need a vbox we can destroy if user changes grid units.
    */
@@ -1201,28 +1164,16 @@ config_increments_tab_create (GtkWidget * tab_vbox)
       config_increments_tab_vbox = tab_vbox;
     }
 
-  str = g_strdup_printf (_("Increment/Decrement values to use for <b>%s</b>"),
-                         Settings.grid_unit->in_suffix);
-  label = gtk_label_new ("");
-  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-  gtk_label_set_markup (GTK_LABEL (label), str);
-  gtk_box_pack_start (GTK_BOX (config_increments_vbox), label,
-		      FALSE, FALSE, 4);
-  g_free (str);
-
-
   /* ---- Grid Increment/Decrement ---- */
   vbox = ghid_category_vbox (config_increments_vbox,
 			     _("Grid Increment/Decrement"), 4, 2, TRUE, TRUE);
 
   target = &Settings.increments->grid;
-  ghid_spin_button (vbox, NULL,
-                    FROM_PCB_UNITS (Settings.increments->grid),
-                    FROM_PCB_UNITS (Settings.increments->grid_min),
-                    FROM_PCB_UNITS (Settings.increments->grid_max),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_medium),
-		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
+  ghid_coord_entry (vbox, NULL,
+                    Settings.increments->grid,
+                    Settings.increments->grid_min,
+                    Settings.increments->grid_max,
+                    CE_SMALL, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 'g' and '<shift>g' grid change actions"));
 
@@ -1231,18 +1182,12 @@ config_increments_tab_create (GtkWidget * tab_vbox)
   vbox = ghid_category_vbox (config_increments_vbox,
 			     _("Size Increment/Decrement"), 4, 2, TRUE, TRUE);
 
-  /* Size increment spin button ('s' and '<shift>s').  For mil
-     |  units, range from 1.0 to 10.0.  For mm, range from 0.01 to 0.5
-     |  Step sizes of 1 mil or .01 mm, and .01 mm precision or 1 mil precision.
-   */
   target = &Settings.increments->size;
-  ghid_spin_button (vbox, NULL,
-                    FROM_PCB_UNITS (Settings.increments->size),
-                    FROM_PCB_UNITS (Settings.increments->size_min),
-                    FROM_PCB_UNITS (Settings.increments->size_max),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
-		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
+  ghid_coord_entry (vbox, NULL,
+                    Settings.increments->size,
+                    Settings.increments->size_min,
+                    Settings.increments->size_max,
+                    CE_SMALL, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 's' and '<shift>s' size change actions on lines,\n"
 		      "pads, pins and text.\n"
@@ -1252,45 +1197,29 @@ config_increments_tab_create (GtkWidget * tab_vbox)
   vbox = ghid_category_vbox (config_increments_vbox,
 			     _("Line Increment/Decrement"), 4, 2, TRUE, TRUE);
 
-  /* Line increment spin button ('l' and '<shift>l').  For mil
-     |  units, range from 0.5 to 10.0.  For mm, range from 0.005 to 0.5
-     |  Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
-     |  precision.
-   */
   target = &Settings.increments->line;
-  ghid_spin_button (vbox, NULL,
-                    FROM_PCB_UNITS (Settings.increments->line),
-                    FROM_PCB_UNITS (Settings.increments->line_min),
-                    FROM_PCB_UNITS (Settings.increments->line_max),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
-		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
+  ghid_coord_entry (vbox, NULL,
+                    Settings.increments->line,
+                    Settings.increments->line_min,
+                    Settings.increments->line_max,
+                    CE_SMALL, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 'l' and '<shift>l' routing line width change actions"));
 
   /* ---- Clear Increment/Decrement ---- */
   vbox = ghid_category_vbox (config_increments_vbox,
-			     _("Clear Increment/Decrement"), 4, 2, TRUE,
-			     TRUE);
+			     _("Clear Increment/Decrement"), 4, 2, TRUE, TRUE);
 
-  /* Clear increment spin button ('l' and '<shift>l').  For mil
-     |  units, range from 0.5 to 10.0.  For mm, range from 0.005 to 0.5
-     |  Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
-     |  precision.
-   */
   target = &Settings.increments->clear;
-  ghid_spin_button (vbox, NULL,
-                    FROM_PCB_UNITS (Settings.increments->clear),
-                    FROM_PCB_UNITS (Settings.increments->clear_min),
-                    FROM_PCB_UNITS (Settings.increments->clear_max),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
-                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
-		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
+  ghid_coord_entry (vbox, NULL,
+                    Settings.increments->clear,
+                    Settings.increments->clear_min,
+                    Settings.increments->clear_max,
+                    CE_SMALL, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 'k' and '<shift>k' line clearance inside polygon size\n"
 		     "change actions"));
 
-
   gtk_widget_show_all (config_increments_vbox);
 }
 
diff --git a/src/hid/gtk/gui-utils.c b/src/hid/gtk/gui-utils.c
index d6e42d2..a36057b 100644
--- a/src/hid/gtk/gui-utils.c
+++ b/src/hid/gtk/gui-utils.c
@@ -33,6 +33,7 @@
 #endif
 
 #include "gui.h"
+#include "gtk-pcb-coord-entry.h"
 #include <gdk/gdkkeysyms.h>
 
 #ifdef HAVE_LIBDMALLOC
@@ -270,6 +271,51 @@ ghid_button_connected (GtkWidget * box, GtkWidget ** button,
 }
 
 void
+ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value,
+		  Coord low, Coord high,  enum ce_step_size step_size,
+		  gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+		  gpointer data, gboolean right_align, gchar * string)
+{
+  GtkWidget *hbox = NULL, *label, *entry_widget;
+  GtkPcbCoordEntry *entry;
+
+  if (string && box)
+    {
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 2);
+      box = hbox;
+    }
+
+  entry_widget = gtk_pcb_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
+  if (coord_entry)
+    *coord_entry = entry_widget;
+  if (width > 0)
+    gtk_widget_set_size_request (entry_widget, width, -1);
+  entry = GTK_PCB_COORD_ENTRY (entry_widget);
+  if (data == NULL)
+    data = (gpointer) entry;
+  if (cb_func)
+    g_signal_connect (G_OBJECT (entry_widget), "value_changed",
+		      G_CALLBACK (cb_func), data);
+  if (box)
+    {
+      if (right_align && string)
+	{
+	  label = gtk_label_new (string);
+	  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+	  gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2);
+	}
+      gtk_box_pack_start (GTK_BOX (box), entry_widget, FALSE, FALSE, 2);
+      if (!right_align && string)
+	{
+	  label = gtk_label_new (string);
+	  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+	  gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2);
+	}
+    }
+}
+
+void
 ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button, gfloat value,
 		  gfloat low, gfloat high, gfloat step0, gfloat step1,
 		  gint digits, gint width,
@@ -319,6 +365,58 @@ ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button, gfloat value,
 }
 
 void
+ghid_table_coord_entry (GtkWidget * table, gint row, gint column,
+			GtkWidget ** coord_entry, Coord value,
+			Coord low, Coord high, enum ce_step_size step_size,
+			gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+			gpointer data, gboolean right_align, gchar * string)
+{
+  GtkWidget *label, *entry_widget;
+  GtkPcbCoordEntry *entry;
+
+  if (!table)
+    return;
+
+  entry_widget = gtk_pcb_coord_entry_new (low, high, value, Settings.grid_unit, step_size);
+  if (coord_entry)
+    *coord_entry = entry_widget;
+  if (width > 0)
+    gtk_widget_set_size_request (entry_widget, width, -1);
+  entry = GTK_PCB_COORD_ENTRY (entry_widget);
+  if (data == NULL)
+    data = (gpointer) entry;
+  if (cb_func)
+    g_signal_connect (G_OBJECT (entry), "value_changed",
+		      G_CALLBACK (cb_func), data);
+
+  if (right_align)
+    {
+      gtk_table_attach_defaults (GTK_TABLE (table), entry_widget,
+				 column + 1, column + 2, row, row + 1);
+      if (string)
+	{
+	  label = gtk_label_new (string);
+	  gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+	  gtk_table_attach_defaults (GTK_TABLE (table), label,
+				     column, column + 1, row, row + 1);
+	}
+    }
+  else
+    {
+      gtk_table_attach_defaults (GTK_TABLE (table), entry_widget,
+				 column, column + 1, row, row + 1);
+      if (string)
+	{
+	  label = gtk_label_new (string);
+	  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	  gtk_table_attach_defaults (GTK_TABLE (table), label,
+				     column + 1, column + 2, row, row + 1);
+	}
+    }
+}
+
+
+void
 ghid_table_spin_button (GtkWidget * table, gint row, gint column,
 			GtkWidget ** spin_button, gfloat value,
 			gfloat low, gfloat high, gfloat step0, gfloat step1,
@@ -334,8 +432,9 @@ ghid_table_spin_button (GtkWidget * table, gint row, gint column,
     return;
 
   adj = (GtkAdjustment *) gtk_adjustment_new (value,
-					      low, high, step0, step1, 0.0);
+                                             low, high, step0, step1, 0.0);
   spin_but = gtk_spin_button_new (adj, 0.5, digits);
+
   if (spin_button)
     *spin_button = spin_but;
   if (width > 0)
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 807afce..752c184 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 
 #include <gtk/gtk.h>
+#include "gtk-pcb-coord-entry.h"
 #include "gui-pinout-preview.h"
 
 
@@ -366,11 +367,20 @@ void ghid_button_connected (GtkWidget * box, GtkWidget ** button,
 			    gboolean pack_start, gboolean expand,
 			    gboolean fill, gint pad, void (*cb_func) (gpointer),
 			    gpointer data, gchar * string);
+void ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value,
+		       Coord low, Coord high,  enum ce_step_size step_size,
+		       gint width, void (*cb_func) (GtkPcbCoordEntry *, gpointer),
+		       gpointer data, gboolean right_align, gchar * string);
 void ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button,
 		       gfloat value, gfloat low, gfloat high, gfloat step0,
 		       gfloat step1, gint digits, gint width,
 		       void (*cb_func) (GtkSpinButton *, gpointer), gpointer data,
 		       gboolean right_align, gchar * string);
+void ghid_table_coord_entry (GtkWidget * table, gint row, gint column,
+		 	    GtkWidget ** coord_entry, Coord value,
+			    Coord low, Coord high, enum ce_step_size, gint width,
+			    void (*cb_func) (GtkPcbCoordEntry *, gpointer), gpointer data,
+			    gboolean right_align, gchar * string);
 void ghid_table_spin_button (GtkWidget * box, gint row, gint column,
 			     GtkWidget ** spin_button, gfloat value,
 			     gfloat low, gfloat high, gfloat step0,

commit 6d7ab8297a73fd8ccc01e7e81ba82e2b49ae598c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit hidgl stuff, implement Coord
    
    I did not touch any code, only change 'int' to Coord where
    appropriate (and in a couple cases 'double' to Coord), under
    the assumption that any real changes should be done by Peter
    C.

diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
index 2ba295e..6bd48c3 100644
--- a/src/hid/common/hidgl.c
+++ b/src/hid/common/hidgl.c
@@ -110,7 +110,7 @@ hidgl_draw_grid (BoxType *drawn_area)
 {
   static GLfloat *points = 0;
   static int npoints = 0;
-  int x1, y1, x2, y2, n, i;
+  Coord x1, y1, x2, y2, n, i;
   double x, y;
 
   if (!Settings.DrawGrid)
@@ -123,14 +123,14 @@ hidgl_draw_grid (BoxType *drawn_area)
 
   if (x1 > x2)
     {
-      int tmp = x1;
+      Coord tmp = x1;
       x1 = x2;
       x2 = tmp;
     }
 
   if (y1 > y2)
     {
-      int tmp = y1;
+      Coord tmp = y1;
       y1 = y2;
       y2 = tmp;
     }
@@ -177,7 +177,7 @@ int calc_slices (float pix_radius, float sweep_angle)
 
 #define MIN_TRIANGLES_PER_CAP 3
 #define MAX_TRIANGLES_PER_CAP 90
-static void draw_cap (double width, int x, int y, double angle, double scale)
+static void draw_cap (Coord width, Coord x, Coord y, Angle angle, double scale)
 {
   float last_capx, last_capy;
   float capx, capy;
@@ -205,7 +205,7 @@ static void draw_cap (double width, int x, int y, double angle, double scale)
 }
 
 void
-hidgl_draw_line (int cap, double width, int x1, int y1, int x2, int y2, double scale)
+hidgl_draw_line (int cap, Coord width, Coord x1, Coord y1, Coord x2, Coord y2, double scale)
 {
   double angle;
   float deltax, deltay, length;
@@ -279,8 +279,8 @@ hidgl_draw_line (int cap, double width, int x1, int y1, int x2, int y2, double s
 #define MIN_SLICES_PER_ARC 6
 #define MAX_SLICES_PER_ARC 360
 void
-hidgl_draw_arc (double width, int x, int y, int rx, int ry,
-                int start_angle, int delta_angle, double scale)
+hidgl_draw_arc (Coord width, Coord x, Coord y, Coord rx, Coord ry,
+                Angle start_angle, Angle delta_angle, double scale)
 {
   float last_inner_x, last_inner_y;
   float last_outer_x, last_outer_y;
@@ -357,7 +357,7 @@ hidgl_draw_arc (double width, int x, int y, int rx, int ry,
 }
 
 void
-hidgl_draw_rect (int x1, int y1, int x2, int y2)
+hidgl_draw_rect (Coord x1, Coord y1, Coord x2, Coord y2)
 {
   glBegin (GL_LINE_LOOP);
   glVertex3f (x1, y1, global_depth);
@@ -369,7 +369,7 @@ hidgl_draw_rect (int x1, int y1, int x2, int y2)
 
 
 void
-hidgl_fill_circle (int vx, int vy, int vr, double scale)
+hidgl_fill_circle (Coord vx, Coord vy, Coord vr, double scale)
 {
 #define MIN_TRIANGLES_PER_CIRCLE 6
 #define MAX_TRIANGLES_PER_CIRCLE 360
@@ -518,7 +518,7 @@ myVertex (GLdouble *vertex_data)
 }
 
 void
-hidgl_fill_polygon (int n_coords, int *x, int *y)
+hidgl_fill_polygon (int n_coords, Coord *x, Coord *y)
 {
   int i;
   GLUtesselator *tobj;
@@ -693,7 +693,7 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
 }
 
 void
-hidgl_fill_rect (int x1, int y1, int x2, int y2)
+hidgl_fill_rect (Coord x1, Coord y1, Coord x2, Coord y2)
 {
   hidgl_ensure_triangle_space (&buffer, 2);
   hidgl_add_triangle (&buffer, x1, y1, x1, y2, x2, y2);
diff --git a/src/hid/common/hidgl.h b/src/hid/common/hidgl.h
index 3af338d..858270a 100644
--- a/src/hid/common/hidgl.h
+++ b/src/hid/common/hidgl.h
@@ -68,13 +68,13 @@ hidgl_add_triangle (triangle_buffer *buffer,
 
 void hidgl_draw_grid (BoxType *drawn_area);
 void hidgl_set_depth (float depth);
-void hidgl_draw_line (int cap, double width, int x1, int y1, int x2, int y2, double scale);
-void hidgl_draw_arc (double width, int vx, int vy, int vrx, int vry, int start_angle, int delta_angle, double scale);
-void hidgl_draw_rect (int x1, int y1, int x2, int y2);
-void hidgl_fill_circle (int vx, int vy, int vr, double scale);
-void hidgl_fill_polygon (int n_coords, int *x, int *y);
+void hidgl_draw_line (int cap, Coord width, Coord x1, Coord y1, Coord x2, Coord y2, double scale);
+void hidgl_draw_arc (Coord width, Coord vx, Coord vy, Coord vrx, Coord vry, Angle start_angle, Angle delta_angle, double scale);
+void hidgl_draw_rect (Coord x1, Coord y1, Coord x2, Coord y2);
+void hidgl_fill_circle (Coord vx, Coord vy, Coord vr, double scale);
+void hidgl_fill_polygon (int n_coords, Coord *x, Coord *y);
 void hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale);
-void hidgl_fill_rect (int x1, int y1, int x2, int y2);
+void hidgl_fill_rect (Coord x1, Coord y1, Coord x2, Coord y2);
 
 void hidgl_init (void);
 int hidgl_stencil_bits (void);
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 71ab0fa..95ab93d 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -482,7 +482,7 @@ ghid_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 void
-ghid_set_line_width (hidGC gc, int width)
+ghid_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -504,7 +504,7 @@ ghid_set_draw_faded (hidGC gc, int faded)
 }
 
 void
-ghid_set_line_cap_angle (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_set_line_cap_angle (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   printf ("ghid_set_line_cap_angle() -- not implemented\n");
 }

commit fa2a0e35a644646b400cba4c075710c0f0742771
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce HID_Coord type and related changes
    
    Give measure-specific HID options their own datatype,
    so that things like the --grid option can support suffixes
    instead of exposing the base unit. (In fact, since they
    use GetValue, they will keep right on pretending the base
    unit is cmil.)
    
    This gives us the opportunity to write measure-entry GUI
    widgets that will handle units correctly and whatnot, though
    I have not yet done this.
    
    Fixes-bug: lp-699640
    Fixes-bug: lp-699641

diff --git a/src/hid.h b/src/hid.h
index 505b4f2..b1f532f 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -159,12 +159,13 @@ extern "C"
     int int_value;
     const char *str_value;
     double real_value;
+    Coord coord_value;
   } HID_Attr_Val;
 
   enum hids
     { HID_Label, HID_Integer, HID_Real, HID_String,
       HID_Boolean, HID_Enum, HID_Mixed, HID_Path,
-      HID_Unit
+      HID_Unit, HID_Coord
     };
 
   typedef struct
diff --git a/src/hid/common/hidinit.c b/src/hid/common/hidinit.c
index 120dffd..0bdd395 100644
--- a/src/hid/common/hidinit.c
+++ b/src/hid/common/hidinit.c
@@ -263,6 +263,10 @@ hid_parse_command_line (int *argc, char ***argv)
 	    if (a->value)
 	      *(int *) a->value = a->default_val.int_value;
 	    break;
+	  case HID_Coord:
+	    if (a->value)
+	      *(Coord *) a->value = a->default_val.coord_value;
+	    break;
 	  case HID_Boolean:
 	    if (a->value)
 	      *(char *) a->value = a->default_val.int_value;
@@ -320,6 +324,14 @@ hid_parse_command_line (int *argc, char ***argv)
 		  (*argc)--;
 		  (*argv)++;
 		  break;
+		case HID_Coord:
+		  if (a->value)
+		    *(Coord *) a->value = GetValue ((*argv)[1], NULL, NULL);
+		  else
+		    a->default_val.coord_value = GetValue ((*argv)[1], NULL, NULL);
+		  (*argc)--;
+		  (*argv)++;
+		  break;
 		case HID_Real:
 		  if (a->value)
 		    *(double *) a->value = strtod ((*argv)[1], 0);
@@ -475,6 +487,11 @@ hid_save_settings (int locally)
 		       a->name,
 		       a->value ? *(int *)a->value : a->default_val.int_value);
 	      break;
+	    case HID_Coord:
+	      pcb_fprintf (f, "%s = %$mS\n",
+		           a->name,
+		           a->value ? *(Coord *)a->value : a->default_val.coord_value);
+	      break;
 	    case HID_Boolean:
 	      fprintf (f, "%s = %d\n",
 		       a->name,
@@ -537,6 +554,9 @@ hid_set_attribute (char *name, char *value)
 	    case HID_Integer:
 	      a->default_val.int_value = strtol (value, 0, 0);
 	      break;
+	    case HID_Coord:
+	      a->default_val.coord_value = GetValue (value, NULL, NULL);
+	      break;
 	    case HID_Real:
 	      a->default_val.real_value = strtod (value, 0);
 	      break;
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 1b1e93e..e4127cb 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -65,6 +65,7 @@ enum ConfigType
 {
   CONFIG_Boolean,
   CONFIG_Integer,
+  CONFIG_Coord,
   CONFIG_Real,
   CONFIG_String,
   CONFIG_Unused
@@ -280,6 +281,10 @@ ghid_config_init (void)
 	      *(int *) a->value = a->default_val.int_value;
 	      ca->type = CONFIG_Integer;
 	      break;
+	    case HID_Coord:
+	      *(Coord *) a->value = a->default_val.coord_value;
+	      ca->type = CONFIG_Coord;
+	      break;
 	    case HID_Real:
 	      *(double *) a->value = a->default_val.real_value;
 	      ca->type = CONFIG_Real;
@@ -560,6 +565,14 @@ parse_optionv (gint * argc, gchar *** argv, gboolean from_cmd_line)
 		  (*argc)--;
 		  (*argv)++;
 		  break;
+		case HID_Coord:
+		  if (a->value)
+		    *(Coord *) a->value = GetValue ((*argv)[1], 0, 0);
+		  else
+		    a->default_val.coord_value = GetValue ((*argv)[1], 0, 0);
+		  (*argc)--;
+		  (*argv)++;
+                  break;
 		case HID_Real:
 		  if (a->value)
 		    *(double *) a->value = strtod ((*argv)[1], 0);
diff --git a/src/hid/gtk/gui-dialog-print.c b/src/hid/gtk/gui-dialog-print.c
index ee8b282..16fa132 100644
--- a/src/hid/gtk/gui-dialog-print.c
+++ b/src/hid/gtk/gui-dialog-print.c
@@ -63,6 +63,13 @@ intspinner_changed_cb (GtkSpinButton * spin_button, gpointer data)
 }
 
 static void
+coordentry_changed_cb (GtkEntry * entry, Coord * res)
+{
+  const gchar *s = gtk_entry_get_text (entry);
+  *res = GetValue (s, NULL, NULL);
+}
+
+static void
 dblspinner_changed_cb (GtkSpinButton * spin_button, gpointer data)
 {
   double *dval = (double *)data;
@@ -163,6 +170,25 @@ ghid_attribute_dialog (HID_Attribute * attrs,
 	  gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
 	  break;
 
+	case HID_Coord:
+	  hbox = gtk_hbox_new (FALSE, 4);
+	  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+	  /* FIXME: need to write a coord-entry widget for this */
+	  entry = gtk_entry_new ();
+	  gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+	  if(attrs[j].default_val.str_value != NULL)
+	    gtk_entry_set_text (GTK_ENTRY (entry),
+				attrs[j].default_val.str_value);
+	  gtk_tooltips_set_tip (tips, entry, attrs[j].help_text, NULL);
+	  g_signal_connect (G_OBJECT (entry), "changed",
+			    G_CALLBACK (coordentry_changed_cb),
+			    &(attrs[j].default_val.coord_value));
+
+	  widget = gtk_label_new (attrs[j].name);
+	  gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+	  break;
+
 	case HID_Real:
 	  hbox = gtk_hbox_new (FALSE, 4);
 	  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index b7e6c16..75e4a20 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -749,6 +749,13 @@ lesstif_attribute_dialog (HID_Attribute * attrs,
 	  stdarg (XmNvalue, buf);
 	  wl[i] = XmCreateTextField (form, attrs[i].name, args, n);
 	  break;
+	case HID_Coord:
+	  stdarg (XmNcolumns, 13);
+	  stdarg (XmNresizeWidth, True);
+	  pcb_sprintf (buf, "%$mS", results[i].coord_value);
+	  stdarg (XmNvalue, buf);
+	  wl[i] = XmCreateTextField (form, attrs[i].name, args, n);
+	  break;
 	case HID_Real:
 	  stdarg (XmNcolumns, 16);
 	  stdarg (XmNresizeWidth, True);
@@ -823,6 +830,10 @@ lesstif_attribute_dialog (HID_Attribute * attrs,
 	  cp = XmTextGetString (wl[i]);
 	  sscanf (cp, "%d", &results[i].int_value);
 	  break;
+	case HID_Coord:
+	  cp = XmTextGetString (wl[i]);
+	  results[i].coord_value = GetValue (cp, NULL, NULL);
+	  break;
 	case HID_Real:
 	  cp = XmTextGetString (wl[i]);
 	  sscanf (cp, "%lg", &results[i].real_value);
diff --git a/src/hid/lesstif/lesstif.h b/src/hid/lesstif/lesstif.h
index e81c3e4..1ca229d 100644
--- a/src/hid/lesstif/lesstif.h
+++ b/src/hid/lesstif/lesstif.h
@@ -57,6 +57,10 @@ extern char *lesstif_fileselect (const char *, const char *,
 extern void lesstif_log (const char *fmt, ...);
 extern void lesstif_attributes_dialog (char *, AttributeListType *);
 
+#ifndef XtRPCBCoord
+#define XtRPCBCoord	"PCBCoord"
+#endif
+
 #define need_idle_proc lesstif_need_idle_proc
 #define show_crosshair lesstif_show_crosshair
 
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index d079d0c..ad10772 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -1950,12 +1950,12 @@ typedef union
   int i;
   double f;
   char *s;
+  Coord c;
 } val_union;
 
 static Boolean
-cvtres_string_to_double (Display * d, XrmValue * args, Cardinal * num_args,
-			 XrmValue * from, XrmValue * to,
-			 XtPointer * converter_data)
+pcb_cvt_string_to_double (Display * d, XrmValue * args, Cardinal * num_args,
+                          XrmValue * from, XrmValue * to, XtPointer * data)
 {
   static double rv;
   rv = strtod ((char *) from->addr, 0);
@@ -1967,6 +1967,20 @@ cvtres_string_to_double (Display * d, XrmValue * args, Cardinal * num_args,
   return True;
 }
 
+static Boolean
+pcb_cvt_string_to_coord (Display * d, XrmValue * args, Cardinal * num_args,
+                         XrmValue * from, XrmValue * to, XtPointer *data)
+{
+  static Coord rv;
+  rv = GetValue ((char *) from->addr, NULL, NULL);
+  if (to->addr)
+    *(Coord *) to->addr = rv;
+  else
+    to->addr = (XPointer) &rv;
+  to->size = sizeof (rv);
+  return TRUE;
+}
+
 static void
 mainwind_delete_cb ()
 {
@@ -1989,7 +2003,6 @@ lesstif_listener_cb (XtPointer client_data, int *fid, XtInputId *id)
     }
 }
 
-
 static void
 lesstif_parse_arguments (int *argc, char ***argv)
 {
@@ -2005,7 +2018,11 @@ lesstif_parse_arguments (int *argc, char ***argv)
 
   XtSetTypeConverter (XtRString,
 		      XtRDouble,
-		      cvtres_string_to_double, NULL, 0, XtCacheAll, NULL);
+		      pcb_cvt_string_to_double, NULL, 0, XtCacheAll, NULL);
+  XtSetTypeConverter (XtRString,
+		      XtRPCBCoord,
+		      pcb_cvt_string_to_coord, NULL, 0, XtCacheAll, NULL);
+
 
   for (ha = hid_attr_nodes; ha; ha = ha->next)
     for (i = 0; i < ha->n; i++)
@@ -2014,6 +2031,7 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	switch (a->type)
 	  {
 	  case HID_Integer:
+	  case HID_Coord:
 	  case HID_Real:
 	  case HID_String:
 	  case HID_Path:
@@ -2074,6 +2092,7 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	switch (a->type)
 	  {
 	  case HID_Integer:
+	  case HID_Coord:
 	  case HID_Real:
 	  case HID_String:
 	  case HID_Path:
@@ -2103,6 +2122,13 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	    r->default_addr = &(a->default_val.int_value);
 	    rcount++;
 	    break;
+	  case HID_Coord:
+	    r->resource_type = XtRPCBCoord;
+	    r->default_type = XtRPCBCoord;
+	    r->resource_size = sizeof (Coord);
+	    r->default_addr = &(a->default_val.coord_value);
+	    rcount++;
+	    break;
 	  case HID_Real:
 	    r->resource_type = XtRDouble;
 	    r->default_type = XtRDouble;
@@ -2185,6 +2211,13 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	      a->default_val.int_value = v->i;
 	    rcount++;
 	    break;
+	  case HID_Coord:
+	    if (a->value)
+	      *(Coord *) a->value = v->c;
+	    else
+	      a->default_val.coord_value = v->c;
+	    rcount++;
+	    break;
 	  case HID_Boolean:
 	    if (a->value)
 	      *(char *) a->value = v->i;
diff --git a/src/main.c b/src/main.c
index a54896a..cd6ccfa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -173,6 +173,9 @@ usage_attr (HID_Attribute * a)
     case HID_Real:
       sprintf (buf, "--%s <num>", a->name);
       break;
+    case HID_Coord:
+      sprintf (buf, "--%s <measure>", a->name);
+      break;
     case HID_String:
       sprintf (buf, "--%s <string>", a->name);
       break;
@@ -318,6 +321,7 @@ static void
 print_defaults_1 (HID_Attribute * a, void *value)
 {
   int i;
+  Coord c;
   double d;
   const char *s;
 
@@ -337,6 +341,10 @@ print_defaults_1 (HID_Attribute * a, void *value)
       d = value ? *(double *) value : a->default_val.real_value;
       fprintf (stderr, "%s %g\n", a->name, d);
       break;
+    case HID_Coord:
+      c = value ? *(Coord *) value : a->default_val.coord_value;
+      pcb_fprintf (stderr, "%s %$mS\n", a->name, c);
+      break;
     case HID_String:
     case HID_Path:
       s = value ? *(char **) value : a->default_val.str_value;
@@ -401,6 +409,8 @@ print_defaults ()
 	HID_Boolean, 0, 0, { D, 0, 0 }, 0, &Settings.F }
 #define RSET(F,D,N,H) { N, H, \
 	HID_Real,    0, 0, { 0, 0, D }, 0, &Settings.F }
+#define CSET(F,D,N,H) { N, H, \
+	HID_Coord,    0, 0, { 0, 0, 0, D }, 0, &Settings.F }
 
 #define COLOR(F,D,N,H) { N, H, \
 	HID_String, 0, 0, { 0, D, 0 }, 0, &Settings.F }
@@ -501,24 +511,24 @@ HID_Attribute main_attribute_list[] = {
   COLOR (WarnColor, "#ff8000", "warn-color", "color for warnings"),
   COLOR (MaskColor, "#ff0000", "mask-color", "color for solder mask"),
 
-  ISET (ViaThickness, MIL_TO_COORD(60), "via-thickness", 0),
-  ISET (ViaDrillingHole, MIL_TO_COORD(28), "via-drilling-hole", 0),
-  ISET (LineThickness, MIL_TO_COORD(10), "line-thickness",
+  CSET (ViaThickness, MIL_TO_COORD(60), "via-thickness", 0),
+  CSET (ViaDrillingHole, MIL_TO_COORD(28), "via-drilling-hole", 0),
+  CSET (LineThickness, MIL_TO_COORD(10), "line-thickness",
 	"Initial thickness of new lines."),
-  ISET (RatThickness, MIL_TO_COORD(10), "rat-thickness", 0),
-  ISET (Keepaway, MIL_TO_COORD(10), "keepaway", 0),
-  ISET (MaxWidth, MIL_TO_COORD(6000), "default-PCB-width", 0),
-  ISET (MaxHeight, MIL_TO_COORD(5000), "default-PCB-height", 0),
+  CSET (RatThickness, MIL_TO_COORD(10), "rat-thickness", 0),
+  CSET (Keepaway, MIL_TO_COORD(10), "keepaway", 0),
+  CSET (MaxWidth, MIL_TO_COORD(6000), "default-PCB-width", 0),
+  CSET (MaxHeight, MIL_TO_COORD(5000), "default-PCB-height", 0),
   ISET (TextScale, 100, "text-scale", 0),
-  ISET (AlignmentDistance, MIL_TO_COORD(2), "alignment-distance", 0),
-  ISET (Bloat, MIL_TO_COORD(10), "bloat", 0),
-  ISET (Shrink, MIL_TO_COORD(10), "shrink", 0),
-  ISET (minWid, MIL_TO_COORD(10), "min-width", "DRC minimum copper spacing"),
-  ISET (minSlk, MIL_TO_COORD(10), "min-silk", "DRC minimum silk width"),
-  ISET (minDrill, MIL_TO_COORD(15), "min-drill", "DRC minimum drill diameter"),
-  ISET (minRing, MIL_TO_COORD(10), "min-ring", "DRC minimum annular ring"),
-
-  ISET (Grid, MIL_TO_COORD(10), "grid", 0),
+  CSET (AlignmentDistance, MIL_TO_COORD(2), "alignment-distance", 0),
+  CSET (Bloat, MIL_TO_COORD(10), "bloat", 0),
+  CSET (Shrink, MIL_TO_COORD(10), "shrink", 0),
+  CSET (minWid, MIL_TO_COORD(10), "min-width", "DRC minimum copper spacing"),
+  CSET (minSlk, MIL_TO_COORD(10), "min-silk", "DRC minimum silk width"),
+  CSET (minDrill, MIL_TO_COORD(15), "min-drill", "DRC minimum drill diameter"),
+  CSET (minRing, MIL_TO_COORD(10), "min-ring", "DRC minimum annular ring"),
+
+  CSET (Grid, MIL_TO_COORD(10), "grid", 0),
   RSET (IsleArea, MIL_TO_COORD(100) * MIL_TO_COORD(100), "minimum polygon area", 0),
 
   ISET (BackupInterval, 60, "backup-interval", 0),
@@ -572,10 +582,10 @@ HID_Attribute main_attribute_list[] = {
   SSET (GnetlistProgram, NULL, "gnetlist",
 	"Sets the name and optionally full path to the gnetlist(3) program"),
 
-  ISET (PinoutOffsetX, MIL_TO_COORD(1), "pinout-offset-x", 0),
-  ISET (PinoutOffsetY, MIL_TO_COORD(1), "pinout-offset-y", 0),
-  ISET (PinoutTextOffsetX, MIL_TO_COORD(8), "pinout-text-offset-x", 0),
-  ISET (PinoutTextOffsetY, MIL_TO_COORD(-1), "pinout-text-offset-y", 0),
+  CSET (PinoutOffsetX, MIL_TO_COORD(1), "pinout-offset-x", 0),
+  CSET (PinoutOffsetY, MIL_TO_COORD(1), "pinout-offset-y", 0),
+  CSET (PinoutTextOffsetX, MIL_TO_COORD(8), "pinout-text-offset-x", 0),
+  CSET (PinoutTextOffsetY, MIL_TO_COORD(-1), "pinout-text-offset-y", 0),
 
   BSET (DrawGrid, 0, "draw-grid", "default to drawing the grid at startup"),
   BSET (ClearLine, 1, "clear-line", 0),

commit 0803816da4460d0bb25b92a4fd67400873da5907
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change lesstif_logv to use pcb-printf [rebase-after: audit lesstif]

diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index 0460a4e..b7e6c16 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -292,8 +292,6 @@ Save (int argc, char **argv, Coord x, Coord y)
 /* ------------------------------------------------------------ */
 
 static Widget log_form, log_text;
-static char *msg_buffer = 0;
-static int msg_buffer_size = 0;
 static int log_size = 0;
 static int pending_newline = 0;
 
@@ -314,8 +312,7 @@ log_dismiss (Widget w, void *up, void *cbp)
 void
 lesstif_logv (const char *fmt, va_list ap)
 {
-  int i;
-  char *bp;
+  gchar *buf, *scan;
   if (!mainwind)
     {
       vprintf (fmt, ap);
@@ -361,42 +358,30 @@ lesstif_logv (const char *fmt, va_list ap)
       log_text = XmCreateScrolledText (log_form, "text", args, n);
       XtManageChild (log_text);
 
-      msg_buffer = (char *) malloc (1002);
-      msg_buffer_size = 1002;
       XtManageChild (log_form);
     }
-  bp = msg_buffer;
   if (pending_newline)
     {
-      *bp++ = '\n';
+      XmTextInsert (log_text, log_size++, "\n");
       pending_newline = 0;
     }
-#ifdef HAVE_VSNPRINTF
-  i = vsnprintf (bp, msg_buffer_size, fmt, ap);
-  if (i >= msg_buffer_size)
-    {
-      msg_buffer_size = i + 100;
-      msg_buffer = (char *) realloc (msg_buffer, msg_buffer_size + 2);
-      vsnprintf (bp, msg_buffer_size, fmt, ap);
-    }
-#else
-  vsprintf (bp, fmt, ap);
-#endif
-  bp = msg_buffer + strlen (msg_buffer) - 1;
-  while (bp >= msg_buffer && bp[0] == '\n')
+  buf = pcb_vprintf (fmt, ap);
+  scan = &buf[strlen (buf) - 1];
+  while (scan >= buf && *scan == '\n')
     {
       pending_newline++;
-      *bp-- = 0;
+      *scan-- = 0;
     }
-  XmTextInsert (log_text, log_size, msg_buffer);
-  log_size += strlen (msg_buffer);
+  XmTextInsert (log_text, log_size, buf);
+  log_size += strlen (buf);
 
-  bp = strrchr(msg_buffer, '\n');
-  if (bp)
-    bp++;
+  scan = strrchr(buf, '\n');
+  if (scan)
+    scan++;
   else
-    bp = msg_buffer;
-  XmTextSetCursorPosition (log_text, log_size - strlen(bp));
+    scan = buf;
+  XmTextSetCursorPosition (log_text, log_size - strlen(scan));
+  g_free (buf);
 }
 
 void

commit 4cc668bb98e986cb16c28e3dac9e71130b814c82
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit lesstif HID
    
    We can now remove LocationType and BDimension! This marks the
    completion of the code audit. Remaining to do is the conversion
    and test.

diff --git a/src/global.h b/src/global.h
index 666d0cf..731742d 100644
--- a/src/global.h
+++ b/src/global.h
@@ -89,11 +89,6 @@ typedef double Angle;		/* degrees */
 # define bindtextdomain(D, Dir) (D)
 #endif /* ENABLE_NLS */
 
-#if 1
-typedef int LocationType;
-typedef int BDimension;		/* big dimension */
-#endif
-
 /* This is used by the lexer/parser */
 typedef struct {
   int ival;
diff --git a/src/gpcb-menu.res.in b/src/gpcb-menu.res.in
index 7449d50..a715ffd 100644
--- a/src/gpcb-menu.res.in
+++ b/src/gpcb-menu.res.in
@@ -117,8 +117,8 @@ MainMenu =
   {"View"
    {"Enable visible grid" checked=drawgrid Display(Grid)}
    {"Grid units"
-    {"mil" checked=grid_units_mil SetUnits(mil)}
-    {"mm"  checked=grid_units_mm SetUnits(mm)}
+    {"mil" checked=grid_units_mil,1 SetUnits(mil)}
+    {"mm"  checked=grid_units_mm,1 SetUnits(mm)}
    }
    {"Grid size"
     {"No Grid" checked=grid,0 SetValue(Grid,1)}
diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index 5606e5b..0460a4e 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -1134,17 +1134,14 @@ static Widget sz_set, sz_reset, sz_units;
 static int
 sz_str2val (Widget w, bool pcbu)
 {
-  double d;
-  char *buf;
-  buf = XmTextGetString (w);
+  char *buf = XmTextGetString (w);
   if (!pcbu)
     return strtol (buf, NULL, 0);
-  sscanf (buf, "%lf", &d);
-  return unit_to_coord (Settings.grid_unit, d);
+  return GetValueEx (buf, NULL, NULL, NULL, Settings.grid_unit->suffix);
 }
 
 static void
-sz_val2str (Widget w, BDimension u, int pcbu)
+sz_val2str (Widget w, Coord u, int pcbu)
 {
   static char buf[40];
   if (pcbu)
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index ef0b164..d079d0c 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -108,8 +108,8 @@ typedef struct PinoutData
   struct PinoutData *prev, *next;
   Widget form;
   Window window;
-  int left, right, top, bottom;	/* PCB extents of item */
-  int x, y;			/* PCB coordinates of upper right corner of window */
+  Coord left, right, top, bottom;	/* PCB extents of item */
+  Coord x, y;			/* PCB coordinates of upper right corner of window */
   double zoom;			/* PCB units per screen pixel */
   int v_width, v_height;	/* pixels */
   void *item;
@@ -2115,7 +2115,7 @@ lesstif_parse_arguments (int *argc, char ***argv)
 	    r->resource_type = XtRString;
 	    r->default_type = XtRString;
 	    r->resource_size = sizeof (char *);
-	    r->default_addr = a->default_val.str_value;
+	    r->default_addr = (char *) a->default_val.str_value;
 	    rcount++;
 	    break;
 	  case HID_Boolean:
@@ -2312,7 +2312,7 @@ draw_grid ()
 }
 
 static void
-mark_delta_to_widget (BDimension dx, BDimension dy, Widget w)
+mark_delta_to_widget (Coord dx, Coord dy, Widget w)
 {
   char *buf;
   double g = coord_to_unit (Settings.grid_unit, PCB->Grid);
@@ -2329,8 +2329,8 @@ mark_delta_to_widget (BDimension dx, BDimension dy, Widget w)
     buf = pcb_g_strdup_printf ("%m+%+.*mS, %+.*mS", UUNIT, prec, dx, prec, dy);
   else
     {
-      int angle = atan2 (dy, -dx) * 180 / M_PI;
-      BDimension dist = Distance (0, 0, dx, dy);
+      Angle angle = atan2 (dy, -dx) * 180 / M_PI;
+      Coord dist = Distance (0, 0, dx, dy);
 
       buf = pcb_g_strdup_printf ("%m+%+.*mS, %+.*mS (%.*mS, %d\260)", UUNIT,
                              prec, dx, prec, dy, prec, dist, angle);
@@ -2344,7 +2344,7 @@ mark_delta_to_widget (BDimension dx, BDimension dy, Widget w)
 }
 
 static int
-cursor_pos_to_widget (BDimension x, BDimension y, Widget w, int prev_state)
+cursor_pos_to_widget (Coord x, Coord y, Widget w, int prev_state)
 {
   int this_state = prev_state;
   static char *buf;
@@ -2452,13 +2452,13 @@ idle_proc (XtPointer dummy)
       region.Y2 = Py (view_height);
       if (flip_x)
 	{
-	  int tmp = region.X1;
+	  Coord tmp = region.X1;
 	  region.X1 = region.X2;
 	  region.X2 = tmp;
 	}
       if (flip_y)
 	{
-	  int tmp = region.Y1;
+	  Coord tmp = region.Y1;
 	  region.Y1 = region.Y2;
 	  region.Y2 = tmp;
 	}
@@ -3187,7 +3187,7 @@ lesstif_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-lesstif_set_line_width (hidGC gc, int width)
+lesstif_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -3201,7 +3201,7 @@ lesstif_set_draw_xor (hidGC gc, int xor_set)
 #define ISORT(a,b) if (a>b) { a^=b; b^=a; a^=b; }
 
 static void
-lesstif_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+lesstif_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   double dx1, dy1, dx2, dy2;
   int vw = Vz (gc->width);
@@ -3247,8 +3247,8 @@ lesstif_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-lesstif_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-		  int start_angle, int delta_angle)
+lesstif_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+		  Angle start_angle, Angle delta_angle)
 {
   if ((pinout || TEST_FLAG (THINDRAWFLAG, PCB)) && gc->erase)
     return;
@@ -3269,7 +3269,9 @@ lesstif_draw_arc (hidGC gc, int cx, int cy, int width, int height,
       start_angle = - start_angle;
       delta_angle = - delta_angle;					
     }
-  start_angle = (start_angle + 360 + 180) % 360 - 180;
+  start_angle = NormalizeAngle (start_angle);
+  if (start_angle >= 180)
+    start_angle -= 360;
 #if 0
   pcb_printf (" = %#mD %#mSx%#mS %d %s\n", cx, cy, width, height, gc->width,
 	  gc->colorname);
@@ -3301,7 +3303,7 @@ lesstif_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-lesstif_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+lesstif_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   int vw = Vz (gc->width);
   if ((pinout || TEST_FLAG (THINDRAWFLAG, PCB)) && gc->erase)
@@ -3328,7 +3330,7 @@ lesstif_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-lesstif_fill_circle (hidGC gc, int cx, int cy, int radius)
+lesstif_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   if (pinout && use_mask && gc->erase)
     return;
@@ -3356,7 +3358,7 @@ lesstif_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-lesstif_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+lesstif_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   static XPoint *p = 0;
   static int maxp = 0;
@@ -3388,7 +3390,7 @@ lesstif_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 }
 
 static void
-lesstif_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+lesstif_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   int vw = Vz (gc->width);
   if ((pinout || TEST_FLAG (THINDRAWFLAG, PCB)) && gc->erase)
diff --git a/src/hid/lesstif/styles.c b/src/hid/lesstif/styles.c
index ee07273..b6e3b51 100644
--- a/src/hid/lesstif/styles.c
+++ b/src/hid/lesstif/styles.c
@@ -15,6 +15,7 @@
 #include "global.h"
 #include "data.h"
 #include "set.h"
+#include "misc.h"
 #include "mymem.h"
 #include "pcb-printf.h"
 
@@ -159,15 +160,13 @@ update_style_buttons ()
 static void
 style_value_cb (Widget w, int i, void *cbs)
 {
-  double d;
   Coord n;
   char *s;
 
   if (local_update)
     return;
   s = XmTextGetString (w);
-  sscanf (s, "%lf", &d);
-  n = unit_to_coord (unit, d);
+  n = GetValueEx (s, NULL, NULL, NULL, unit->suffix);
   switch (i)
     {
     case SSthick:
diff --git a/src/pcb-menu.res.in b/src/pcb-menu.res.in
index fc3008a..7e6e8bd 100644
--- a/src/pcb-menu.res.in
+++ b/src/pcb-menu.res.in
@@ -90,8 +90,8 @@ MainMenu =
     {"Zoom to 10mil/px" Zoom(=10mil)}
    }
    {Grid
-    {"mil" checked=grid_units_mil SetUnits(mil)}
-    {"mm"  checked=grid_units_mm SetUnits(mm)}
+    {"mil" checked=grid_units_mil,1 SetUnits(mil)}
+    {"mm"  checked=grid_units_mm,1 SetUnits(mm)}
     {"Display grid" checked=drawgrid Display(Grid)}
     {"Realign grid" GetXY(Click to set the grid origin) Display(ToggleGrid)}
     {"No Grid" checked=grid,0 SetValue(Grid,1)}

commit e46c9ef9505e88e446f003e5d89df0547c65b3f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit Gtk HID

diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index 99472cd..c38cbc5 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -462,7 +462,7 @@ ghid_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 void
-ghid_set_line_width (hidGC gc, int width)
+ghid_set_line_width (hidGC gc, Coord width)
 {
   render_priv *priv = gport->render_priv;
 
@@ -518,7 +518,7 @@ use_gc (hidGC gc)
 }
 
 void
-ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   double dx1, dy1, dx2, dy2;
   render_priv *priv = gport->render_priv;
@@ -537,8 +537,8 @@ ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 void
-ghid_draw_arc (hidGC gc, int cx, int cy,
-	       int xradius, int yradius, int start_angle, int delta_angle)
+ghid_draw_arc (hidGC gc, Coord cx, Coord cy,
+	       Coord xradius, Coord yradius, Angle start_angle, Angle delta_angle)
 {
   gint vrx, vry;
   gint w, h, radius;
@@ -568,7 +568,8 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
       delta_angle = -delta_angle;
     }
   /* make sure we fall in the -180 to +180 range */
-  start_angle = (start_angle + 360 + 180) % 360 - 180;
+  start_angle = NormalizeAngle (start_angle);
+  if (start_angle >= 180)  start_angle -= 360;
 
   gdk_draw_arc (gport->drawable, priv->u_gc, 0,
 		Vx (cx) - vrx, Vy (cy) - vry,
@@ -576,7 +577,7 @@ ghid_draw_arc (hidGC gc, int cx, int cy,
 }
 
 void
-ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   gint w, h, lw;
   render_priv *priv = gport->render_priv;
@@ -620,7 +621,7 @@ ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 
 
 void
-ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
+ghid_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   gint w, h, vr;
   render_priv *priv = gport->render_priv;
@@ -640,7 +641,7 @@ ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 void
-ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+ghid_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   static GdkPoint *points = 0;
   static int npoints = 0;
@@ -662,7 +663,7 @@ ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 }
 
 void
-ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   gint w, h, lw, xx, yy;
   render_priv *priv = gport->render_priv;
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 5c554fa..71ab0fa 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -534,7 +534,7 @@ use_gc (hidGC gc)
 }
 
 void
-ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   USE_GC (gc);
 
@@ -542,8 +542,8 @@ ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 void
-ghid_draw_arc (hidGC gc, int cx, int cy, int xradius, int yradius,
-                         int start_angle, int delta_angle)
+ghid_draw_arc (hidGC gc, Coord cx, Coord cy, Coord xradius, Coord yradius,
+                         Angle start_angle, Angle delta_angle)
 {
   USE_GC (gc);
 
@@ -552,7 +552,7 @@ ghid_draw_arc (hidGC gc, int cx, int cy, int xradius, int yradius,
 }
 
 void
-ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   USE_GC (gc);
 
@@ -561,7 +561,7 @@ ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 
 
 void
-ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
+ghid_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   USE_GC (gc);
 
@@ -570,7 +570,7 @@ ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
 
 
 void
-ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+ghid_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   USE_GC (gc);
 
@@ -595,7 +595,7 @@ ghid_thindraw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box)
 }
 
 void
-ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ghid_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   USE_GC (gc);
 
diff --git a/src/hid/gtk/gui-log-window.c b/src/hid/gtk/gui-log-window.c
index e964b8e..5f6d58f 100644
--- a/src/hid/gtk/gui-log-window.c
+++ b/src/hid/gtk/gui-log-window.c
@@ -34,6 +34,7 @@
 #endif
 
 #include "gui.h"
+#include "pcb-printf.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -137,64 +138,12 @@ ghid_log (const char *fmt, ...)
   va_end (ap);
 }
 
-static char *msg_buffer = 0;
-static int msg_buffer_size = 0;
-
 void
 ghid_logv (const char *fmt, va_list args)
 {
-  int i;
-
-  if (msg_buffer == NULL)
-    {
-      msg_buffer = (char *) malloc (1002);
-      if (msg_buffer == NULL)
-	{
-	  fprintf (stderr, "ghid_logv():  malloc failed\n\n");
-	  exit (1);
-	}
-      msg_buffer_size = 1000;
-    }
-
-  /* 
-   * FIXME -- fix check to see if the main window is up.  Is 
-   * that needed here?  Lesstif does it.
-   */
-#ifdef FIXME
-  if (!mainwind)
-    {
-      vprintf (fmt, args);
-      return;
-    }
-#endif
-
-#ifdef HAVE_VSNPRINTF
-
-  /* 
-   * NOTE:  some implementations of vsnprintf(), for example
-   * solaris-2.9, will not return the formatted length if you
-   * use a length of 0 in the initial call.  So, we use a small
-   * buffer.
-   */
-  i = vsnprintf (msg_buffer, msg_buffer_size, fmt, args);
-  if (i >= msg_buffer_size)
-    {
-      msg_buffer_size = i + 100;
-      msg_buffer = (char *) realloc (msg_buffer, msg_buffer_size + 2);
-      if (msg_buffer == NULL)
-	{
-	  fprintf (stderr, "ghid_logv():  malloc failed\n\n");
-	  exit (1);
-	}
-      vsnprintf (msg_buffer, msg_buffer_size, fmt, args);
-    }
-
-#else
-  vsprintf (msg_buffer, fmt, args);
-#endif /* !HAVE_VSNPRINTF */
-
-  ghid_log_append_string (msg_buffer);
-
+  gchar *msg = pcb_vprintf (fmt, args);
+  ghid_log_append_string (msg);
+  g_free (msg);
 }
 
 static const char logshowonappend_syntax[] =
diff --git a/src/hid/gtk/gui-misc.c b/src/hid/gtk/gui-misc.c
index 396abe1..3ed276c 100644
--- a/src/hid/gtk/gui-misc.c
+++ b/src/hid/gtk/gui-misc.c
@@ -435,10 +435,10 @@ ghid_set_cursor_position_labels (void)
 
   if (Marked.status)
     {
-      BDimension dx = Crosshair.X - Marked.X;
-      BDimension dy = Crosshair.Y - Marked.Y;
-      BDimension r  = Distance (Crosshair.X, Crosshair.Y, Marked.X, Marked.Y);
-      double a      = atan2 (dy, dx) * RAD_TO_DEG;
+      Coord dx = Crosshair.X - Marked.X;
+      Coord dy = Crosshair.Y - Marked.Y;
+      Coord r  = Distance (Crosshair.X, Crosshair.Y, Marked.X, Marked.Y);
+      double a = atan2 (dy, dx) * RAD_TO_DEG;
 
       text = pcb_g_strdup_printf ("%m+r %-mS; phi %-.1f; %-mS %-mS",
                                   Settings.grid_unit->allow,
diff --git a/src/hid/gtk/gui-output-events.c b/src/hid/gtk/gui-output-events.c
index 2bb3dd7..527945a 100644
--- a/src/hid/gtk/gui-output-events.c
+++ b/src/hid/gtk/gui-output-events.c
@@ -474,7 +474,7 @@ ghid_port_drawing_area_configure_event_cb (GtkWidget * widget,
 
 
 static char *
-describe_location (LocationType X, LocationType Y)
+describe_location (Coord X, Coord Y)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 2f63b57..807afce 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -170,9 +170,9 @@ typedef struct
 |  out - the largest value means you are looking at the whole board.
 */
   gdouble zoom;			/* PCB units per screen pixel.  Larger */
-  /* numbers mean zooming out. */
-  gint view_x0,			/* Viewport in PCB coordinates */
-    view_y0, view_width, view_height;
+                                /* numbers mean zooming out. */
+  /* Viewport in PCB coordinates */
+  Coord view_x0, view_y0, view_width, view_height;
   Coord pcb_x, pcb_y;
 
   gint crosshair_x, crosshair_y;
@@ -462,15 +462,15 @@ void ghid_destroy_gc (hidGC);
 void ghid_use_mask (int use_it);
 void ghid_set_color (hidGC gc, const char *name);
 void ghid_set_line_cap (hidGC gc, EndCapStyle style);
-void ghid_set_line_width (hidGC gc, int width);
+void ghid_set_line_width (hidGC gc, Coord width);
 void ghid_set_draw_xor (hidGC gc, int _xor);
-void ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2);
-void ghid_draw_arc (hidGC gc, int cx, int cy, int xradius, int yradius,
-                    int start_angle, int delta_angle);
-void ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2);
-void ghid_fill_circle (hidGC gc, int cx, int cy, int radius);
-void ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y);
-void ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
+void ghid_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+void ghid_draw_arc (hidGC gc, Coord cx, Coord cy, Coord xradius, Coord yradius,
+                    Angle start_angle, Angle delta_angle);
+void ghid_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+void ghid_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
+void ghid_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y);
+void ghid_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
 void ghid_invalidate_lr (int left, int right, int top, int bottom);
 void ghid_invalidate_all ();
 void ghid_notify_crosshair_change (bool changes_complete);
@@ -511,7 +511,7 @@ extern GdkPixmap *XC_clock_source, *XC_clock_mask;
 /* Coordinate conversions */
 /* Px converts view->pcb, Vx converts pcb->view */
 static inline int
-Vx (int x)
+Vx (Coord x)
 {
   int rv;
   if (ghid_flip_x)
@@ -522,7 +522,7 @@ Vx (int x)
 }
 
 static inline int
-Vy (int y)
+Vy (Coord y)
 {
   int rv;
   if (ghid_flip_y)
@@ -533,30 +533,30 @@ Vy (int y)
 }
 
 static inline int
-Vz (int z)
+Vz (Coord z)
 {
   return z / gport->zoom + 0.5;
 }
 
-static inline int
+static inline Coord
 Px (int x)
 {
-  int rv = x * gport->zoom + gport->view_x0;
+  Coord rv = x * gport->zoom + gport->view_x0;
   if (ghid_flip_x)
     rv = PCB->MaxWidth - (x * gport->zoom + gport->view_x0);
   return  rv;
 }
 
-static inline int
+static inline Coord
 Py (int y)
 {
-  int rv = y * gport->zoom + gport->view_y0;
+  Coord rv = y * gport->zoom + gport->view_y0;
   if (ghid_flip_y)
     rv = PCB->MaxHeight - (y * gport->zoom + gport->view_y0);
   return  rv;
 }
 
-static inline int
+static inline Coord
 Pz (int z)
 {
   return (z * gport->zoom);

commit c73e0ee01e6b348aa772919225afaab31ee2f1df
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit HID nogui/common code

diff --git a/src/hid/common/draw_helpers.c b/src/hid/common/draw_helpers.c
index d7ef716..03e82d8 100644
--- a/src/hid/common/draw_helpers.c
+++ b/src/hid/common/draw_helpers.c
@@ -5,12 +5,12 @@
 static void
 fill_contour (hidGC gc, PLINE *pl)
 {
-  int *x, *y, n, i = 0;
+  Coord *x, *y, n, i = 0;
   VNODE *v;
 
   n = pl->Count;
-  x = (int *)malloc (n * sizeof (int));
-  y = (int *)malloc (n * sizeof (int));
+  x = (Coord *)malloc (n * sizeof (*x));
+  y = (Coord *)malloc (n * sizeof (*y));
 
   for (v = &pl->head; i < n; v = v->next)
     {
@@ -28,8 +28,8 @@ static void
 thindraw_contour (hidGC gc, PLINE *pl)
 {
   VNODE *v;
-  int last_x, last_y;
-  int this_x, this_y;
+  Coord last_x, last_y;
+  Coord this_x, this_y;
 
   gui->set_line_width (gc, 0);
   gui->set_line_cap (gc, Round_Cap);
@@ -110,9 +110,9 @@ fill_clipped_contour (hidGC gc, PLINE *pl, const BoxType *clip_box)
 static int
 should_compute_no_holes (PolygonType *poly, const BoxType *clip_box)
 {
-  int x1, x2, y1, y2;
-  float poly_bounding_area;
-  float clipped_poly_area;
+  Coord x1, x2, y1, y2;
+  double poly_bounding_area;
+  double clipped_poly_area;
 
   /* If there is no passed clip box, compute the whole thing */
   if (clip_box == NULL)
@@ -127,10 +127,10 @@ should_compute_no_holes (PolygonType *poly, const BoxType *clip_box)
   if ((x2 <= x1) || (y2 <= y1))
     return 0;
 
-  poly_bounding_area = (float)(poly->BoundingBox.X2 - poly->BoundingBox.X1) *
-                       (float)(poly->BoundingBox.Y2 - poly->BoundingBox.Y1);
+  poly_bounding_area = (double)(poly->BoundingBox.X2 - poly->BoundingBox.X1) *
+                       (double)(poly->BoundingBox.Y2 - poly->BoundingBox.Y1);
 
-  clipped_poly_area = (float)(x2 - x1) * (float)(y2 - y1);
+  clipped_poly_area = (double)(x2 - x1) * (double)(y2 - y1);
 
   if (clipped_poly_area / poly_bounding_area >= BOUNDS_INSIDE_CLIP_THRESHOLD)
     return 1;
@@ -198,19 +198,19 @@ common_thindraw_pcb_polygon (hidGC gc, PolygonType *poly,
 void
 common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
 {
-  int w = clear ? (mask ? pad->Mask
-                        : pad->Thickness + pad->Clearance)
-                : pad->Thickness;
-  int x1, y1, x2, y2;
-  int t = w / 2;
+  Coord w = clear ? (mask ? pad->Mask
+                          : pad->Thickness + pad->Clearance)
+                  : pad->Thickness;
+  Coord x1, y1, x2, y2;
+  Coord t = w / 2;
   x1 = pad->Point1.X;
   y1 = pad->Point1.Y;
   x2 = pad->Point2.X;
   y2 = pad->Point2.Y;
   if (x1 > x2 || y1 > y2)
     {
-      int temp_x = x1;
-      int temp_y = y1;
+      Coord temp_x = x1;
+      Coord temp_y = y1;
       x1 = x2; x2 = temp_x;
       y1 = y2; y2 = temp_y;
     }
@@ -219,7 +219,7 @@ common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
   if (TEST_FLAG (SQUAREFLAG, pad))
     {
       /* slanted square pad */
-      float tx, ty, theta;
+      double tx, ty, theta;
 
       if (x1 == x2 && y1 == y2)
         theta = 0;
@@ -243,8 +243,8 @@ common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
   else
     {
       /* Slanted round-end pads.  */
-      LocationType dx, dy, ox, oy;
-      float h;
+      Coord dx, dy, ox, oy;
+      double h;
 
       dx = x2 - x1;
       dy = y2 - y1;
@@ -256,7 +256,7 @@ common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
 
       if (abs (ox) >= pixel_slop || abs (oy) >= pixel_slop)
         {
-          LocationType angle = atan2 (dx, dy) * 57.295779;
+          Angle angle = atan2 (dx, dy) * 57.295779;
           gui->draw_line (gc, x1 - ox, y1 - oy, x2 - ox, y2 - oy);
           gui->draw_arc (gc, x1, y1, t, t, angle - 180, 180);
           gui->draw_arc (gc, x2, y2, t, t, angle, 180);
@@ -267,16 +267,16 @@ common_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
 void
 common_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
 {
-  int w = clear ? (mask ? pad->Mask
-                        : pad->Thickness + pad->Clearance)
-                : pad->Thickness;
+  Coord w = clear ? (mask ? pad->Mask
+                          : pad->Thickness + pad->Clearance)
+                  : pad->Thickness;
 
   if (pad->Point1.X == pad->Point2.X &&
       pad->Point1.Y == pad->Point2.Y)
     {
       if (TEST_FLAG (SQUAREFLAG, pad))
         {
-          int l, r, t, b;
+          Coord l, r, t, b;
           l = pad->Point1.X - w / 2;
           b = pad->Point1.Y - w / 2;
           r = l + w;
@@ -320,8 +320,8 @@ typedef struct
 FloatPolyType;
 
 static void
-draw_octagon_poly (hidGC gc, LocationType X, LocationType Y,
-                   int Thickness, int thin_draw)
+draw_octagon_poly (hidGC gc, Coord X, Coord Y,
+                   Coord Thickness, Coord thin_draw)
 {
   static FloatPolyType p[8] = {
     { 0.5,               -TAN_22_5_DEGREE_2},
@@ -336,8 +336,8 @@ draw_octagon_poly (hidGC gc, LocationType X, LocationType Y,
   static int special_size = 0;
   static int scaled_x[8];
   static int scaled_y[8];
-  int polygon_x[9];
-  int polygon_y[9];
+  Coord polygon_x[9];
+  Coord polygon_y[9];
   int i;
 
   if (Thickness != special_size)
@@ -374,8 +374,8 @@ draw_octagon_poly (hidGC gc, LocationType X, LocationType Y,
 void
 common_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask)
 {
-  int w = mask ? pv->Mask : pv->Thickness;
-  int r = w / 2;
+  Coord w = mask ? pv->Mask : pv->Thickness;
+  Coord r = w / 2;
 
   if (TEST_FLAG (HOLEFLAG, pv))
     {
@@ -393,10 +393,10 @@ common_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool m
 
   if (TEST_FLAG (SQUAREFLAG, pv))
     {
-      int l = pv->X - r;
-      int b = pv->Y - r;
-      int r = l + w;
-      int t = b + w;
+      Coord l = pv->X - r;
+      Coord b = pv->Y - r;
+      Coord r = l + w;
+      Coord t = b + w;
 
       gui->fill_rect (fg_gc, l, b, r, t);
     }
@@ -413,8 +413,8 @@ common_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool m
 void
 common_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask)
 {
-  int w = mask ? pv->Mask : pv->Thickness;
-  int r = w / 2;
+  Coord w = mask ? pv->Mask : pv->Thickness;
+  Coord r = w / 2;
 
   if (TEST_FLAG (HOLEFLAG, pv))
     {
@@ -432,10 +432,10 @@ common_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bo
 
   if (TEST_FLAG (SQUAREFLAG, pv))
     {
-      int l = pv->X - r;
-      int b = pv->Y - r;
-      int r = l + w;
-      int t = b + w;
+      Coord l = pv->X - r;
+      Coord b = pv->Y - r;
+      Coord r = l + w;
+      Coord t = b + w;
 
       gui->set_line_cap (fg_gc, Round_Cap);
       gui->set_line_width (fg_gc, 0);
diff --git a/src/hid/common/extents.c b/src/hid/common/extents.c
index 2de34ac..6cdc135 100644
--- a/src/hid/common/extents.c
+++ b/src/hid/common/extents.c
@@ -90,7 +90,7 @@ extents_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-extents_set_line_width (hidGC gc, int width)
+extents_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -106,7 +106,7 @@ extents_set_draw_xor (hidGC gc, int xor_)
 	if (box.Y2 < (y)+(w)) box.Y2 = (y)+(w)
 
 static void
-extents_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+extents_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   PEX (x1, gc->width);
   PEY (y1, gc->width);
@@ -115,8 +115,8 @@ extents_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-extents_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-		  int start_angle, int end_angle)
+extents_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+		  Angle start_angle, Angle end_angle)
 {
   /* Naive but good enough.  */
   PEX (cx, width + gc->width);
@@ -124,7 +124,7 @@ extents_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-extents_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+extents_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   PEX (x1, gc->width);
   PEY (y1, gc->width);
@@ -133,14 +133,14 @@ extents_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-extents_fill_circle (hidGC gc, int cx, int cy, int radius)
+extents_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   PEX (cx, radius);
   PEY (cy, radius);
 }
 
 static void
-extents_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+extents_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   int i;
   for (i = 0; i < n_coords; i++)
@@ -151,7 +151,7 @@ extents_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 }
 
 static void
-extents_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+extents_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   PEX (x1, 0);
   PEY (y1, 0);
diff --git a/src/hid/common/hidnogui.c b/src/hid/common/hidnogui.c
index 55e6dca..9d88086 100644
--- a/src/hid/common/hidnogui.c
+++ b/src/hid/common/hidnogui.c
@@ -103,7 +103,7 @@ nogui_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-nogui_set_line_width (hidGC gc, int width)
+nogui_set_line_width (hidGC gc, Coord width)
 {
   CRASH;
 }
@@ -120,32 +120,32 @@ nogui_set_draw_faded (hidGC gc, int faded)
 }
 
 static void
-nogui_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+nogui_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   CRASH;
 }
 
 static void
-nogui_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-		int start_angle, int end_angle)
+nogui_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+		Angle start_angle, Angle end_angle)
 {
   CRASH;
 }
 
 static void
-nogui_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+nogui_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   CRASH;
 }
 
 static void
-nogui_fill_circle (hidGC gc, int cx, int cy, int radius)
+nogui_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   CRASH;
 }
 
 static void
-nogui_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+nogui_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   CRASH;
 }
@@ -181,7 +181,7 @@ nogui_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pad, bool drawHole, bo
 }
 
 static void
-nogui_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+nogui_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   CRASH;
 }

commit 7822af60f7b28648eb41b2a2ae1aa5d55dd54182
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit nelma HID

diff --git a/src/hid/nelma/nelma.c b/src/hid/nelma/nelma.c
index 6e1e9cd..e91594b 100644
--- a/src/hid/nelma/nelma.c
+++ b/src/hid/nelma/nelma.c
@@ -99,7 +99,7 @@ struct color_struct {
 struct hid_gc_struct {
 	HID            *me_pointer;
 	EndCapStyle     cap;
-	int             width;
+	Coord           width;
 	unsigned char   r, g, b;
 	int             erase;
 	int             faded;
@@ -110,7 +110,7 @@ struct hid_gc_struct {
 static HID nelma_hid;
 
 static struct color_struct *black = NULL, *white = NULL;
-static int      linewidth = -1;
+static Coord    linewidth = -1;
 static int      lastgroup = -1;
 static gdImagePtr lastbrush = (gdImagePtr)((void *) -1);
 static int      lastcap = -1;
@@ -184,13 +184,9 @@ REGISTER_ATTRIBUTES(nelma_attribute_list)
 /* *** Utility funcions **************************************************** */
 
 /* convert from default PCB units to nelma units */
-	static int      pcb_to_nelma(int pcb)
+static int pcb_to_nelma (Coord pcb)
 {
-	int             nelma;
-
-	nelma = COORD_TO_INCH(pcb) * nelma_dpi;
-
-	return nelma;
+  return COORD_TO_INCH(pcb) * nelma_dpi;
 }
 
 static char    *
@@ -210,7 +206,7 @@ nelma_get_png_name(const char *basename, const char *suffix)
 /* Retrieves coordinates (in default PCB units) of a pin or pad. */
 /* Copied from netlist.c */
 static int 
-pin_name_to_xy(LibraryEntryType * pin, int *x, int *y)
+pin_name_to_xy (LibraryEntryType * pin, Coord *x, Coord *y)
 {
 	ConnectionType  conn;
 	if (!SeekPad(pin, &conn, false))
@@ -430,15 +426,16 @@ static void
 nelma_write_object(FILE * out, LibraryEntryTypePtr pin)
 {
 	int             i, idx;
-	int             x = 0, y = 0;
+	Coord           px = 0, py = 0;
+	int             x, y;
 
 	char           *f;
 	const char     *ext;
 
-	pin_name_to_xy(pin, &x, &y);
+	pin_name_to_xy (pin, &px, &py);
 
-	x = pcb_to_nelma(x);
-	y = pcb_to_nelma(y);
+	x = pcb_to_nelma (px);
+	y = pcb_to_nelma (py);
 
 	for (i = 0; i < MAX_LAYER; i++)
 		if (nelma_export_group[i]) {
@@ -790,7 +787,7 @@ nelma_set_line_cap(hidGC gc, EndCapStyle style)
 }
 
 static void
-nelma_set_line_width(hidGC gc, int width)
+nelma_set_line_width(hidGC gc, Coord width)
 {
 	gc->width = width;
 }
@@ -912,7 +909,7 @@ use_gc(hidGC gc)
 }
 
 static void
-nelma_draw_rect(hidGC gc, int x1, int y1, int x2, int y2)
+nelma_draw_rect(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
 	use_gc(gc);
 	gdImageRectangle(nelma_im,
@@ -921,7 +918,7 @@ nelma_draw_rect(hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-nelma_fill_rect(hidGC gc, int x1, int y1, int x2, int y2)
+nelma_fill_rect(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
 	use_gc(gc);
 	gdImageSetThickness(nelma_im, 0);
@@ -931,10 +928,10 @@ nelma_fill_rect(hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-nelma_draw_line(hidGC gc, int x1, int y1, int x2, int y2)
+nelma_draw_line(hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
 	if (x1 == x2 && y1 == y2) {
-		int             w = gc->width / 2;
+		Coord             w = gc->width / 2;
 		nelma_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w);
 		return;
 	}
@@ -947,10 +944,10 @@ nelma_draw_line(hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-nelma_draw_arc(hidGC gc, int cx, int cy, int width, int height,
-	       int start_angle, int delta_angle)
+nelma_draw_arc(hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+	       Angle start_angle, Angle delta_angle)
 {
-	int             sa, ea;
+	Angle sa, ea;
 
 	/*
 	 * in gdImageArc, 0 degrees is to the right and +90 degrees is down
@@ -970,14 +967,8 @@ nelma_draw_arc(hidGC gc, int cx, int cy, int width, int height,
 	 * make sure we start between 0 and 360 otherwise gd does strange
 	 * things
 	 */
-	while (sa < 0) {
-		sa += 360;
-		ea += 360;
-	}
-	while (sa >= 360) {
-		sa -= 360;
-		ea -= 360;
-	}
+        sa = NormalizeAngle (sa);
+        ea = NormalizeAngle (ea);
 
 #if 0
 	printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
@@ -994,7 +985,7 @@ nelma_draw_arc(hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-nelma_fill_circle(hidGC gc, int cx, int cy, int radius)
+nelma_fill_circle(hidGC gc, Coord cx, Coord cy, Coord radius)
 {
 	use_gc(gc);
 
@@ -1006,7 +997,7 @@ nelma_fill_circle(hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-nelma_fill_polygon(hidGC gc, int n_coords, int *x, int *y)
+nelma_fill_polygon(hidGC gc, int n_coords, Coord *x, Coord *y)
 {
 	int             i;
 	gdPoint        *points;

commit ec8937d84ef409007438d78f8d9b6b8bd1440119
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit png HID

diff --git a/src/hid/png/png.c b/src/hid/png/png.c
index 583b165..61437a0 100644
--- a/src/hid/png/png.c
+++ b/src/hid/png/png.c
@@ -64,8 +64,8 @@ static void *brush_cache = NULL;
 
 static double bloat = 0;
 static double scale = 1;
-static int x_shift = 0;
-static int y_shift = 0;
+static Coord x_shift = 0;
+static Coord y_shift = 0;
 static int show_solder_side;
 #define SCALE(w)   ((int)((w)/scale + 0.5))
 #define SCALE_X(x) ((int)(((x) - x_shift)/scale))
@@ -77,7 +77,7 @@ static int show_solder_side;
 #define NOT_EDGE_Y(y) ((y) != 0 && (y) != PCB->MaxHeight)
 #define NOT_EDGE(x,y) (NOT_EDGE_X(x) || NOT_EDGE_Y(y))
 
-static void png_fill_circle (hidGC gc, int cx, int cy, int radius);
+static void png_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
 
 /* The result of a failed gdImageColorAllocate() call */
 #define BADC -1
@@ -319,26 +319,14 @@ static int in_mono, as_shown;
 static void
 parse_bloat (const char *str)
 {
-  double val;
-  char suf[10];
-  bloat = 0.0;
+  UnitList extra_units = {
+    { "pix", scale, 0 },
+    { "px", scale, 0 },
+    { "", 0, 0 }
+  };
   if (str == NULL)
     return;
-  suf[0] = 0;
-  sscanf (str, "%lf %s", &val, suf);
-  if (strcmp (suf, "in") == 0)
-    bloat = INCH_TO_COORD(val);
-  else if (strcmp (suf, "mil") == 0)
-    bloat = MIL_TO_COORD(val);
-  else if (strcmp (suf, "mm") == 0)
-    bloat = MM_TO_COORD(val);
-  else if (strcmp (suf, "um") == 0)
-    bloat = MM_TO_COORD(val) / 1000.0;
-  else if (strcmp (suf, "pix") == 0
-	   || strcmp (suf, "px") == 0)
-    bloat = val * scale;
-  else
-    bloat = val;
+  bloat = GetValueEx (str, NULL, NULL, extra_units, "");
 }
 
 void
@@ -1192,7 +1180,7 @@ png_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-png_set_line_width (hidGC gc, int width)
+png_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -1318,7 +1306,7 @@ use_gc (hidGC gc)
 }
 
 static void
-png_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+png_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   gdImageRectangle (im,
@@ -1327,7 +1315,7 @@ png_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-png_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+png_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   gdImageSetThickness (im, 0);
@@ -1335,13 +1323,13 @@ png_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
 
   if (x1 > x2)
     {
-      int t = x1;
+      Coord t = x1;
       x2 = x2;
       x2 = t;
     }
   if (y1 > y2)
     {
-      int t = y1;
+      Coord t = y1;
       y2 = y2;
       y2 = t;
     }
@@ -1355,11 +1343,11 @@ png_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-png_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+png_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   if (x1 == x2 && y1 == y2)
     {
-      int w = gc->width / 2;
+      Coord w = gc->width / 2;
       if (gc->cap != Square_Cap)
 	png_fill_circle (gc, x1, y1, w);
       else
@@ -1418,19 +1406,18 @@ png_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-png_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-	      int start_angle, int delta_angle)
+png_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+	      Angle start_angle, Angle delta_angle)
 {
-  int sa, ea;
+  Angle sa, ea;
 
   /*
    * zero angle arcs need special handling as gd will output either
    * nothing at all or a full circle when passed delta angle of 0 or 360.
    */
   if (delta_angle == 0) {
-    double r = width;
-    int x = (int) (r * cos (start_angle * M_PI / 180));
-    int y = (int) (r * sin (start_angle * M_PI / 180));
+    Coord x = (width * cos (start_angle * M_PI / 180));
+    Coord y = (width * sin (start_angle * M_PI / 180));
     x = cx - x;
     y = cy + y;
     png_fill_circle (gc, x, y, gc->width / 2);
@@ -1459,22 +1446,14 @@ png_draw_arc (hidGC gc, int cx, int cy, int width, int height,
       ea = start_angle;
     }
 
-  have_outline |= doing_outline;
-
   /* 
    * make sure we start between 0 and 360 otherwise gd does
    * strange things
    */
-  while (sa < 0)
-    {
-      sa += 360;
-      ea += 360;
-    }
-  while (sa >= 360)
-    {
-      sa -= 360;
-      ea -= 360;
-    }
+  sa = NormalizeAngle (sa);
+  ea = NormalizeAngle (ea);
+
+  have_outline |= doing_outline;
 
 #if 0
   printf ("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
@@ -1491,9 +1470,9 @@ png_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-png_fill_circle (hidGC gc, int cx, int cy, int radius)
+png_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
-  int my_bloat;
+  Coord my_bloat;
 
   use_gc (gc);
 
@@ -1513,7 +1492,7 @@ png_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-png_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+png_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   int i;
   gdPoint *points;

commit be98cd59b2fb3e027c2b9f441603dc6d799899f0
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit gcode HID

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index 2a3cff6..07e3d35 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -171,7 +171,7 @@ HID_Attribute gcode_attribute_list[] = {
 #define HA_drilldepth 5
 
   {"measurement-unit", "Measurement unit",
-   HID_Enum, 0, 0, {0, 0, 0}, units, 0},
+   HID_Unit, 0, 0, {-1, 0, 0}, units, 0},
 #define HA_unit 6
 
 };
@@ -243,6 +243,16 @@ static HID_Attribute *
 gcode_get_export_options (int *n)
 {
   static char *last_made_filename = 0;
+  static int last_unit_value = -1;
+
+  if (gcode_attribute_list[HA_unit].default_val.int_value == last_unit_value)
+    {
+      if (Settings.grid_unit)
+        gcode_attribute_list[HA_unit].default_val.int_value = Settings.grid_unit->index;
+      else
+        gcode_attribute_list[HA_unit].default_val.int_value = get_unit_struct ("mil")->index;
+      last_unit_value = gcode_attribute_list[HA_unit].default_val.int_value;
+    }
 
   if (PCB)
     {
@@ -373,6 +383,7 @@ gcode_do_export (HID_Attr_Val * options)
   int save_ons[MAX_LAYER + 2];
   int i, idx;
   time_t t;
+  const Unit *unit;
   double scale = 0, d = 0;
   int r, c, v, p, metric;
   char *filename;
@@ -412,24 +423,11 @@ gcode_do_export (HID_Attr_Val * options)
       fprintf (stderr, "ERROR:  dpi may not be < 0\n");
       return;
     }
-  switch (options[HA_unit].int_value)
-    {
-    case 0:
-      scale = 1.0;		/* mm */
-      metric = 1;
-      break;
-    case 1:
-      scale = 0.001;		/* mil */
-      metric = 0;
-      break;
-    case 2:
-      scale = 0.001;		/* um */
-      metric = 1;
-      break;
-    default:
-      scale = 1.0;		/* inch */
-      metric = 0;
-    }
+  unit = &(get_unit_list() [options[HA_unit].int_value]);
+  metric = (unit->family == METRIC);
+  scale = metric ? 1.0 / coord_to_unit (unit, MM_TO_COORD (1.0))
+                 : 1.0 / coord_to_unit (unit, INCH_TO_COORD (1.0));
+
   gcode_cutdepth = options[HA_cutdepth].real_value * scale;
   gcode_drilldepth = options[HA_drilldepth].real_value * scale;
   gcode_safeZ = options[HA_safeZ].real_value * scale;
@@ -707,7 +705,7 @@ gcode_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-gcode_set_line_width (hidGC gc, int width)
+gcode_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -843,7 +841,7 @@ use_gc (hidGC gc)
 }
 
 static void
-gcode_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+gcode_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   gdImageRectangle (gcode_im,
@@ -855,7 +853,7 @@ gcode_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-gcode_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+gcode_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   gdImageSetThickness (gcode_im, 0);
@@ -869,11 +867,11 @@ gcode_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-gcode_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+gcode_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   if (x1 == x2 && y1 == y2)
     {
-      int w = gc->width / 2;
+      Coord w = gc->width / 2;
       gcode_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w);
       return;
     }
@@ -886,10 +884,10 @@ gcode_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-gcode_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-		int start_angle, int delta_angle)
+gcode_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+		Angle start_angle, Angle delta_angle)
 {
-  int sa, ea;
+  Angle sa, ea;
 
   /*
    * in gdImageArc, 0 degrees is to the right and +90 degrees is down
@@ -912,16 +910,8 @@ gcode_draw_arc (hidGC gc, int cx, int cy, int width, int height,
    * make sure we start between 0 and 360 otherwise gd does strange
    * things
    */
-  while (sa < 0)
-    {
-      sa += 360;
-      ea += 360;
-    }
-  while (sa >= 360)
-    {
-      sa -= 360;
-      ea -= 360;
-    }
+  sa = NormalizeAngle (sa);
+  ea = NormalizeAngle (ea);
 
 #if 0
   printf ("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
@@ -940,7 +930,7 @@ gcode_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-gcode_fill_circle (hidGC gc, int cx, int cy, int radius)
+gcode_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   use_gc (gc);
 
@@ -969,7 +959,7 @@ gcode_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-gcode_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+gcode_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   int i;
   gdPoint *points;

commit 48cea1ad5e8b183d769d762ce98498ae3d1f907c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit ps.c

diff --git a/src/hid/ps/ps.c b/src/hid/ps/ps.c
index 307a89a..fa0835f 100644
--- a/src/hid/ps/ps.c
+++ b/src/hid/ps/ps.c
@@ -41,7 +41,7 @@ typedef struct hid_gc_struct
 {
   HID *me_pointer;
   EndCapStyle cap;
-  int width;
+  Coord width;
   unsigned char r, g, b;
   int erase;
   int faded;
@@ -63,8 +63,8 @@ static const char *medias[] = {
 typedef struct
 {
   char *name;
-  BDimension Width, Height;
-  BDimension MarginX, MarginY;
+  Coord Width, Height;
+  Coord MarginX, MarginY;
 } MediaType, *MediaTypePtr;
 
 /*
@@ -211,12 +211,12 @@ static struct {
 
   FILE *f;
   int pagecount;
-  BDimension linewidth;
+  Coord linewidth;
   bool print_group[MAX_LAYER];
   bool print_layer[MAX_LAYER];
   double fade_ratio;
   bool multi_file;
-  BDimension media_width, media_height, ps_width, ps_height;
+  Coord media_width, media_height, ps_width, ps_height;
 
   const char *filename;
   bool drill_helper;
@@ -227,7 +227,7 @@ static struct {
   bool automirror;
   bool incolor;
   bool doing_toc;
-  BDimension bloat;
+  Coord bloat;
   bool invert;
   int media_idx;
   bool drillcopper;
@@ -605,11 +605,11 @@ ps_parse_arguments (int *argc, char ***argv)
 }
 
 static void
-corner (FILE *fh, BDimension x, BDimension y, BDimension dx, BDimension dy)
+corner (FILE *fh, Coord x, Coord y, Coord dx, Coord dy)
 {
-  BDimension len   = MIL_TO_COORD (2000);
-  BDimension len2  = MIL_TO_COORD (200);
-  BDimension thick = 0;
+  Coord len   = MIL_TO_COORD (2000);
+  Coord len2  = MIL_TO_COORD (200);
+  Coord thick = 0;
   /*
    * Originally 'thick' used thicker lines.  Currently is uses
    * Postscript's "device thin" line - i.e. zero width means one
@@ -775,8 +775,8 @@ ps_set_layer (const char *name, int group, int empty)
        * If users don't want to make smaller boards, or use fewer drill
        * sizes, they can always ignore this sheet. */
       if (SL_TYPE (idx) == SL_FAB) {
-        BDimension natural = boffset - MIL_TO_COORD(500) - PCB->MaxHeight / 2;
-	BDimension needed  = PrintFab_overhang ();
+        Coord natural = boffset - MIL_TO_COORD(500) - PCB->MaxHeight / 2;
+	Coord needed  = PrintFab_overhang ();
         pcb_fprintf (global.f, "%% PrintFab overhang natural %mi, needed %mi\n", natural, needed);
 	if (needed > natural)
 	  pcb_fprintf (global.f, "0 %mi translate\n", needed - natural);
@@ -827,7 +827,7 @@ ps_set_layer (const char *name, int group, int empty)
       if (global.drill_helper)
 	pcb_fprintf (global.f,
                     "/dh { gsave %mi setlinewidth 0 gray %mi 0 360 arc stroke grestore} bind def\n",
-                    (BDimension) MIN_PINORVIAHOLE, (BDimension) (MIN_PINORVIAHOLE * 3 / 2));
+                    (Coord) MIN_PINORVIAHOLE, (Coord) (MIN_PINORVIAHOLE * 3 / 2));
     }
 #if 0
   /* Try to outsmart ps2pdf's heuristics for page rotation, by putting
@@ -907,7 +907,7 @@ ps_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-ps_set_line_width (hidGC gc, int width)
+ps_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -927,8 +927,8 @@ ps_set_draw_faded (hidGC gc, int faded)
 static void
 use_gc (hidGC gc)
 {
-  static BDimension lastcap = -1;
-  static BDimension lastcolor = -1;
+  static int lastcap = -1;
+  static int lastcolor = -1;
 
   if (gc == NULL)
     {
@@ -993,17 +993,17 @@ use_gc (hidGC gc)
 }
 
 static void
-ps_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ps_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   pcb_fprintf (global.f, "%mi %mi %mi %mi dr\n", x1, y1, x2, y2);
 }
 
-static void ps_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
-static void ps_fill_circle (hidGC gc, int cx, int cy, int radius);
+static void ps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void ps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
 
 static void
-ps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+ps_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
 #if 0
   /* If you're etching your own paste mask, this will reduce the
@@ -1012,7 +1012,7 @@ ps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
   if (is_paste && gc->width > 2500 && gc->cap == Square_Cap
       && (x1 == x2 || y1 == y2))
     {
-      int t, w;
+      Coord t, w;
       if (x1 > x2)
 	{ t = x1; x1 = x2; x2 = t; }
       if (y1 > y2)
@@ -1024,7 +1024,7 @@ ps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 #endif
   if (x1 == x2 && y1 == y2)
     {
-      int w = gc->width / 2;
+      Coord w = gc->width / 2;
       if (gc->cap == Square_Cap)
 	ps_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w);
       else
@@ -1036,10 +1036,10 @@ ps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-ps_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-	     int start_angle, int delta_angle)
+ps_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+	     Angle start_angle, Angle delta_angle)
 {
-  int sa, ea;
+  Angle sa, ea;
   if (delta_angle > 0)
     {
       sa = start_angle;
@@ -1055,13 +1055,13 @@ ps_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 	  cx, cy, width, height, start_angle, delta_angle, sa, ea);
 #endif
   use_gc (gc);
-  pcb_fprintf (global.f, "%d %d %mi %mi %mi %mi %g a\n",
+  pcb_fprintf (global.f, "%ma %ma %mi %mi %mi %mi %g a\n",
                sa, ea, -width, height, cx, cy,
                (double) (global.linewidth + 2 * global.bloat) / (double) width);
 }
 
 static void
-ps_fill_circle (hidGC gc, int cx, int cy, int radius)
+ps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   use_gc (gc);
   if (!gc->erase || !global.is_copper || global.drillcopper)
@@ -1075,7 +1075,7 @@ ps_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-ps_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+ps_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   int i;
   char *op = "moveto";
@@ -1118,18 +1118,18 @@ ps_fill_pcb_polygon (hidGC gc, PolygonType * poly, const BoxType * clip_box)
 }
 
 static void
-ps_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+ps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   if (x1 > x2)
     {
-      int t = x1;
+      Coord t = x1;
       x1 = x2;
       x2 = t;
     }
   if (y1 > y2)
     {
-      int t = y1;
+      Coord t = y1;
       y1 = y2;
       y2 = t;
     }

commit 736c3f2987c8d394140446455913c25a9d5b90b3
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit eps.c

diff --git a/src/hid/ps/eps.c b/src/hid/ps/eps.c
index 8916507..903270e 100644
--- a/src/hid/ps/eps.c
+++ b/src/hid/ps/eps.c
@@ -42,14 +42,14 @@ static void eps_destroy_gc (hidGC gc);
 static void eps_use_mask (int use_it);
 static void eps_set_color (hidGC gc, const char *name);
 static void eps_set_line_cap (hidGC gc, EndCapStyle style);
-static void eps_set_line_width (hidGC gc, int width);
+static void eps_set_line_width (hidGC gc, Coord width);
 static void eps_set_draw_xor (hidGC gc, int _xor);
-static void eps_draw_rect (hidGC gc, int x1, int y1, int x2, int y2);
-static void eps_draw_line (hidGC gc, int x1, int y1, int x2, int y2);
-static void eps_draw_arc (hidGC gc, int cx, int cy, int width, int height, int start_angle, int delta_angle);
-static void eps_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
-static void eps_fill_circle (hidGC gc, int cx, int cy, int radius);
-static void eps_fill_polygon (hidGC gc, int n_coords, int *x, int *y);
+static void eps_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void eps_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void eps_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle);
+static void eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
+static void eps_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y);
 static void eps_calibrate (double xval, double yval);
 static void eps_set_crosshair (int x, int y, int action);
 /*----------------------------------------------------------------------------*/
@@ -57,7 +57,7 @@ static void eps_set_crosshair (int x, int y, int action);
 typedef struct hid_gc_struct
 {
   EndCapStyle cap;
-  int width;
+  Coord width;
   int color;
   int erase;
 } hid_gc_struct;
@@ -65,7 +65,7 @@ typedef struct hid_gc_struct
 static HID eps_hid;
 
 static FILE *f = 0;
-static int linewidth = -1;
+static Coord linewidth = -1;
 static int lastgroup = -1;
 static int lastcap = -1;
 static int lastcolor = -1;
@@ -231,8 +231,8 @@ eps_hid_export_to_file (FILE * the_file, HID_Attr_Val * options)
 
   in_mono = options[HA_mono].int_value;
 
-#define pcb2em(x) (BDimension)((x) * 72.0 * options[HA_scale].real_value + INCH_TO_COORD(1))
-  pcb_fprintf (f, "%%%%BoundingBox: 0 0 %mi %mi\n",
+#define pcb2em(x) 1 + COORD_TO_INCH (x) * 72.0 * options[HA_scale].real_value
+  fprintf (f, "%%%%BoundingBox: 0 0 %f %f\n",
 	   pcb2em (bounds->X2 - bounds->X1),
 	   pcb2em (bounds->Y2 - bounds->Y1));
 #undef pcb2em
@@ -252,7 +252,7 @@ eps_hid_export_to_file (FILE * the_file, HID_Attr_Val * options)
   linewidth = -1;
   lastcap = -1;
   lastcolor = -1;
-#define Q (BDimension) MIL_TO_COORD(10)
+#define Q (Coord) MIL_TO_COORD(10)
   pcb_fprintf (f,
 	   "/nclip { %mi %mi moveto %mi %mi lineto %mi %mi lineto %mi %mi lineto %mi %mi lineto eoclip newpath } def\n",
 	   bounds->X1 - Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y2 + Q,
@@ -472,7 +472,7 @@ eps_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-eps_set_line_width (hidGC gc, int width)
+eps_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -517,20 +517,20 @@ use_gc (hidGC gc)
     }
 }
 
-static void eps_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
-static void eps_fill_circle (hidGC gc, int cx, int cy, int radius);
+static void eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
 
 static void
-eps_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+eps_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   pcb_fprintf (f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2);
 }
 
 static void
-eps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+eps_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
-  int w = gc->width / 2;
+  Coord w = gc->width / 2;
   if (x1 == x2 && y1 == y2)
     {
       if (gc->cap == Square_Cap)
@@ -546,8 +546,8 @@ eps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
       double dx = w * sin (ang);
       double dy = -w * cos (ang);
       double deg = ang * 180.0 / M_PI;
-      int vx1 = x1 + dx;
-      int vy1 = y1 + dy;
+      Coord vx1 = x1 + dx;
+      Coord vy1 = y1 + dy;
 
       pcb_fprintf (f, "%mi %mi moveto ", vx1, vy1);
       pcb_fprintf (f, "%mi %mi %mi %g %g arc\n", x2, y2, w, deg - 90, deg + 90);
@@ -560,10 +560,10 @@ eps_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-eps_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-	      int start_angle, int delta_angle)
+eps_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+	      Angle start_angle, Angle delta_angle)
 {
-  int sa, ea;
+  Angle sa, ea;
   if (delta_angle > 0)
     {
       sa = start_angle;
@@ -579,19 +579,19 @@ eps_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 	  cx, cy, width, height, start_angle, delta_angle, sa, ea);
 #endif
   use_gc (gc);
-  pcb_fprintf (f, "%d %d %mi %mi %mi %mi %g a\n",
+  pcb_fprintf (f, "%ma %ma %mi %mi %mi %mi %g a\n",
 	   sa, ea, -width, height, cx, cy, (double) linewidth / width);
 }
 
 static void
-eps_fill_circle (hidGC gc, int cx, int cy, int radius)
+eps_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   use_gc (gc);
   pcb_fprintf (f, "%mi %mi %mi %s\n", cx, cy, radius, gc->erase ? "cc" : "c");
 }
 
 static void
-eps_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+eps_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   int i;
   char *op = "moveto";
@@ -605,7 +605,7 @@ eps_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 }
 
 static void
-eps_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+eps_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   use_gc (gc);
   pcb_fprintf (f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2);

commit 4dcbf39a2531705a2f8b2e40c52e3bbdebcae8da
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit gerber HID

diff --git a/src/hid/gerber/gerber.c b/src/hid/gerber/gerber.c
index 44fbe40..8829527 100644
--- a/src/hid/gerber/gerber.c
+++ b/src/hid/gerber/gerber.c
@@ -55,30 +55,30 @@ static void gerber_destroy_gc (hidGC gc);
 static void gerber_use_mask (int use_it);
 static void gerber_set_color (hidGC gc, const char *name);
 static void gerber_set_line_cap (hidGC gc, EndCapStyle style);
-static void gerber_set_line_width (hidGC gc, int width);
+static void gerber_set_line_width (hidGC gc, Coord width);
 static void gerber_set_draw_xor (hidGC gc, int _xor);
-static void gerber_draw_line (hidGC gc, int x1, int y1, int x2, int y2);
-static void gerber_draw_arc (hidGC gc, int cx, int cy, int width, int height, int start_angle, int delta_angle);
-static void gerber_draw_rect (hidGC gc, int x1, int y1, int x2, int y2);
-static void gerber_fill_circle (hidGC gc, int cx, int cy, int radius);
-static void gerber_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
+static void gerber_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void gerber_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height, Angle start_angle, Angle delta_angle);
+static void gerber_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
+static void gerber_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius);
+static void gerber_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2);
 static void gerber_calibrate (double xval, double yval);
 static void gerber_set_crosshair (int x, int y, int action);
-static void gerber_fill_polygon (hidGC gc, int n_coords, int *x, int *y);
+static void gerber_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y);
 
 /*----------------------------------------------------------------------------*/
 /* Utility routines                                                           */
 /*----------------------------------------------------------------------------*/
 
 /* These are for films */
-#define gerberX(pcb, x) ((BDimension) (x))
-#define gerberY(pcb, y) ((BDimension) ((pcb)->MaxHeight - (y)))
-#define gerberXOffset(pcb, x) ((BDimension) (x))
-#define gerberYOffset(pcb, y) ((BDimension) (-(y)))
+#define gerberX(pcb, x) ((Coord) (x))
+#define gerberY(pcb, y) ((Coord) ((pcb)->MaxHeight - (y)))
+#define gerberXOffset(pcb, x) ((Coord) (x))
+#define gerberYOffset(pcb, y) ((Coord) (-(y)))
 
 /* These are for drills (printed as mils but are really 1/10th mil) */
-#define gerberDrX(pcb, x) ((BDimension) (x) * 10)
-#define gerberDrY(pcb, y) ((BDimension) ((pcb)->MaxHeight - (y)) * 10)
+#define gerberDrX(pcb, x) ((Coord) (x) * 10)
+#define gerberDrY(pcb, y) ((Coord) ((pcb)->MaxHeight - (y)) * 10)
 
 /*----------------------------------------------------------------------------*/
 /* Private data structures                                                    */
@@ -112,7 +112,7 @@ typedef enum ApertureShape ApertureShape;
 typedef struct aperture
 {
   int dCode;			/* The RS-274X D code */
-  BDimension width;		/* Size in pcb units */
+  Coord width;		/* Size in pcb units */
   ApertureShape shape;		/* ROUND/SQUARE etc */
   struct aperture *next;
 }
@@ -131,9 +131,9 @@ static int layer_list_idx;
 
 typedef struct
 {
-  int diam;
-  int x;
-  int y;
+  Coord diam;
+  Coord x;
+  Coord y;
 } PendingDrills;
 PendingDrills *pending_drills = NULL;
 int n_pending_drills = 0, max_pending_drills = 0;
@@ -183,7 +183,7 @@ static void resetApertures()
 
 /* Create and add a new aperture to the list */
 static Aperture *
-addAperture (ApertureList *list, BDimension width, ApertureShape shape)
+addAperture (ApertureList *list, Coord width, ApertureShape shape)
 {
   static int aperture_count;
 
@@ -205,7 +205,7 @@ addAperture (ApertureList *list, BDimension width, ApertureShape shape)
 /* Fetch an aperture from the list with the specified
  *  width/shape, creating a new one if none exists */
 static Aperture *
-findAperture (ApertureList *list, BDimension width, ApertureShape shape)
+findAperture (ApertureList *list, Coord width, ApertureShape shape)
 {
   Aperture *search;
 
@@ -237,7 +237,7 @@ fprintAperture (FILE *f, Aperture *aptr)
     case OCTAGON:
       pcb_fprintf (f, "%%AMOCT%d*5,0,8,0,0,%.4mi,22.5*%%\r\n"
 	       "%%ADD%dOCT%d*%%\r\n", aptr->dCode,
-	       (BDimension) ((double) aptr->width / COS_22_5_DEGREE), aptr->dCode,
+	       (Coord) ((double) aptr->width / COS_22_5_DEGREE), aptr->dCode,
 	       aptr->dCode);
       break;
 #if 0
@@ -877,7 +877,7 @@ gerber_set_line_cap (hidGC gc, EndCapStyle style)
 }
 
 static void
-gerber_set_line_width (hidGC gc, int width)
+gerber_set_line_width (hidGC gc, Coord width)
 {
   gc->width = width;
 }
@@ -957,7 +957,7 @@ use_gc (hidGC gc, int radius)
 }
 
 static void
-gerber_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+gerber_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   gerber_draw_line (gc, x1, y1, x1, y2);
   gerber_draw_line (gc, x1, y1, x2, y1);
@@ -966,13 +966,13 @@ gerber_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-gerber_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+gerber_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
   bool m = false;
 
   if (x1 != x2 && y1 != y2 && gc->cap == Square_Cap)
     {
-      int x[5], y[5];
+      Coord x[5], y[5];
       double tx, ty, theta;
 
       theta = atan2 (y2-y1, x2-x1);
@@ -1031,8 +1031,8 @@ gerber_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 }
 
 static void
-gerber_draw_arc (hidGC gc, int cx, int cy, int width, int height,
-		 int start_angle, int delta_angle)
+gerber_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
+		 Angle start_angle, Angle delta_angle)
 {
   bool m = false;
   double arcStartX, arcStopX, arcStartY, arcStopY;
@@ -1056,10 +1056,10 @@ gerber_draw_arc (hidGC gc, int cx, int cy, int width, int height,
   if (width != height)
     {
       double step, angle;
-      int max = width > height ? width : height;
-      int minr = max - gc->width / 10;
+      Coord max = width > height ? width : height;
+      Coord minr = max - gc->width / 10;
       int nsteps;
-      int x0, y0, x1, y1;
+      Coord x0, y0, x1, y1;
 
       if (minr >= max)
 	minr = max - 1;
@@ -1112,7 +1112,7 @@ gerber_draw_arc (hidGC gc, int cx, int cy, int width, int height,
 }
 
 static void
-gerber_fill_circle (hidGC gc, int cx, int cy, int radius)
+gerber_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
 {
   if (radius <= 0)
     return;
@@ -1152,12 +1152,12 @@ gerber_fill_circle (hidGC gc, int cx, int cy, int radius)
 }
 
 static void
-gerber_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+gerber_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
 {
   bool m = false;
   int i;
   int firstTime = 1;
-  LocationType startX = 0, startY = 0;
+  Coord startX = 0, startY = 0;
 
   if (is_mask && current_mask == HID_MASK_BEFORE)
     return;
@@ -1210,10 +1210,10 @@ gerber_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 }
 
 static void
-gerber_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+gerber_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
 {
-  int x[5];
-  int y[5];
+  Coord x[5];
+  Coord y[5];
   x[0] = x[4] = x1;
   y[0] = y[4] = y1;
   x[1] = x1;

commit da403312d4c45b3d286b1b836affe2d002cfba7c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Implement new unit selector in BOM HID, audit bom.c

diff --git a/src/hid/bom/bom.c b/src/hid/bom/bom.c
index e49c157..70b0567 100644
--- a/src/hid/bom/bom.c
+++ b/src/hid/bom/bom.c
@@ -33,9 +33,12 @@ static HID_Attribute bom_options[] = {
   {"xyfile", "XY output file",
    HID_String, 0, 0, {0, 0, 0}, 0, 0},
 #define HA_xyfile 1
-  {"xy-in-mm", "XY dimensions in mm instead of mils",
+  {"xy-unit", "XY units",
+   HID_Unit, 0, 0, {-1, 0, 0}, NULL, 0},
+#define HA_unit 2
+  {"xy-in-mm", ATTR_UNDOCUMENTED,
    HID_Boolean, 0, 0, {0, 0, 0}, 0, 0},
-#define HA_xymm 2
+#define HA_xymm 3
 };
 
 #define NUM_OPTIONS (sizeof(bom_options)/sizeof(bom_options[0]))
@@ -44,7 +47,7 @@ static HID_Attr_Val bom_values[NUM_OPTIONS];
 
 static const char *bom_filename;
 static const char *xy_filename;
-static int xy_dim_type;
+static const Unit *xy_unit;
 
 typedef struct _StringList
 {
@@ -64,11 +67,21 @@ typedef struct _BomList
 static HID_Attribute *
 bom_get_export_options (int *n)
 {
-   static char *last_bom_filename = 0;
-   static char *last_xy_filename = 0;
+  static char *last_bom_filename = 0;
+  static char *last_xy_filename = 0;
+  static int last_unit_value = -1;
+
+  if (bom_options[HA_unit].default_val.int_value == last_unit_value)
+    {
+      if (Settings.grid_unit)
+        bom_options[HA_unit].default_val.int_value = Settings.grid_unit->index;
+      else
+        bom_options[HA_unit].default_val.int_value = get_unit_struct ("mil")->index;
+      last_unit_value = bom_options[HA_unit].default_val.int_value;
+    }
   if (PCB) {
-	derive_default_filename(PCB->Filename, &bom_options[HA_bomfile], ".bom", &last_bom_filename);
-	derive_default_filename(PCB->Filename, &bom_options[HA_xyfile ], ".xy" , &last_xy_filename );
+    derive_default_filename(PCB->Filename, &bom_options[HA_bomfile], ".bom", &last_bom_filename);
+    derive_default_filename(PCB->Filename, &bom_options[HA_xyfile ], ".xy" , &last_xy_filename );
   }
 
   if (n)
@@ -275,7 +288,7 @@ static int
 PrintBOM (void)
 {
   char utcTime[64];
-  BDimension x, y;
+  Coord x, y;
   double theta = 0.0;
   double sumx, sumy;
   double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0;
@@ -309,11 +322,7 @@ PrintBOM (void)
   fprintf (fp, "# Author: %s\n", pcb_author ());
   fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name));
   fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n");
-  if (xy_dim_type) {
-    fprintf (fp, "# X,Y in mm.  rotation in degrees.\n");
-  } else {
-    fprintf (fp, "# X,Y in mils.  rotation in degrees.\n");
-  }
+  fprintf (fp, "# X,Y in %s.  rotation in degrees.\n", xy_unit->in_suffix);
   fprintf (fp, "# --------------------------------------------\n");
 
   /*
@@ -451,11 +460,9 @@ PrintBOM (void)
 	value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element)));
 
  	y = PCB->MaxHeight - y;
-	pcb_fprintf (fp, "%s,\"%s\",\"%s\",%.2m*,%.2m*,%g,%s\n",
-		 name, descr, value,
-		 (xy_dim_type ? "mm" : "mil"), x,
-		 (xy_dim_type ? "mm" : "mil"), y,
-		 theta, FRONT (element) == 1 ? "top" : "bottom");
+	pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%mS,%.2mS,%g,%s\n",
+		     xy_unit->allow, name, descr, value, x, y,
+		     theta, FRONT (element) == 1 ? "top" : "bottom");
 	free (name);
 	free (descr);
 	free (value);
@@ -512,7 +519,11 @@ bom_do_export (HID_Attr_Val * options)
   if (!xy_filename)
     xy_filename = "pcb-out.xy";
 
-  xy_dim_type = options[HA_xymm].int_value;
+  if (options[HA_unit].int_value == -1)
+    xy_unit = options[HA_xymm].int_value ? get_unit_struct ("mm")
+                                         : get_unit_struct ("mil");
+  else
+    xy_unit = &get_unit_list ()[options[HA_unit].int_value];
   PrintBOM ();
 }
 

commit 4f0ce31aecdadc65d79fa4838b32d8312086c64c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce HID_Unit option type

diff --git a/src/hid.h b/src/hid.h
index 6bc89c5..505b4f2 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -157,13 +157,14 @@ extern "C"
   typedef struct
   {
     int int_value;
-    char *str_value;
+    const char *str_value;
     double real_value;
   } HID_Attr_Val;
 
   enum hids
     { HID_Label, HID_Integer, HID_Real, HID_String,
-      HID_Boolean, HID_Enum, HID_Mixed, HID_Path
+      HID_Boolean, HID_Enum, HID_Mixed, HID_Path,
+      HID_Unit
     };
 
   typedef struct
diff --git a/src/hid/bom/bom.c b/src/hid/bom/bom.c
index 89bd6eb..e49c157 100644
--- a/src/hid/bom/bom.c
+++ b/src/hid/bom/bom.c
@@ -42,8 +42,8 @@ static HID_Attribute bom_options[] = {
 
 static HID_Attr_Val bom_values[NUM_OPTIONS];
 
-static char *bom_filename;
-static char *xy_filename;
+static const char *bom_filename;
+static const char *xy_filename;
 static int xy_dim_type;
 
 typedef struct _StringList
diff --git a/src/hid/common/hidinit.c b/src/hid/common/hidinit.c
index 58d1880..120dffd 100644
--- a/src/hid/common/hidinit.c
+++ b/src/hid/common/hidinit.c
@@ -32,6 +32,7 @@
 #include "error.h"
 #include "global.h"
 #include "misc.h"
+#include "pcb-printf.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -272,7 +273,7 @@ hid_parse_command_line (int *argc, char ***argv)
 	    break;
 	  case HID_String:
 	    if (a->value)
-	      *(char **) a->value = a->default_val.str_value;
+	      *(const char **) a->value = a->default_val.str_value;
 	    break;
 	  case HID_Enum:
 	    if (a->value)
@@ -281,6 +282,10 @@ hid_parse_command_line (int *argc, char ***argv)
 	  case HID_Mixed:
 	    if (a->value) {
               *(HID_Attr_Val *) a->value = a->default_val;
+	  case HID_Unit:
+	    if (a->value)
+	      *(int *) a->value = a->default_val.int_value;
+	    break;
            }
            break;
 	  default:
@@ -302,6 +307,7 @@ hid_parse_command_line (int *argc, char ***argv)
 	    {
 	      HID_Attribute *a = ha->attributes + i;
 	      char *ep;
+              const Unit *unit;
 	      switch (ha->attributes[i].type)
 		{
 		case HID_Label:
@@ -367,6 +373,20 @@ hid_parse_command_line (int *argc, char ***argv)
 		  (*argc)--;
 		  (*argv)++;
 		  break;
+		case HID_Unit:
+                  unit = get_unit_struct ((*argv)[1]);
+                  if (unit == NULL)
+		    {
+		      fprintf (stderr,
+			       "ERROR:  unit \"%s\" is unknown to pcb (option --%s)\n",
+			       (*argv)[1], a->name);
+		      exit (1);
+		    }
+		  a->default_val.int_value = unit->index;
+		  a->default_val.str_value = unit->suffix;
+		  (*argc)--;
+		  (*argv)++;
+		  break;
 		}
 	      (*argc)--;
 	      (*argv)++;
@@ -441,7 +461,7 @@ hid_save_settings (int locally)
     {
       for (i = 0; i < ha->n; i++)
 	{
-	  char *str;
+	  const char *str;
 	  HID_Attribute *a = ha->attributes + i;
 
 	  if (a->hash == attr_hash (a))
@@ -468,9 +488,7 @@ hid_save_settings (int locally)
 	    case HID_String:
 	    case HID_Path:
 	      str = a->value ? *(char **)a->value : a->default_val.str_value;
-	      fprintf (f, "%s = %s\n",
-		       a->name,
-		       str ? str : "");
+	      fprintf (f, "%s = %s\n", a->name, str ? str : "");
 	      break;
 	    case HID_Enum:
 	      fprintf (f, "%s = %s\n",
@@ -487,6 +505,11 @@ hid_save_settings (int locally)
                         a->enumerations[value->int_value]);
              }
 	      break;
+	    case HID_Unit:
+	      fprintf (f, "%s = %s\n",
+		       a->name,
+		       get_unit_list()[a->value ? *(int *)a->value : a->default_val.int_value].suffix);
+	      break;
 	    }
 	}
       fprintf (f, "\n");
@@ -498,6 +521,7 @@ hid_save_settings (int locally)
 static void
 hid_set_attribute (char *name, char *value)
 {
+  const Unit *unit;
   HID_AttrNode *ha;
   int i, e, ok;
 
@@ -546,6 +570,18 @@ hid_set_attribute (char *name, char *value)
 	    case HID_Path:
 	      a->default_val.str_value = value;
 	      break;
+	    case HID_Unit:
+              unit = get_unit_struct (value);
+              if (unit == NULL)
+		{
+		  fprintf (stderr,
+		           "ERROR:  unit \"%s\" is unknown to pcb (option --%s)\n",
+			   value, a->name);
+		  exit (1);
+		}
+	      a->default_val.int_value = unit->index;
+	      a->default_val.str_value = unit->suffix;
+	      break;
 	    }
 	}
 }
@@ -703,7 +739,7 @@ derive_default_filename(const char *pcbfile, HID_Attribute *filename_attrib, con
 			buf[bl - 4] = 0;
 		strcat(buf, suffix);
 		if (filename_attrib->default_val.str_value)
-			free(filename_attrib->default_val.str_value);
+			free ((void *) filename_attrib->default_val.str_value);
 		filename_attrib->default_val.str_value = buf;
 	}
 
diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index bae327d..2a3cff6 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -116,7 +116,7 @@ static int gcode_export_group[MAX_LAYER];
 static int gcode_cur_group;
 
 /* Filename prefix that will be used when saving files. */
-static char *gcode_basename = NULL;
+static const char *gcode_basename = NULL;
 
 /* Horizontal DPI (grid points per inch) */
 static int gcode_dpi = -1;
diff --git a/src/hid/gerber/gerber.c b/src/hid/gerber/gerber.c
index 5a4d84c..44fbe40 100644
--- a/src/hid/gerber/gerber.c
+++ b/src/hid/gerber/gerber.c
@@ -488,7 +488,7 @@ assign_file_suffix (char *dest, int idx)
 static void
 gerber_do_export (HID_Attr_Val * options)
 {
-  char *fnbase;
+  const char *fnbase;
   int i;
   static int saved_layer_stack[MAX_LAYER];
   int save_ons[MAX_LAYER + 2];
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 083ce25..1b1e93e 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -311,6 +311,7 @@ ghid_config_init (void)
 	      break;
 
 	    case HID_Enum:
+	    case HID_Unit:
 	      *(int *) a->value = a->default_val.int_value;
 	      break;
 
@@ -530,6 +531,7 @@ parse_optionv (gint * argc, gchar *** argv, gboolean from_cmd_line)
 {
   HID_AttrNode *ha;
   HID_Attribute *a;
+  const Unit *unit;
   gchar *ep;
   gint e, ok, offset;
   gboolean matched = FALSE;
@@ -611,6 +613,20 @@ parse_optionv (gint * argc, gchar *** argv, gboolean from_cmd_line)
 		  (*argc)--;
 		  (*argv)++;
 		  break;
+	        case HID_Unit:
+                  unit = get_unit_struct ((*argv)[1]);
+                  if (unit == NULL)
+		    {
+		      fprintf (stderr,
+		               "ERROR:  unit \"%s\" is unknown to pcb (option --%s)\n",
+			       (*argv)[1], a->name);
+		      exit (1);
+		    }
+	          a->default_val.int_value = unit->index;
+	          a->default_val.str_value = unit->suffix;
+		  (*argc)--;
+		  (*argv)++;
+	          break;
 		}
 	      (*argc)--;
 	      (*argv)++;
diff --git a/src/hid/gtk/gui-dialog-print.c b/src/hid/gtk/gui-dialog-print.c
index 4a2fb85..ee8b282 100644
--- a/src/hid/gtk/gui-dialog-print.c
+++ b/src/hid/gtk/gui-dialog-print.c
@@ -37,6 +37,7 @@
 #endif
 
 #include "gui.h"
+#include "pcb-printf.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -102,7 +103,7 @@ ghid_attribute_dialog (HID_Attribute * attrs,
   GtkWidget *combo;
   GtkWidget *widget;
   GHidPort *out = &ghid_port;
-  int i, j;
+  int i, j, n;
   GtkTooltips *tips;
   int rc = 0;
 
@@ -131,6 +132,7 @@ ghid_attribute_dialog (HID_Attribute * attrs,
    */
   for (j = 0; j < n_attrs; j++)
     {
+      const Unit *unit_list;
       if (attrs[j].help_text == ATTR_UNDOCUMENTED)
 	continue;
       switch (attrs[j].type)
@@ -279,6 +281,38 @@ ghid_attribute_dialog (HID_Attribute * attrs,
 	  gtk_tooltips_set_tip (tips, entry, attrs[j].help_text, NULL);
 	  break;
 
+	case HID_Unit:
+          unit_list = get_unit_list ();
+          n = get_n_units ();
+
+	  hbox = gtk_hbox_new (FALSE, 4);
+	  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+	  /* 
+	   * We have to put the combo_box inside of an event_box in
+	   * order for tooltips to work.
+	   */
+	  widget = gtk_event_box_new ();
+	  gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
+	  gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+	  combo = gtk_combo_box_new_text ();
+	  gtk_container_add (GTK_CONTAINER (widget), combo);
+	  g_signal_connect (G_OBJECT (combo), "changed",
+			    G_CALLBACK (enum_changed_cb),
+			    &(attrs[j].default_val.int_value));
+
+	  /* 
+	   * Iterate through each value and add them to the
+	   * combo box
+	   */
+	  for (i = 0; i < n; ++i)
+	    gtk_combo_box_append_text (GTK_COMBO_BOX (combo),
+					unit_list[i].in_suffix);
+	  gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
+				    attrs[j].default_val.int_value);
+	  widget = gtk_label_new (attrs[j].name);
+	  gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+          break;
 	default:
 	  printf ("%s: unknown type of HID attribute\n", __FUNCTION__);
 	  break;
@@ -351,7 +385,7 @@ ghid_dialog_print (HID *hid)
   for (i = 0; i < n; i++)
     {
       if (results[i].str_value)
-	free (results[i].str_value);
+	free ((void *) results[i].str_value);
     }
 
   if (results)
diff --git a/src/hid/gtk/gui-utils.c b/src/hid/gtk/gui-utils.c
index 5db7b42..d6e42d2 100644
--- a/src/hid/gtk/gui-utils.c
+++ b/src/hid/gtk/gui-utils.c
@@ -44,7 +44,7 @@ RCSID ("$Id$");
 /* Not a gui function, but no better place to put it...
  */
 gboolean
-dup_string (gchar ** dst, gchar * src)
+dup_string (gchar ** dst, const gchar * src)
 {
   if ((dst == NULL) || ((*dst == NULL) && (src == NULL)))
     return FALSE;
@@ -758,7 +758,7 @@ ghid_scrolled_text_view (GtkWidget * box,
 /* If src is not utf8, *dst is converted to utf8.
  */
 gboolean
-utf8_dup_string (gchar ** dst_utf8, gchar * src)
+utf8_dup_string (gchar ** dst_utf8, const gchar * src)
 {
   if (!dst_utf8 || (!*dst_utf8 && !src))
     return FALSE;
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 6cd85e5..2f63b57 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -340,8 +340,8 @@ void ghid_update_toggle_flags (void);
 
 /* gui-utils.c
 */
-gboolean dup_string (gchar ** dst, gchar * src);
-gboolean utf8_dup_string (gchar ** dst_utf8, gchar * src);
+gboolean dup_string (gchar ** dst, const gchar * src);
+gboolean utf8_dup_string (gchar ** dst_utf8, const gchar * src);
 void free_glist_and_data (GList ** list_head);
 
 ModifierKeysState ghid_modifier_keys_state (GdkModifierType * state);
diff --git a/src/hid/lpr/lpr.c b/src/hid/lpr/lpr.c
index 3d46fec..65f0491 100644
--- a/src/hid/lpr/lpr.c
+++ b/src/hid/lpr/lpr.c
@@ -73,7 +73,7 @@ lpr_do_export (HID_Attr_Val * options)
 {
   FILE *f;
   int i;
-  char *filename;
+  const char *filename;
 
   if (!options)
     {
diff --git a/src/hid/nelma/nelma.c b/src/hid/nelma/nelma.c
index 4f5f748..6e1e9cd 100644
--- a/src/hid/nelma/nelma.c
+++ b/src/hid/nelma/nelma.c
@@ -133,7 +133,7 @@ static int      nelma_export_group[MAX_LAYER];
 static int      nelma_cur_group;
 
 /* Filename prefix that will be used when saving files. */
-static char    *nelma_basename = NULL;
+static const char *nelma_basename = NULL;
 
 /* Horizontal DPI (grid points per inch) */
 static int      nelma_dpi = -1;
diff --git a/src/hid/png/png.c b/src/hid/png/png.c
index bfa98ad..583b165 100644
--- a/src/hid/png/png.c
+++ b/src/hid/png/png.c
@@ -312,12 +312,12 @@ layer_sort (const void *va, const void *vb)
   return b - a;
 }
 
-static char *filename;
+static const char *filename;
 static BoxType *bounds;
 static int in_mono, as_shown;
 
 static void
-parse_bloat (char *str)
+parse_bloat (const char *str)
 {
   double val;
   char suf[10];
diff --git a/src/hid/ps/eps.c b/src/hid/ps/eps.c
index 8fe5d82..8916507 100644
--- a/src/hid/ps/eps.c
+++ b/src/hid/ps/eps.c
@@ -142,7 +142,7 @@ layer_sort (const void *va, const void *vb)
   return b - a;
 }
 
-static char *filename;
+static const char *filename;
 static BoxType *bounds;
 static int in_mono, as_shown;
 
diff --git a/src/hid/ps/ps.c b/src/hid/ps/ps.c
index 201b721..307a89a 100644
--- a/src/hid/ps/ps.c
+++ b/src/hid/ps/ps.c
@@ -218,7 +218,7 @@ static struct {
   bool multi_file;
   BDimension media_width, media_height, ps_width, ps_height;
 
-  char *filename;
+  const char *filename;
   bool drill_helper;
   bool align_marks;
   bool outline;
@@ -1290,7 +1290,7 @@ ps_calibrate_1 (double xval, double yval, int use_command)
 
   if (use_command || strchr (vals[0].str_value, '|'))
     {
-      char *cmd = vals[0].str_value;
+      const char *cmd = vals[0].str_value;
       while (*cmd == ' ' || *cmd == '|')
 	cmd ++;
       ps_cal_file = popen (cmd, "w");
diff --git a/src/main.c b/src/main.c
index 8d6509a..a54896a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -158,7 +158,8 @@ static UsageNotes *usage_notes = NULL;
 static void
 usage_attr (HID_Attribute * a)
 {
-  int i;
+  int i, n;
+  const Unit *unit_list;
   static char buf[200];
 
   if (a->help_text == ATTR_UNDOCUMENTED)
@@ -193,6 +194,17 @@ usage_attr (HID_Attribute * a)
     case HID_Path:
       sprintf (buf, "--%s <path>", a->name);
       break;
+    case HID_Unit:
+      unit_list = get_unit_list ();
+      n = get_n_units ();
+      sprintf (buf, "--%s ", a->name);
+      for (i = 0; i < n; i++)
+	{
+	  strcat (buf, i ? "|" : "<");
+	  strcat (buf, unit_list[i].suffix);
+	}
+      strcat (buf, ">");
+      break;
     }
 
   if (strlen (buf) <= 30)
@@ -307,7 +319,7 @@ print_defaults_1 (HID_Attribute * a, void *value)
 {
   int i;
   double d;
-  char *s;
+  const char *s;
 
   /* Remember, at this point we've parsed the command line, so they
      may be in the global variable instead of the default_val.  */
@@ -343,6 +355,9 @@ print_defaults_1 (HID_Attribute * a, void *value)
       break;
     case HID_Label:
       break;
+    case HID_Unit:
+      i = value ? *(int *) value : a->default_val.int_value;
+      fprintf (stderr, "%s %s\n", a->name, get_unit_list()[i].suffix);
     }
 }
 

commit 7b8f7840a1247a3523a0a26ad06cb5fc3638fdf8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change drawing function coords in hid.h to Coord from int
    
    Note that this causes a slew of compilation warnings about
    mismatched pointer types, since the HIDs themselves are still
    using int-taking functions. These warnings will be cleaned up
    over the next few commits.

diff --git a/src/hid.h b/src/hid.h
index efa2dfd..6bc89c5 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -354,7 +354,7 @@ typedef enum
        different values each time may be expensive, so grouping items by
        line style is helpful.  */
     void (*set_line_cap) (hidGC gc_, EndCapStyle style_);
-    void (*set_line_width) (hidGC gc_, int width_);
+    void (*set_line_width) (hidGC gc_, Coord width_);
     void (*set_draw_xor) (hidGC gc_, int xor_);
     /* Blends 20% or so color with 80% background.  Only used for
        assembly drawings so far. */
@@ -363,12 +363,12 @@ typedef enum
     /* The usual drawing functions.  "draw" means to use segments of the
        given width, whereas "fill" means to fill to a zero-width
        outline.  */
-    void (*draw_line) (hidGC gc_, int x1_, int y1_, int x2_, int y2_);
-    void (*draw_arc) (hidGC gc_, int cx_, int cy_, int xradius_, int yradius_,
-		      int start_angle_, int delta_angle_);
-    void (*draw_rect) (hidGC gc_, int x1_, int y1_, int x2_, int y2_);
-    void (*fill_circle) (hidGC gc_, int cx_, int cy_, int radius_);
-    void (*fill_polygon) (hidGC gc_, int n_coords_, int *x_, int *y_);
+    void (*draw_line) (hidGC gc_, Coord x1_, Coord y1_, Coord x2_, Coord y2_);
+    void (*draw_arc) (hidGC gc_, Coord cx_, Coord cy_, Coord xradius_, Coord yradius_,
+		      Angle start_angle_, Angle delta_angle_);
+    void (*draw_rect) (hidGC gc_, Coord x1_, Coord y1_, Coord x2_, Coord y2_);
+    void (*fill_circle) (hidGC gc_, Coord cx_, Coord cy_, Coord radius_);
+    void (*fill_polygon) (hidGC gc_, int n_coords_, Coord *x_, Coord *y_);
     void (*fill_pcb_polygon) (hidGC gc_, PolygonType *poly,
                               const BoxType *clip_box);
     void (*thindraw_pcb_polygon) (hidGC gc_, PolygonType *poly,
@@ -377,7 +377,7 @@ typedef enum
     void (*thindraw_pcb_pad) (hidGC gc_, PadType *pad, bool clip, bool mask);
     void (*fill_pcb_pv) (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask);
     void (*thindraw_pcb_pv) (hidGC fg_gc, hidGC bg_gc, PinType *pv, bool drawHole, bool mask);
-    void (*fill_rect) (hidGC gc_, int x1_, int y1_, int x2_, int y2_);
+    void (*fill_rect) (hidGC gc_, Coord x1_, Coord y1_, Coord x2_, Coord y2_);
 
 
     /* This is for the printer.  If you call this for the GUI, xval and
@@ -396,7 +396,7 @@ typedef enum
     /* Temporary */
     int (*shift_is_pressed) (void);
     int (*control_is_pressed) (void);
-	int (*mod1_is_pressed) (void);
+    int (*mod1_is_pressed) (void);
     void (*get_coords) (const char *msg_, Coord *x_, Coord *y_);
 
     /* Sets the crosshair, which may differ from the pointer depending

commit affb432342fe81557c6427ed87da0da611b70c41
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit crosshair.[ch], implement Coord

diff --git a/src/crosshair.c b/src/crosshair.c
index 2b0e9b8..d927cf8 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -64,17 +64,16 @@ typedef struct
 /* ---------------------------------------------------------------------------
  * some local prototypes
  */
-static void XORPolygon (PolygonTypePtr, LocationType, LocationType);
-static void XORDrawElement (ElementTypePtr, LocationType, LocationType);
+static void XORPolygon (PolygonTypePtr, Coord, Coord);
+static void XORDrawElement (ElementTypePtr, Coord, Coord);
 static void XORDrawBuffer (BufferTypePtr);
 static void XORDrawInsertPointObject (void);
 static void XORDrawMoveOrCopyObject (void);
-static void XORDrawAttachedLine (LocationType, LocationType, LocationType,
-				 LocationType, BDimension);
-static void XORDrawAttachedArc (BDimension);
+static void XORDrawAttachedLine (Coord, Coord, Coord, Coord, Coord);
+static void XORDrawAttachedArc (Coord);
 
 static void
-thindraw_moved_pv (PinType *pv, int x, int y)
+thindraw_moved_pv (PinType *pv, Coord x, Coord y)
 {
   /* Make a copy of the pin structure, moved to the correct position */
   PinType moved_pv = *pv;
@@ -88,7 +87,7 @@ thindraw_moved_pv (PinType *pv, int x, int y)
  * creates a tmp polygon with coordinates converted to screen system
  */
 static void
-XORPolygon (PolygonTypePtr polygon, LocationType dx, LocationType dy)
+XORPolygon (PolygonTypePtr polygon, Coord dx, Coord dy)
 {
   Cardinal i;
   for (i = 0; i < polygon->PointN; i++)
@@ -106,13 +105,13 @@ XORPolygon (PolygonTypePtr polygon, LocationType dx, LocationType dy)
  * Draws the outline of an arc
  */
 static void
-XORDrawAttachedArc (BDimension thick)
+XORDrawAttachedArc (Coord thick)
 {
   ArcType arc;
   BoxTypePtr bx;
-  LocationType wx, wy;
-  int sa, dir;
-  BDimension wid = thick / 2;
+  Coord wx, wy;
+  Angle sa, dir;
+  Coord wid = thick / 2;
 
   wx = Crosshair.X - Crosshair.AttachedBox.Point1.X;
   wy = Crosshair.Y - Crosshair.AttachedBox.Point1.Y;
@@ -164,11 +163,10 @@ XORDrawAttachedArc (BDimension thick)
  * Draws the outline of a line
  */
 static void
-XORDrawAttachedLine (LocationType x1, LocationType y1, LocationType x2,
-		     LocationType y2, BDimension thick)
+XORDrawAttachedLine (Coord x1, Coord y1, Coord x2, Coord y2, Coord thick)
 {
-  LocationType dx, dy, ox, oy;
-  float h;
+  Coord dx, dy, ox, oy;
+  double h;
 
   dx = x2 - x1;
   dy = y2 - y1;
@@ -181,7 +179,7 @@ XORDrawAttachedLine (LocationType x1, LocationType y1, LocationType x2,
   gui->draw_line (Crosshair.GC, x1 + ox, y1 + oy, x2 + ox, y2 + oy);
   if (abs (ox) >= pixel_slop || abs (oy) >= pixel_slop)
     {
-      LocationType angle = atan2 ((float) dx, (float) dy) * 57.295779;
+      Angle angle = atan2 (dx, dy) * 57.295779;
       gui->draw_line (Crosshair.GC, x1 - ox, y1 - oy, x2 - ox, y2 - oy);
       gui->draw_arc (Crosshair.GC,
 		     x1, y1, thick / 2, thick / 2, angle - 180, 180);
@@ -193,7 +191,7 @@ XORDrawAttachedLine (LocationType x1, LocationType y1, LocationType x2,
  * draws the elements of a loaded circuit which is to be merged in
  */
 static void
-XORDrawElement (ElementTypePtr Element, LocationType DX, LocationType DY)
+XORDrawElement (ElementTypePtr Element, Coord DX, Coord DY)
 {
   /* if no silkscreen, draw the bounding box */
   if (Element->ArcN == 0 && Element->LineN == 0)
@@ -288,7 +286,7 @@ static void
 XORDrawBuffer (BufferTypePtr Buffer)
 {
   Cardinal i;
-  LocationType x, y;
+  Coord x, y;
 
   /* set offset */
   x = Crosshair.X - Buffer->X;
@@ -382,7 +380,7 @@ XORDrawMoveOrCopyObject (void)
 {
   RubberbandTypePtr ptr;
   Cardinal i;
-  LocationType dx = Crosshair.X - Crosshair.AttachedObject.X,
+  Coord dx = Crosshair.X - Crosshair.AttachedObject.X,
     dy = Crosshair.Y - Crosshair.AttachedObject.Y;
 
   switch (Crosshair.AttachedObject.Type)
@@ -657,7 +655,7 @@ DrawAttached (void)
   if (Crosshair.AttachedBox.State == STATE_SECOND ||
       Crosshair.AttachedBox.State == STATE_THIRD)
     {
-      LocationType x1, y1, x2, y2;
+      Coord x1, y1, x2, y2;
 
       x1 = Crosshair.AttachedBox.Point1.X;
       y1 = Crosshair.AttachedBox.Point1.Y;
@@ -796,7 +794,7 @@ square (double x)
 }
 
 static double
-crosshair_sq_dist (CrosshairType *crosshair, LocationType x, LocationType y)
+crosshair_sq_dist (CrosshairType *crosshair, Coord x, Coord y)
 {
   return square (x - crosshair->X) + square (y - crosshair->Y);
 }
@@ -815,7 +813,7 @@ struct snap_data {
  * (including grid points), is always preferred.
  */
 static void
-check_snap_object (struct snap_data *snap_data, LocationType x, LocationType y,
+check_snap_object (struct snap_data *snap_data, Coord x, Coord y,
                    bool prefer_to_grid)
 {
   double sq_dist;
@@ -833,13 +831,13 @@ check_snap_object (struct snap_data *snap_data, LocationType x, LocationType y,
 
 static void
 check_snap_offgrid_line (struct snap_data *snap_data,
-                         LocationType nearest_grid_x,
-                         LocationType nearest_grid_y)
+                         Coord nearest_grid_x,
+                         Coord nearest_grid_y)
 {
   void *ptr1, *ptr2, *ptr3;
   int ans;
   LineType *line;
-  LocationType try_x, try_y;
+  Coord try_x, try_y;
   double dx, dy;
   double dist;
 
@@ -1120,7 +1118,7 @@ FitCrosshairIntoGrid (Coord X, Coord Y)
  * move crosshair relative (has to be switched off)
  */
 void
-MoveCrosshairRelative (LocationType DeltaX, LocationType DeltaY)
+MoveCrosshairRelative (Coord DeltaX, Coord DeltaY)
 {
   FitCrosshairIntoGrid (Crosshair.X + DeltaX, Crosshair.Y + DeltaY);
 }
@@ -1130,9 +1128,9 @@ MoveCrosshairRelative (LocationType DeltaX, LocationType DeltaY)
  * return true if the crosshair was moved from its existing position
  */
 bool
-MoveCrosshairAbsolute (LocationType X, LocationType Y)
+MoveCrosshairAbsolute (Coord X, Coord Y)
 {
-  LocationType x, y, z;
+  Coord x, y, z;
   x = Crosshair.X;
   y = Crosshair.Y;
   FitCrosshairIntoGrid (X, Y);
@@ -1158,13 +1156,12 @@ MoveCrosshairAbsolute (LocationType X, LocationType Y)
  * sets the valid range for the crosshair cursor
  */
 void
-SetCrosshairRange (LocationType MinX, LocationType MinY, LocationType MaxX,
-		   LocationType MaxY)
+SetCrosshairRange (Coord MinX, Coord MinY, Coord MaxX, Coord MaxY)
 {
   Crosshair.MinX = MAX (0, MinX);
   Crosshair.MinY = MAX (0, MinY);
-  Crosshair.MaxX = MIN ((LocationType) PCB->MaxWidth, MaxX);
-  Crosshair.MaxY = MIN ((LocationType) PCB->MaxHeight, MaxY);
+  Crosshair.MaxX = MIN (PCB->MaxWidth, MaxX);
+  Crosshair.MaxY = MIN (PCB->MaxHeight, MaxY);
 
   /* force update of position */
   MoveCrosshairRelative (0, 0);
diff --git a/src/crosshair.h b/src/crosshair.h
index 3fbd998..8c42067 100644
--- a/src/crosshair.h
+++ b/src/crosshair.h
@@ -47,12 +47,11 @@ void HideCrosshair (void);
 void RestoreCrosshair (void);
 void DrawAttached (void);
 void DrawMark (void);
-void MoveCrosshairRelative (LocationType, LocationType);
-bool MoveCrosshairAbsolute (LocationType, LocationType);
-void SetCrosshairRange (LocationType, LocationType, LocationType,
-			LocationType);
+void MoveCrosshairRelative (Coord, Coord);
+bool MoveCrosshairAbsolute (Coord, Coord);
+void SetCrosshairRange (Coord, Coord, Coord, Coord);
 void InitCrosshair (void);
 void DestroyCrosshair (void);
-void FitCrosshairIntoGrid (LocationType, LocationType);
+void FitCrosshairIntoGrid (Coord, Coord);
 
 #endif

commit 4632e403310efaef0b8bb3e48f5d5a839398f6e7
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit parse_y.y, implement Coord

diff --git a/src/parse_y.y b/src/parse_y.y
index 9c1bb6a..8cf1888 100644
--- a/src/parse_y.y
+++ b/src/parse_y.y
@@ -85,7 +85,7 @@ int yyerror(const char *s);
 int yylex();
 static int check_file_version (int);
 
-static void do_measure (PLMeasure *m, int i, double d, int u);
+static void do_measure (PLMeasure *m, Coord i, double d, int u);
 #define M(r,f,d) do_measure (&(r), f, d, 1)
 
 /* Macros for interpreting what "measure" means - integer value only,
@@ -95,8 +95,8 @@ static void do_measure (PLMeasure *m, int i, double d, int u);
 #define NU(m) new_units (m)
 
 static int integer_value (PLMeasure m);
-static BDimension old_units (PLMeasure m);
-static BDimension new_units (PLMeasure m);
+static Coord old_units (PLMeasure m);
+static Coord new_units (PLMeasure m);
 
 #define YYDEBUG 1
 #define YYERROR_VERBOSE 1
@@ -780,7 +780,7 @@ via_oldformat
 			/* old format: x, y, thickness, name, flags */
 		: T_VIA '(' measure measure measure STRING INTEGER ')'
 			{
-				BDimension	hole = (OU($5) * DEFAULT_DRILLINGHOLE);
+				Coord	hole = (OU($5) * DEFAULT_DRILLINGHOLE);
 
 					/* make sure that there's enough copper left */
 				if (OU($5) - hole < MIN_PINORVIACOPPER && 
@@ -1592,8 +1592,8 @@ pin_oldformat
 			 */
 		: T_PIN '(' measure measure measure STRING INTEGER ')'
 			{
-				BDimension	hole = OU ($5) * DEFAULT_DRILLINGHOLE;
-				char		p_number[8];
+				Coord	hole = OU ($5) * DEFAULT_DRILLINGHOLE;
+				char	p_number[8];
 
 					/* make sure that there's enough copper left */
 				if (OU ($5) - hole < MIN_PINORVIACOPPER && 
@@ -1979,7 +1979,7 @@ check_file_version (int ver)
 }
 
 static void
-do_measure (PLMeasure *m, BDimension i, double d, int u)
+do_measure (PLMeasure *m, Coord i, double d, int u)
 {
   m->ival = i;
   m->bval = round (d);
@@ -1995,7 +1995,7 @@ integer_value (PLMeasure m)
   return m.ival;
 }
 
-static BDimension
+static Coord
 old_units (PLMeasure m)
 {
   if (m.has_units)
@@ -2003,7 +2003,7 @@ old_units (PLMeasure m)
   return round (MIL_TO_COORD (m.ival));
 }
 
-static BDimension
+static Coord
 new_units (PLMeasure m)
 {
   if (m.has_units)

commit f97d92bfbb9580a54a6d1770ffa3973420fb49ab
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit mtspace.[ch], implement Coord

diff --git a/src/mtspace.c b/src/mtspace.c
index 40f5413..a4bb314 100644
--- a/src/mtspace.c
+++ b/src/mtspace.c
@@ -66,7 +66,7 @@ RCSID ("$Id$");
 typedef struct mtspacebox
 {
   const BoxType box;
-  BDimension keepaway;		/* the smallest keepaway around this box */
+  Coord keepaway;		/* the smallest keepaway around this box */
 }
 mtspacebox_t;
 
@@ -91,15 +91,15 @@ struct vetting
   heap_or_vector no_fix;
   heap_or_vector no_hi;
   heap_or_vector hi_candidate;
-  BDimension radius;
-  BDimension keepaway;
+  Coord radius;
+  Coord keepaway;
   CheapPointType desired;
 };
 
 #define SPECIAL 823157
 
 mtspacebox_t *
-mtspace_create_box (const BoxType * box, BDimension keepaway)
+mtspace_create_box (const BoxType * box, Coord keepaway)
 {
   mtspacebox_t *mtsb;
   assert (box_is_good (box));
@@ -140,7 +140,7 @@ mtspace_destroy (mtspace_t ** mtspacep)
 
 struct mts_info
 {
-  BDimension keepaway;
+  Coord keepaway;
   BoxType box;
   rtree_t *tree;
   jmp_buf env;
@@ -181,7 +181,7 @@ which_tree (mtspace_t * mtspace, mtspace_type_t which)
 /* add a space-filler to the empty space representation.  */
 void
 mtspace_add (mtspace_t * mtspace, const BoxType * box, mtspace_type_t which,
-	     BDimension keepaway)
+	     Coord keepaway)
 {
   mtspacebox_t *filler = mtspace_create_box (box, keepaway);
   r_insert_entry (which_tree (mtspace, which), (const BoxType *) filler, 1);
@@ -191,7 +191,7 @@ mtspace_add (mtspace_t * mtspace, const BoxType * box, mtspace_type_t which,
 void
 mtspace_remove (mtspace_t * mtspace,
 		const BoxType * box, mtspace_type_t which,
-		BDimension keepaway)
+		Coord keepaway)
 {
   struct mts_info cl;
   BoxType small_search;
@@ -213,7 +213,7 @@ struct query_closure
   heap_or_vector checking;
   heap_or_vector touching;
   CheapPointType *desired;
-  BDimension radius, keepaway;
+  Coord radius, keepaway;
   jmp_buf env;
   bool touch_is_vec;
 };
@@ -245,7 +245,7 @@ query_one (const BoxType * box, void *cl)
 {
   struct query_closure *qc = (struct query_closure *) cl;
   mtspacebox_t *mtsb = (mtspacebox_t *) box;
-  BDimension shrink;
+  Coord shrink;
   assert (box_intersect (qc->cbox, &mtsb->box));
   /* we need to satisfy the larger of the two keepaways */
   if (qc->keepaway > mtsb->keepaway)
@@ -262,8 +262,8 @@ query_one (const BoxType * box, void *cl)
   /* ok, we do touch this box, now create up to 4 boxes that don't */
   if (mtsb->box.Y1 > qc->cbox->Y1 + shrink)	/* top region exists */
     {
-      int Y1 = qc->cbox->Y1;
-      int Y2 = mtsb->box.Y1 + shrink;
+      Coord Y1 = qc->cbox->Y1;
+      Coord Y2 = mtsb->box.Y1 + shrink;
       if (Y2 - Y1 >= 2 * (qc->radius + qc->keepaway))
 	{
 	  BoxType *newone = (BoxType *) malloc (sizeof (BoxType));
@@ -277,8 +277,8 @@ query_one (const BoxType * box, void *cl)
     }
   if (mtsb->box.Y2 < qc->cbox->Y2 - shrink)	/* bottom region exists */
     {
-      int Y1 = mtsb->box.Y2 - shrink;
-      int Y2 = qc->cbox->Y2;
+      Coord Y1 = mtsb->box.Y2 - shrink;
+      Coord Y2 = qc->cbox->Y2;
       if (Y2 - Y1 >= 2 * (qc->radius + qc->keepaway))
 	{
 	  BoxType *newone = (BoxType *) malloc (sizeof (BoxType));
@@ -292,8 +292,8 @@ query_one (const BoxType * box, void *cl)
     }
   if (mtsb->box.X1 > qc->cbox->X1 + shrink)	/* left region exists */
     {
-      int X1 = qc->cbox->X1;
-      int X2 = mtsb->box.X1 + shrink;
+      Coord X1 = qc->cbox->X1;
+      Coord X2 = mtsb->box.X1 + shrink;
       if (X2 - X1 >= 2 * (qc->radius + qc->keepaway))
 	{
 	  BoxType *newone;
@@ -308,8 +308,8 @@ query_one (const BoxType * box, void *cl)
     }
   if (mtsb->box.X2 < qc->cbox->X2 - shrink)	/* right region exists */
     {
-      int X1 = mtsb->box.X2 - shrink;
-      int X2 = qc->cbox->X2;
+      Coord X1 = mtsb->box.X2 - shrink;
+      Coord X2 = qc->cbox->X2;
       if (X2 - X1 >= 2 * (qc->radius + qc->keepaway))
 	{
 	  BoxType *newone = (BoxType *) malloc (sizeof (BoxType));
@@ -429,7 +429,7 @@ mtsFreeWork (vetting_t ** w)
  */
 vetting_t *
 mtspace_query_rect (mtspace_t * mtspace, const BoxType * region,
-		    BDimension radius, BDimension keepaway,
+		    Coord radius, Coord keepaway,
 		    vetting_t * work,
 		    vector_t * free_space_vec,
 		    vector_t * lo_conflict_space_vec,
diff --git a/src/mtspace.h b/src/mtspace.h
index b2872cd..c169170 100644
--- a/src/mtspace.h
+++ b/src/mtspace.h
@@ -60,7 +60,7 @@ void mtspace_destroy (mtspace_t ** mtspacep);
  * *at least* a radius of keepaway around it;
  */
 void mtspace_add (mtspace_t * mtspace,
-                  const BoxType * box, mtspace_type_t which, BDimension
+                  const BoxType * box, mtspace_type_t which, Coord
                   keepaway);
 /* remove a space-filler from the empty space representation.  The given box
  * should *not* be bloated; it should be "true".  The feature will fill
@@ -68,11 +68,11 @@ void mtspace_add (mtspace_t * mtspace,
  */
 void mtspace_remove (mtspace_t * mtspace,
                      const BoxType * box, mtspace_type_t which,
-                     BDimension keepaway);
+                     Coord keepaway);
 
 
 vetting_t *mtspace_query_rect (mtspace_t * mtspace, const BoxType * region,
-                               BDimension radius, BDimension keepaway,
+                               Coord radius, Coord keepaway,
                                vetting_t * work,
                                vector_t * free_space_vec,
                                vector_t * lo_conflict_space_vec,

commit 2217294268a1d5dee74ab96f059eeba5ed7c9995
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit report.c, implement Coord
    
    Includes fixes for the original pcb-printf conversion:
      Fix drill report spacing in report.c
      Use %ma spec outputting angles in report.c

diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index ed81060..f86d4d9 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -25,8 +25,8 @@
  */
 
 /* This file defines a wrapper around sprintf, that
- *  defines new specifiers that take pcb BDimension
- *  objects as input.
+ *  defines new specifiers that take pcb Coord objects
+ *  as input.
  *
  * There is a fair bit of nasty (repetitious) code in
  *  here, but I feel the gain in clarity for output
diff --git a/src/report.c b/src/report.c
index dbcf776..56e1fa9 100644
--- a/src/report.c
+++ b/src/report.c
@@ -88,7 +88,7 @@ ReportDrills (int argc, char **argv, Coord x, Coord y)
   for (n = 0; n < AllDrills->DrillN; n++)
     {
       pcb_sprintf (thestring,
-	       "\t%$m*\t\t%d\t\t%d\t\t%d\t\t%d\n",
+	       "%10m*\t\t%d\t\t%d\t\t%d\t\t%d\n",
 	       Settings.grid_unit->suffix,
 	       AllDrills->Drill[n].DrillSize,
 	       AllDrills->Drill[n].PinCount, AllDrills->Drill[n].ViaCount,
@@ -291,7 +291,7 @@ ReportDialog (int argc, char **argv, Coord x, Coord y)
 		 "CenterPoint(X,Y) = %$mD.\n"
 		 "Radius = %$mS, Thickness = %$mS.\n"
 		 "Clearance width in polygons = %$mS.\n"
-		 "StartAngle = %ld degrees, DeltaAngle = %ld degrees.\n"
+		 "StartAngle = %ma degrees, DeltaAngle = %ma degrees.\n"
 		 "Bounding Box is %$mD, %$mD.\n"
 		 "That makes the end points at %$mD and %$mD.\n"
 		 "It is on layer %d.\n"
@@ -337,7 +337,7 @@ ReportDialog (int argc, char **argv, Coord x, Coord y)
       }
     case PAD_TYPE:
       {
-	BDimension len;
+	Coord len;
 	PadTypePtr Pad;
 	ElementTypePtr element;
 #ifndef NDEBUG
@@ -411,7 +411,7 @@ ReportDialog (int argc, char **argv, Coord x, Coord y)
 		 EMPTY (element->Name[0].TextString),
 		 EMPTY (element->Name[1].TextString),
 		 EMPTY (element->Name[2].TextString),
-		 (BDimension) (0.45 * element->Name[1].Scale * 100),
+		 (Coord) (0.45 * element->Name[1].Scale * 100),
 		 element->Name[1].X, element->Name[1].Y,
 		 TEST_FLAG (HIDENAMEFLAG, element) ? ",\n  but it's hidden" : "",
 		 element->MarkX, element->MarkY,
@@ -452,7 +452,7 @@ ReportDialog (int argc, char **argv, Coord x, Coord y)
 		 "The bounding box is %$mD %$mD.\n"
 		 "%s\n"
 		 "%s", USER_UNITMASK, text->ID, flags_to_string (text->Flags, TEXT_TYPE),
-		 text->X, text->Y, (BDimension) (0.45 * text->Scale * 100),
+		 text->X, text->Y, (Coord) (0.45 * text->Scale * 100),
 		 text->TextString, text->Direction,
 		 text->BoundingBox.X1, text->BoundingBox.Y1,
 		 text->BoundingBox.X2, text->BoundingBox.Y2,
@@ -630,7 +630,7 @@ ReportAllNetLengths (int argc, char **argv, Coord x, Coord y)
         {
           char buf[50];
           const char *units_name = argv[0];
-          BDimension length;
+          Coord length;
 
           if (argc < 1)
             units_name = Settings.grid_unit->suffix;
@@ -652,7 +652,7 @@ ReportAllNetLengths (int argc, char **argv, Coord x, Coord y)
 static int
 ReportNetLength (int argc, char **argv, Coord x, Coord y)
 {
-  BDimension length = 0;
+  Coord length = 0;
   char *netname = 0;
   int found = 0;
 

commit 732d85dd996d352b19dee8c3232688b38b7819b4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit autoroute.[ch], implement Coord
    
    There are many magic numbers in this file. It is likely
    they will be skewed by base-unit changes, though I have
    worked to mitigate this.

diff --git a/src/autoroute.c b/src/autoroute.c
index 63ab15c..34e01dc 100644
--- a/src/autoroute.c
+++ b/src/autoroute.c
@@ -326,8 +326,8 @@ typedef struct routedata
   RouteStyleType *styles[NUM_STYLES + 1];
   /* what is the maximum bloat (keepaway+line half-width or
    * keepaway+via_radius) for any style we've seen? */
-  BDimension max_bloat;
-  BDimension max_keep;
+  Coord max_bloat;
+  Coord max_keep;
   mtspace_t *mtspace;
 }
 routedata_t;
@@ -364,7 +364,7 @@ static struct
   /* net style parameters */
   RouteStyleType *style;
   /* the present bloat */
-  BDimension bloat;
+  Coord bloat;
   /* cost parameters */
   cost_t ViaCost,		/* additional "length" cost for using a via */
     LastConflictPenalty,	/* length mult. for routing over last pass' trace */
@@ -417,7 +417,7 @@ static BoxType edge_to_box (const routebox_t * rb, direction_t expand_dir);
 static void add_or_destroy_edge (struct routeone_state *s, edge_t * e);
 
 static void
-RD_DrawThermal (routedata_t * rd, LocationType X, LocationType Y,
+RD_DrawThermal (routedata_t * rd, Coord X, Coord Y,
 		Cardinal group, Cardinal layer, routebox_t * subnet,
 		bool is_bad);
 static void ResetSubnet (routebox_t * net);
@@ -594,8 +594,8 @@ RemoveFromNet (routebox_t * a, enum boxlist which)
 
 static void
 init_const_box (routebox_t * rb,
-		LocationType X1, LocationType Y1, LocationType X2,
-		LocationType Y2, BDimension keepaway)
+		Coord X1, Coord Y1, Coord X2,
+		Coord Y2, Coord keepaway)
 {
   BoxType *bp = (BoxType *) & rb->box;	/* note discarding const! */
   assert (!rb->flags.inited);
@@ -632,7 +632,7 @@ closest_point_in_routebox (const CheapPointType * from, const routebox_t * rb)
 }
 
 static inline bool
-point_in_shrunk_box (const routebox_t * box, LocationType X, LocationType Y)
+point_in_shrunk_box (const routebox_t * box, Coord X, Coord Y)
 {
   BoxType b = shrink_routebox (box);
   return point_in_box (&b, X, Y);
@@ -693,7 +693,7 @@ static routebox_t *
 AddPad (PointerListType layergroupboxes[],
 	ElementTypePtr element, PadTypePtr pad, RouteStyleType * style)
 {
-  BDimension halfthick;
+  Coord halfthick;
   routebox_t **rbpp;
   int layergroup = (TEST_FLAG (ONSOLDERFLAG, pad) ? back : front);
   assert (0 <= layergroup && layergroup < max_group);
@@ -770,12 +770,12 @@ AddLine (PointerListType layergroupboxes[], int layergroup, LineTypePtr line,
 }
 static routebox_t *
 AddIrregularObstacle (PointerListType layergroupboxes[],
-		      LocationType X1, LocationType Y1,
-		      LocationType X2, LocationType Y2, Cardinal layergroup,
+		      Coord X1, Coord Y1,
+		      Coord X2, Coord Y2, Cardinal layergroup,
 		      void *parent, RouteStyleType * style)
 {
   routebox_t **rbpp;
-  LocationType keep = style->Keepaway;
+  Coord keep = style->Keepaway;
   assert (layergroupboxes && parent);
   assert (X1 <= X2 && Y1 <= Y2);
   assert (0 <= layergroup && layergroup < max_group);
@@ -879,7 +879,7 @@ __found_one_on_lg (const BoxType * box, void *cl)
 }
 static routebox_t *
 FindRouteBoxOnLayerGroup (routedata_t * rd,
-			  LocationType X, LocationType Y, Cardinal layergroup)
+			  Coord X, Coord Y, Cardinal layergroup)
 {
   struct rb_info info;
   info.winner = NULL;
@@ -1060,12 +1060,12 @@ CreateRouteData ()
 		  && line->Point1.Y != line->Point2.Y)
 		{
 		  LineType fake_line = *line;
-		  int dx = (line->Point2.X - line->Point1.X);
-		  int dy = (line->Point2.Y - line->Point1.Y);
+		  Coord dx = (line->Point2.X - line->Point1.X);
+		  Coord dy = (line->Point2.Y - line->Point1.Y);
 		  int segs = MAX (ABS (dx),
 				  ABS (dy)) / (4 * BLOAT (rd->styles[j]) + 1);
 		  int qq;
-		  segs = MAX (1, MIN (segs, 32));	/* don't go too crazy */
+		  segs = CLAMP (segs, 1, 32);	/* don't go too crazy */
 		  dx /= segs;
 		  dy /= segs;
 		  for (qq = 0; qq < segs - 1; qq++)
@@ -1195,11 +1195,11 @@ CreateRouteData ()
 	    && line->Point1.Y != line->Point2.Y)
 	  {
 	    LineType fake_line = *line;
-	    int dx = (line->Point2.X - line->Point1.X);
-	    int dy = (line->Point2.Y - line->Point1.Y);
+	    Coord dx = (line->Point2.X - line->Point1.X);
+	    Coord dy = (line->Point2.Y - line->Point1.Y);
 	    int segs = MAX (ABS (dx), ABS (dy)) / (4 * rd->max_bloat + 1);
 	    int qq;
-	    segs = MAX (1, MIN (segs, 32));	/* don't go too crazy */
+	    segs = CLAMP (segs, 1, 32);	/* don't go too crazy */
 	    dx /= segs;
 	    dy /= segs;
 	    for (qq = 0; qq < segs - 1; qq++)
@@ -1442,7 +1442,7 @@ static BoxType
 bloat_routebox (routebox_t * rb)
 {
   BoxType r;
-  LocationType keepaway;
+  Coord keepaway;
   assert (__routebox_is_good (rb));
 
   if (rb->flags.nobloat)
@@ -1712,7 +1712,7 @@ mincost_target_to_point (const CheapPointType * CostPoint,
 /* mincost_target_guess can be NULL */
 static edge_t *
 CreateEdge (routebox_t * rb,
-	    LocationType CostPointX, LocationType CostPointY,
+	    Coord CostPointX, Coord CostPointY,
 	    cost_t cost_to_point,
 	    routebox_t * mincost_target_guess,
 	    direction_t expand_dir, rtree_t * targets)
@@ -2077,7 +2077,7 @@ struct E_result
 {
   routebox_t *parent;
   routebox_t *n, *e, *s, *w;
-  BDimension keep, bloat;
+  Coord keep, bloat;
   BoxType inflated, orig;
   int done;
 };
@@ -2094,7 +2094,7 @@ __Expand_this_rect (const BoxType * box, void *cl)
   struct E_result *res = (struct E_result *) cl;
   routebox_t *rb = (routebox_t *) box;
   BoxType rbox;
-  BDimension dn, de, ds, dw, bloat;
+  Coord dn, de, ds, dw, bloat;
 
   /* we don't see conflicts already encountered */
   if (rb->flags.touched)
@@ -2208,7 +2208,7 @@ __Expand_this_rect (const BoxType * box, void *cl)
 static bool
 boink_box (routebox_t * rb, struct E_result *res, direction_t dir)
 {
-  LocationType bloat;
+  Coord bloat;
   if (rb->style->Keepaway > res->keep)
     bloat = res->keep - rb->style->Keepaway;
   else
@@ -2710,7 +2710,7 @@ __GatherBlockers (const BoxType * box, void *cl)
  * edge, which would be the southern most edge for that example.
  */
 static inline BoxType
-previous_edge (LocationType last, direction_t i, const BoxType * b)
+previous_edge (Coord last, direction_t i, const BoxType * b)
 {
   BoxType db = *b;
   switch (i)
@@ -2743,8 +2743,8 @@ BreakManyEdges (struct routeone_state * s, rtree_t * targets, rtree_t * tree,
   struct break_info bi;
   vector_t *edges;
   heap_t *heap[4];
-  LocationType first, last;
-  BDimension bloat;
+  Coord first, last;
+  Coord bloat;
   direction_t dir;
   routebox_t fake;
 
@@ -3174,7 +3174,7 @@ FindThermable (rtree_t * rtree, routebox_t * rb)
  * a line through them to actually create the connection.
  */
 static void
-RD_DrawThermal (routedata_t * rd, LocationType X, LocationType Y,
+RD_DrawThermal (routedata_t * rd, Coord X, Coord Y,
 		Cardinal group, Cardinal layer, routebox_t * subnet,
 		bool is_bad)
 {
@@ -3199,8 +3199,8 @@ RD_DrawThermal (routedata_t * rd, LocationType X, LocationType Y,
 }
 
 static void
-RD_DrawVia (routedata_t * rd, LocationType X, LocationType Y,
-	    BDimension radius, routebox_t * subnet, bool is_bad)
+RD_DrawVia (routedata_t * rd, Coord X, Coord Y,
+	    Coord radius, routebox_t * subnet, bool is_bad)
 {
   routebox_t *rb, *first_via = NULL;
   int i;
@@ -3262,8 +3262,8 @@ RD_DrawVia (routedata_t * rd, LocationType X, LocationType Y,
 }
 static void
 RD_DrawLine (routedata_t * rd,
-	     LocationType X1, LocationType Y1, LocationType X2,
-	     LocationType Y2, BDimension halfthick, Cardinal group,
+	     Coord X1, Coord Y1, Coord X2,
+	     Coord Y2, Coord halfthick, Cardinal group,
 	     routebox_t * subnet, bool is_bad, bool is_45)
 {
   /* we hold the line in a queue to concatenate segments that
@@ -3271,14 +3271,14 @@ RD_DrawLine (routedata_t * rd,
    * the trees and allows conflict boxes to be larger, both of
    * which are really useful.
    */
-  static LocationType qX1 = -1, qY1, qX2, qY2;
-  static BDimension qhthick;
+  static Coord qX1 = -1, qY1, qX2, qY2;
+  static Coord qhthick;
   static Cardinal qgroup;
   static bool qis_45, qis_bad;
   static routebox_t *qsn;
 
   routebox_t *rb;
-  int ka = AutoRouteParameters.style->Keepaway;
+  Coord ka = AutoRouteParameters.style->Keepaway;
 
   /* don't draw zero-length segments. */
   if (X1 == X2 && Y1 == Y2)
@@ -3376,7 +3376,7 @@ static bool
 RD_DrawManhattanLine (routedata_t * rd,
 		      const BoxType * box1, const BoxType * box2,
 		      CheapPointType start, CheapPointType end,
-		      BDimension halfthick, Cardinal group,
+		      Coord halfthick, Cardinal group,
 		      routebox_t * subnet, bool is_bad, bool last_was_x)
 {
   CheapPointType knee = start;
@@ -3426,7 +3426,7 @@ RD_DrawManhattanLine (routedata_t * rd,
   else
     {
       /* draw 45-degree path across knee */
-      BDimension len45 = MIN (ABS (start.X - end.X), ABS (start.Y - end.Y));
+      Coord len45 = MIN (ABS (start.X - end.X), ABS (start.Y - end.Y));
       CheapPointType kneestart = knee, kneeend = knee;
       if (kneestart.X == start.X)
 	kneestart.Y += (kneestart.Y > start.Y) ? -len45 : len45;
@@ -3503,8 +3503,8 @@ TracePath (routedata_t * rd, routebox_t * path, const routebox_t * target,
 	   routebox_t * subnet, bool is_bad)
 {
   bool last_x = false;
-  BDimension halfwidth = HALF_THICK (AutoRouteParameters.style->Thick);
-  BDimension radius = HALF_THICK (AutoRouteParameters.style->Diameter);
+  Coord halfwidth = HALF_THICK (AutoRouteParameters.style->Thick);
+  Coord radius = HALF_THICK (AutoRouteParameters.style->Diameter);
   CheapPointType lastpoint, nextpoint;
   routebox_t *lastpath;
   BoxType b;
@@ -3777,9 +3777,9 @@ add_via_sites (struct routeone_state *s,
 	       struct routeone_via_site_state *vss,
 	       mtspace_t * mtspace, routebox_t * within,
 	       conflict_t within_conflict_level, edge_t * parent_edge,
-	       rtree_t * targets, BDimension shrink, bool in_plane)
+	       rtree_t * targets, Coord shrink, bool in_plane)
 {
-  int radius, keepaway;
+  Coord radius, keepaway;
   vetting_t *work;
   BoxType region = shrink_routebox (within);
   shrink_box (&region, shrink);
@@ -3810,7 +3810,7 @@ do_via_search (edge_t * search, struct routeone_state *s,
 	       rtree_t * targets)
 {
   int i, j, count = 0;
-  int radius, keepaway;
+  Coord radius, keepaway;
   vetting_t *work;
   routebox_t *within;
   conflict_t within_conflict_level;
@@ -4549,7 +4549,7 @@ InitAutoRouteParameters (int pass,
   AutoRouteParameters.bloat = style->Keepaway + HALF_THICK (style->Thick);
   /* costs */
   AutoRouteParameters.ViaCost =
-    350000 + style->Diameter * (is_smoothing ? 80 : 30);
+    INCH_TO_COORD (3.5) + style->Diameter * (is_smoothing ? 80 : 30);
   AutoRouteParameters.LastConflictPenalty =
     (400 * pass / passes + 2) / (pass + 1);
   AutoRouteParameters.ConflictPenalty =
@@ -4690,7 +4690,7 @@ RouteAll (routedata_t * rd)
 #endif
   LIST_LOOP (rd->first_net, different_net, net);
   {
-    float area;
+    double area;
     BoxType bb = shrink_routebox (net);
     LIST_LOOP (net, same_net, p);
     {
@@ -4700,7 +4700,7 @@ RouteAll (routedata_t * rd)
       MAKEMAX (bb.Y2, p->sbox.Y2);
     }
     END_LOOP;
-    area = (float) (bb.X2 - bb.X1) * (bb.Y2 - bb.Y1);
+    area = (double) (bb.X2 - bb.X1) * (bb.Y2 - bb.Y1);
     heap_insert (this_pass, area, net);
   }
   END_LOOP;
@@ -4968,7 +4968,7 @@ out:
 struct fpin_info
 {
   PinTypePtr pin;
-  LocationType X, Y;
+  Coord X, Y;
   jmp_buf env;
 };
 
@@ -5041,7 +5041,7 @@ IronDownAllUnfixedPaths (routedata_t * rd)
 	  assert (p->type != EXPANSION_AREA);
 	  if (p->type == LINE)
 	    {
-	      BDimension halfwidth = HALF_THICK (p->style->Thick);
+	      Coord halfwidth = HALF_THICK (p->style->Thick);
 	      double th = halfwidth * 2 + 1;
 	      BoxType b;
 	      assert (p->parent.line == NULL);
@@ -5058,7 +5058,7 @@ IronDownAllUnfixedPaths (routedata_t * rd)
 		b.Y2 = b.Y1;
 	      if (p->flags.bl_to_ur)
 		{
-		  BDimension t;
+		  Coord t;
 		  t = b.X1;
 		  b.X1 = b.X2;
 		  b.X2 = t;
@@ -5083,7 +5083,7 @@ IronDownAllUnfixedPaths (routedata_t * rd)
 	    {
 	      routebox_t *pp =
 		(p->type == VIA_SHADOW) ? p->parent.via_shadow : p;
-	      BDimension radius = HALF_THICK (pp->style->Diameter);
+	      Coord radius = HALF_THICK (pp->style->Diameter);
 	      BoxType b = shrink_routebox (p);
 	      total_via_count++;
 	      assert (pp->type == VIA);
@@ -5345,8 +5345,8 @@ donerouting:
 
   if (changed)
     changed = IronDownAllUnfixedPaths (rd);
-  Message ("Total added wire length = %f inches, %d vias added\n",
-	   total_wire_length / 1.e5, total_via_count);
+  Message ("Total added wire length = %$mS, %d vias added\n",
+	   (Coord) total_wire_length, total_via_count);
   DestroyRouteData (&rd);
   if (changed)
     {

commit dfbd2188bb9dadc5efbea8871e3ba49ccb79d3ff
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit autoplace.c, implement Coord
    
    Note that there are -many- magic numbers in this file.
    I believe I've caught all of them that are supposed to
    be unit conversions and used macros instead.

diff --git a/src/autoplace.c b/src/autoplace.c
index 991cf9e..0e74b66 100644
--- a/src/autoplace.c
+++ b/src/autoplace.c
@@ -85,21 +85,21 @@ static double ComputeCost (NetListTypePtr Nets, double T0, double T);
  */
 const struct
 {
-  float via_cost;
-  float congestion_penalty;	/* penalty length / unit area */
-  float overlap_penalty_min;	/* penalty length / unit area at start */
-  float overlap_penalty_max;	/* penalty length / unit area at end */
-  float out_of_bounds_penalty;	/* assessed for each component oob */
-  float overall_area_penalty;	/* penalty length / unit area */
-  float matching_neighbor_bonus;	/* length bonus per same-type neigh. */
-  float aligned_neighbor_bonus;	/* length bonus per aligned neigh. */
-  float oriented_neighbor_bonus;	/* length bonus per same-rot neigh. */
+  double via_cost;
+  double congestion_penalty;	/* penalty length / unit area */
+  double overlap_penalty_min;	/* penalty length / unit area at start */
+  double overlap_penalty_max;	/* penalty length / unit area at end */
+  double out_of_bounds_penalty;	/* assessed for each component oob */
+  double overall_area_penalty;	/* penalty length / unit area */
+  double matching_neighbor_bonus;	/* length bonus per same-type neigh. */
+  double aligned_neighbor_bonus;	/* length bonus per aligned neigh. */
+  double oriented_neighbor_bonus;	/* length bonus per same-rot neigh. */
 #if 0
-  float pin_alignment_bonus;	/* length bonus per exact alignment */
-  float bound_alignment_bonus;	/* length bonus per exact alignment */
+  double pin_alignment_bonus;	/* length bonus per exact alignment */
+  double bound_alignment_bonus;	/* length bonus per exact alignment */
 #endif
-  float m;			/* annealing stage cutoff constant */
-  float gamma;			/* annealing schedule constant */
+  double m;			/* annealing stage cutoff constant */
+  double gamma;			/* annealing schedule constant */
   int good_ratio;		/* ratio of moves to good moves for halting */
   bool fast;			/* ignore SMD/pin conflicts */
   Coord large_grid_size;	/* snap perturbations to this grid when T is high */
@@ -139,8 +139,8 @@ typedef struct
 {
   ElementTypePtr element;
   enum ewhich which;
-  LocationType DX, DY;		/* for shift */
-  BYTE rotate;			/* for rotate/flip */
+  Coord DX, DY;			/* for shift */
+  unsigned rotate;		/* for rotate/flip */
   ElementTypePtr other;		/* for exchange */
 }
 PerturbationType;
@@ -242,7 +242,7 @@ struct r_neighbor_info
   BoxType trap;
   direction_t search_dir;
 };
-#define ROTATEBOX(box) { LocationType t;\
+#define ROTATEBOX(box) { Coord t;\
     t = (box).X1; (box).X1 = - (box).Y1; (box).Y1 = t;\
     t = (box).X2; (box).X2 = - (box).Y2; (box).Y2 = t;\
     t = (box).X1; (box).X1 =   (box).X2; (box).X2 = t;\
@@ -336,7 +336,7 @@ ComputeCost (NetListTypePtr Nets, double T0, double T)
   double delta4 = 0;		/* alignment bonus */
   double delta5 = 0;		/* total area penalty */
   Cardinal i, j;
-  LocationType minx, maxx, miny, maxy;
+  Coord minx, maxx, miny, maxy;
   bool allpads, allsameside;
   Cardinal thegroup;
   BoxListType bounds = { 0, 0, NULL };	/* save bounding rectangles here */
@@ -401,8 +401,8 @@ ComputeCost (NetListTypePtr Nets, double T0, double T)
     BoxListTypePtr otherside;
     BoxTypePtr box;
     BoxTypePtr lastbox = NULL;
-    BDimension thickness;
-    BDimension clearance;
+    Coord thickness;
+    Coord clearance;
     if (TEST_FLAG (ONSOLDERFLAG, element))
       {
 	thisside = &solderside;
@@ -566,20 +566,13 @@ ComputeCost (NetListTypePtr Nets, double T0, double T)
 	}
       if (element->Name[0].Direction == boxp->element->Name[0].Direction)
 	delta4 += factor * CostParameter.oriented_neighbor_bonus;
-      if (element->VBox.X1 ==
-	  boxp->element->VBox.X1 ||
-	  element->VBox.X1 ==
-	  boxp->element->VBox.X2 ||
-	  element->VBox.X2 ==
-	  boxp->element->VBox.X1 ||
-	  element->VBox.X2 ==
-	  boxp->element->VBox.X2 ||
-	  element->VBox.Y1 ==
-	  boxp->element->VBox.Y1 ||
-	  element->VBox.Y1 ==
-	  boxp->element->VBox.Y2 ||
-	  element->VBox.Y2 ==
-	  boxp->element->VBox.Y1 ||
+      if (element->VBox.X1 == boxp->element->VBox.X1 ||
+	  element->VBox.X1 == boxp->element->VBox.X2 ||
+	  element->VBox.X2 == boxp->element->VBox.X1 ||
+	  element->VBox.X2 == boxp->element->VBox.X2 ||
+	  element->VBox.Y1 == boxp->element->VBox.Y1 ||
+	  element->VBox.Y1 == boxp->element->VBox.Y2 ||
+	  element->VBox.Y2 == boxp->element->VBox.Y1 ||
 	  element->VBox.Y2 == boxp->element->VBox.Y2)
 	delta4 += factor * CostParameter.aligned_neighbor_bonus;
     }
@@ -590,8 +583,8 @@ ComputeCost (NetListTypePtr Nets, double T0, double T)
   }
   /* penalize total area used by this layout */
   {
-    LocationType minX = MAX_COORD, minY = MAX_COORD;
-    LocationType maxX = -MAX_COORD, maxY = -MAX_COORD;
+    Coord minX = MAX_COORD, minY = MAX_COORD;
+    Coord maxX = -MAX_COORD, maxY = -MAX_COORD;
     ELEMENT_LOOP (PCB->Data);
     {
       MAKEMIN (minX, element->VBox.X1);
@@ -602,7 +595,7 @@ ComputeCost (NetListTypePtr Nets, double T0, double T)
     END_LOOP;
     if (minX < maxX && minY < maxY)
       delta5 = CostParameter.overall_area_penalty *
-	sqrt ((double) (maxX - minX) * (maxY - minY) * 0.0001);
+	sqrt (COORD_TO_MIL (maxX - minX) * COORD_TO_MIL (maxY - minY));
   }
   if (T == 5)
     {
@@ -688,7 +681,7 @@ createPerturbation (PointerListTypePtr selected, double T)
 void
 doPerturb (PerturbationType * pt, bool undo)
 {
-  LocationType bbcx, bbcy;
+  Coord bbcx, bbcy;
   /* compute center of element bounding box */
   bbcx = (pt->element->VBox.X1 + pt->element->VBox.X2) / 2;
   bbcy = (pt->element->VBox.Y1 + pt->element->VBox.Y2) / 2;
@@ -697,7 +690,7 @@ doPerturb (PerturbationType * pt, bool undo)
     {
     case SHIFT:
       {
-	LocationType DX = pt->DX, DY = pt->DY;
+	Coord DX = pt->DX, DY = pt->DY;
 	if (undo)
 	  {
 	    DX = -DX;
@@ -708,7 +701,7 @@ doPerturb (PerturbationType * pt, bool undo)
       }
     case ROTATE:
       {
-	BYTE b = pt->rotate;
+	unsigned b = pt->rotate;
 	if (undo)
 	  b = (4 - b) & 3;
 	/* 0 - flip; 1-3, rotate. */
@@ -716,7 +709,7 @@ doPerturb (PerturbationType * pt, bool undo)
 	  RotateElementLowLevel (PCB->Data, pt->element, bbcx, bbcy, b);
 	else
 	  {
-	    LocationType y = pt->element->VBox.Y1;
+	    Coord y = pt->element->VBox.Y1;
 	    MirrorElementCoordinates (PCB->Data, pt->element, 0);
 	    /* mirroring moves the element.  move it back. */
 	    MoveElementLowLevel (PCB->Data, pt->element, 0,
@@ -727,10 +720,10 @@ doPerturb (PerturbationType * pt, bool undo)
     case EXCHANGE:
       {
 	/* first exchange positions */
-	LocationType x1 = pt->element->VBox.X1;
-	LocationType y1 = pt->element->VBox.Y1;
-	LocationType x2 = pt->other->BoundingBox.X1;
-	LocationType y2 = pt->other->BoundingBox.Y1;
+	Coord x1 = pt->element->VBox.X1;
+	Coord y1 = pt->element->VBox.Y1;
+	Coord x2 = pt->other->BoundingBox.X1;
+	Coord y2 = pt->other->BoundingBox.Y1;
 	MoveElementLowLevel (PCB->Data, pt->element, x2 - x1, y2 - y1);
 	MoveElementLowLevel (PCB->Data, pt->other, x1 - x2, y1 - y2);
 	/* then flip both elements if they are on opposite sides */

commit 5456171cbd9129402acfc6596d1cd7b742880324
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit create.[ch], implement Coord

diff --git a/src/action.c b/src/action.c
index f33ca43..93c17a2 100644
--- a/src/action.c
+++ b/src/action.c
@@ -306,8 +306,7 @@ fake;
 
 static struct
 {
-  int X;
-  int Y;
+  Coord X, Y;
   Cardinal Buffer;
   bool Click;
   bool Moving;		/* selected type clicked on */
@@ -544,9 +543,9 @@ FinishStroke (void)
 	case 12589:
 	case 14589:
 	  {
-	    LocationType x = (StrokeBox.X1 + StrokeBox.X2) / 2;
-	    LocationType y = (StrokeBox.Y1 + StrokeBox.Y2) / 2;
-	    int z;
+	    Coord x = (StrokeBox.X1 + StrokeBox.X2) / 2;
+	    Coord y = (StrokeBox.Y1 + StrokeBox.Y2) / 2;
+	    double z;
 	    /* XXX: PCB->MaxWidth and PCB->MaxHeight may be the wrong
 	     *      divisors below. The old code WAS broken, but this
              *      replacement has not been tested for correctness.
@@ -906,11 +905,8 @@ NotifyLine (void)
       else if (type == PAD_TYPE)
 	{
 	  PadTypePtr pad = (PadTypePtr) ptr2;
-	  float d1, d2;
-	  d1 = SQUARE (Crosshair.X - pad->Point1.X) +
-	    SQUARE (Crosshair.Y - pad->Point1.Y);
-	  d2 = SQUARE (Crosshair.X - pad->Point2.X) +
-	    SQUARE (Crosshair.Y - pad->Point2.Y);
+	  double d1 = Distance (Crosshair.X, Crosshair.Y, pad->Point1.X, pad->Point1.Y);
+	  double d2 = Distance (Crosshair.X, Crosshair.Y, pad->Point2.X, pad->Point2.Y);
 	  if (d2 < d1)
 	    {
 	      Crosshair.AttachedLine.Point1 =
@@ -1058,8 +1054,8 @@ NotifyMode (void)
 	  case STATE_THIRD:
 	    {
 	      ArcTypePtr arc;
-	      LocationType wx, wy;
-	      int sa, dir;
+	      Coord wx, wy;
+	      Angle sa, dir;
 
 	      wx = Note.X - Crosshair.AttachedBox.Point1.X;
 	      wy = Note.Y - Crosshair.AttachedBox.Point1.Y;
@@ -1864,15 +1860,13 @@ ActionDRCheck (int argc, char **argv, Coord x, Coord y)
 
   if (gui->drc_gui == NULL || gui->drc_gui->log_drc_overview)
     {
-      Message (_("Rules are minspace %.2f, minoverlap %.2f "
-		 "minwidth %.2f, minsilk %.2f\n"
-		 "min drill %.2f, min annular ring %.2f\n"),
-	       COORD_TO_MIL(PCB->Bloat + 1),
-	       COORD_TO_MIL(PCB->Shrink),
-	       COORD_TO_MIL(PCB->minWid),
-	       COORD_TO_MIL(PCB->minSlk),
-	       COORD_TO_MIL(PCB->minDrill),
-	       COORD_TO_MIL(PCB->minRing));
+      Message (_("%m+Rules are minspace %$mS, minoverlap %$mS "
+		 "minwidth %$mS, minsilk %$mS\n"
+		 "min drill %$mS, min annular ring %$mS\n"),
+               Settings.grid_unit->allow,
+	       PCB->Bloat, PCB->Shrink,
+	       PCB->minWid, PCB->minSlk,
+	       PCB->minDrill, PCB->minRing);
     }
   count = DRCAll ();
   if (gui->drc_gui == NULL || gui->drc_gui->log_drc_overview)
@@ -4046,7 +4040,7 @@ ActionChangeSize (int argc, char **argv, Coord x, Coord y)
   char *delta = ARG (1);
   char *units = ARG (2);
   bool absolute;			/* indicates if absolute size is given */
-  float value;
+  Coord value;
 
   if (function && delta)
     {
@@ -4138,7 +4132,7 @@ ActionChange2ndSize (int argc, char **argv, Coord x, Coord y)
   char *delta = ARG (1);
   char *units = ARG (2);
   bool absolute;
-  float value;
+  Coord value;
 
   if (function && delta)
     {
@@ -4205,7 +4199,7 @@ ActionChangeClearSize (int argc, char **argv, Coord x, Coord y)
   char *delta = ARG (1);
   char *units = ARG (2);
   bool absolute;
-  float value;
+  Coord value;
 
   if (function && delta)
     {
@@ -4280,7 +4274,7 @@ ActionMinMaskGap (int argc, char **argv, Coord x, Coord y)
   char *delta = ARG (1);
   char *units = ARG (2);
   bool absolute;
-  int value;
+  Coord value;
   int flags;
 
   if (!function)
@@ -4364,7 +4358,7 @@ ActionMinClearGap (int argc, char **argv, Coord x, Coord y)
   char *delta = ARG (1);
   char *units = ARG (2);
   bool absolute;
-  int value;
+  Coord value;
   int flags;
 
   if (!function)
@@ -6089,7 +6083,7 @@ ActionPasteBuffer (int argc, char **argv, Coord x, Coord y)
 
 	case F_ToLayout:
 	  {
-	    static int oldx = 0, oldy = 0;
+	    static Coord oldx = 0, oldy = 0;
 	    Coord x, y;
 	    bool absolute;
 
@@ -6466,7 +6460,7 @@ ActionMoveObject (int argc, char **argv, Coord x, Coord y)
   char *x_str = ARG (0);
   char *y_str = ARG (1);
   char *units = ARG (2);
-  LocationType nx, ny;
+  Coord nx, ny;
   bool absolute1, absolute2;
   void *ptr1, *ptr2, *ptr3;
   int type;
@@ -6962,20 +6956,10 @@ them.
 static int
 parse_layout_attribute_units (char *name, int def)
 {
-  const char *as, *units = NULL;
-  int n = 0, v;
-  bool absolute;
-
-  as = AttributeGet (PCB, name);
+  const char *as = AttributeGet (PCB, name);
   if (!as)
     return def;
-
-  sscanf (as, "%d%n", &v, &n);
-  units = as + n;
-  if (! *units)
-    units = NULL;
-  v = GetValue (as, units, &absolute);
-  return v;
+  return GetValue (as, NULL, NULL);
 }
 
 static int
@@ -7046,7 +7030,7 @@ ActionElementList (int argc, char **argv, Coord x, Coord y)
 
   if (!e)
     {
-      int nx, ny, d;
+      Coord nx, ny, d;
 
 #ifdef DEBUG
       printf("  ... Footprint not on board, need to add it.\n");
@@ -7089,7 +7073,7 @@ ActionElementList (int argc, char **argv, Coord x, Coord y)
       printf("  ... Footprint on board, but different from footprint loaded.\n");
 #endif
       int er, pr, i;
-      LocationType mx, my;
+      Coord mx, my;
       ElementType *pe;
 
       /* Different footprint, we need to swap them out.  */
@@ -7587,7 +7571,7 @@ ActionImport (int argc, char **argv, Coord x, Coord y)
     {
       const char *xs, *ys, *units;
       Coord x, y;
-      gchar *buf;
+      char buf[50];
 
       xs = ARG (1);
       ys = ARG (2);
@@ -7613,9 +7597,8 @@ ActionImport (int argc, char **argv, Coord x, Coord y)
 	}
       else if (ys)
 	{
-	  bool absolute;
-	  x = GetValue (xs, units, &absolute);
-	  y = GetValue (ys, units, &absolute);
+	  x = GetValue (xs, units, NULL);
+	  y = GetValue (ys, units, NULL);
 	}
       else
 	{
@@ -7623,12 +7606,10 @@ ActionImport (int argc, char **argv, Coord x, Coord y)
 	  return 1;
 	}
 
-      buf = pcb_g_strdup_printf ("%$ms", x);
+      pcb_sprintf (buf, "%$ms", x);
       AttributePut (PCB, "import::newX", buf);
-      g_free (buf);
-      buf = pcb_g_strdup_printf ("%$ms", y);
+      pcb_sprintf (buf, "%$ms", y);
       AttributePut (PCB, "import::newY", buf);
-      g_free (buf);
       return 0;
     }
 
diff --git a/src/create.c b/src/create.c
index b5081fa..b57f4a5 100644
--- a/src/create.c
+++ b/src/create.c
@@ -47,6 +47,7 @@
 #include "mymem.h"
 #include "misc.h"
 #include "parse_l.h"
+#include "pcb-printf.h"
 #include "polygon.h"
 #include "rtree.h"
 #include "search.h"
@@ -72,7 +73,7 @@ static bool be_lenient = false;
  * some local prototypes
  */
 static void AddTextToElement (TextTypePtr, FontTypePtr,
-			      LocationType, LocationType, BYTE, char *, int,
+			      Coord, Coord, unsigned, char *, int,
 			      FlagType);
 
 /* ---------------------------------------------------------------------------
@@ -237,9 +238,9 @@ CreateNewPCBPost (PCBTypePtr pcb, int use_defaults)
  */
 PinTypePtr
 CreateNewVia (DataTypePtr Data,
-	      LocationType X, LocationType Y,
-	      BDimension Thickness, BDimension Clearance, BDimension Mask,
-	      BDimension DrillingHole, char *Name, FlagType Flags)
+	      Coord X, Coord Y,
+	      Coord Thickness, Coord Clearance, Coord Mask,
+	      Coord DrillingHole, char *Name, FlagType Flags)
 {
   PinTypePtr Via;
 
@@ -247,11 +248,11 @@ CreateNewVia (DataTypePtr Data,
     {
       VIA_LOOP (Data);
       {
-	if (SQUARE (via->X - X) + SQUARE (via->Y - Y) <=
-	    SQUARE (via->DrillingHole / 2 + DrillingHole / 2)) 
+	if (Distance (X, Y, via->X, via->Y) <=
+	    via->DrillingHole / 2 + DrillingHole / 2)
 	  {
-	    Message (_("Dropping via at (%f, %f) because it's hole would overlap with the via "
-		       "at (%f, %f)\n"), COORD_TO_MIL(X), COORD_TO_MIL(Y), COORD_TO_MIL(via->X), COORD_TO_MIL(via->Y));
+	    Message (_("%m+Dropping via at %$mD because it's hole would overlap with the via "
+		       "at %$mD\n"), Settings.grid_unit->allow, X, Y, via->X, via->Y);
 	    return (NULL);		/* don't allow via stacking */
 	  }
       }
@@ -271,9 +272,8 @@ CreateNewVia (DataTypePtr Data,
   Via->DrillingHole = vendorDrillMap (DrillingHole);
   if (Via->DrillingHole != DrillingHole)
     {
-      Message (_
-	       ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n"),
-	       0.01 * Via->DrillingHole, 0.01 * DrillingHole);
+      Message (_("%m+Mapped via drill hole to %$mS from %$mS per vendor table\n"),
+	       Settings.grid_unit->allow, Via->DrillingHole, DrillingHole);
     }
 
   Via->Name = STRDUP (Name);
@@ -290,9 +290,9 @@ CreateNewVia (DataTypePtr Data,
       (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER))
     {
       Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER;
-      Message (_("Increased via thickness to %.2f mils to allow enough copper"
-		 " at (%.2f,%.2f).\n"),
-	       0.01 * Via->Thickness, 0.01 * Via->X, 0.01 * Via->Y);
+      Message (_("%m+Increased via thickness to %$mS to allow enough copper"
+		 " at %$mD.\n"),
+	       Settings.grid_unit->allow, Via->Thickness, Via->X, Via->Y);
     }
 
   SetPinBoundingBox (Via);
@@ -304,8 +304,8 @@ CreateNewVia (DataTypePtr Data,
 
 struct line_info
 {
-  LocationType X1, X2, Y1, Y2;
-  BDimension Thickness;
+  Coord X1, X2, Y1, Y2;
+  Coord Thickness;
   FlagType Flags;
   LineType test, *ans;
   jmp_buf env;
@@ -350,7 +350,7 @@ line_callback (const BoxType * b, void *cl)
 	  i->test.Point1.Y = line->Point2.Y;
 	  i->test.Point2.X = i->X2;
 	  i->test.Point2.Y = i->Y2;
-	  if (IsPointOnLine ((float) i->X1, (float) i->Y1, 0.0, &i->test))
+	  if (IsPointOnLine (i->X1, i->Y1, 0.0, &i->test))
 	    {
 	      i->ans = line;
 	      longjmp (i->env, 1);
@@ -362,7 +362,7 @@ line_callback (const BoxType * b, void *cl)
 	  i->test.Point1.Y = line->Point1.Y;
 	  i->test.Point2.X = i->X2;
 	  i->test.Point2.Y = i->Y2;
-	  if (IsPointOnLine ((float) i->X1, (float) i->Y1, 0.0, &i->test))
+	  if (IsPointOnLine (i->X1, i->Y1, 0.0, &i->test))
 	    {
 	      i->ans = line;
 	      longjmp (i->env, 1);
@@ -374,7 +374,7 @@ line_callback (const BoxType * b, void *cl)
 	  i->test.Point1.Y = line->Point2.Y;
 	  i->test.Point2.X = i->X1;
 	  i->test.Point2.Y = i->Y1;
-	  if (IsPointOnLine ((float) i->X2, (float) i->Y2, 0.0, &i->test))
+	  if (IsPointOnLine (i->X2, i->Y2, 0.0, &i->test))
 	    {
 	      i->ans = line;
 	      longjmp (i->env, 1);
@@ -386,7 +386,7 @@ line_callback (const BoxType * b, void *cl)
 	  i->test.Point1.Y = line->Point1.Y;
 	  i->test.Point2.X = i->X1;
 	  i->test.Point2.Y = i->Y1;
-	  if (IsPointOnLine ((float) i->X2, (float) i->Y2, 0.0, &i->test))
+	  if (IsPointOnLine (i->X2, i->Y2, 0.0, &i->test))
 	    {
 	      i->ans = line;
 	      longjmp (i->env, 1);
@@ -402,9 +402,9 @@ line_callback (const BoxType * b, void *cl)
  */
 LineTypePtr
 CreateDrawnLineOnLayer (LayerTypePtr Layer,
-			LocationType X1, LocationType Y1,
-			LocationType X2, LocationType Y2,
-			BDimension Thickness, BDimension Clearance,
+			Coord X1, Coord Y1,
+			Coord X2, Coord Y2,
+			Coord Thickness, Coord Clearance,
 			FlagType Flags)
 {
   struct line_info info;
@@ -456,9 +456,9 @@ CreateDrawnLineOnLayer (LayerTypePtr Layer,
 
 LineTypePtr
 CreateNewLineOnLayer (LayerTypePtr Layer,
-		      LocationType X1, LocationType Y1,
-		      LocationType X2, LocationType Y2,
-		      BDimension Thickness, BDimension Clearance,
+		      Coord X1, Coord Y1,
+		      Coord X2, Coord Y2,
+		      Coord Thickness, Coord Clearance,
 		      FlagType Flags)
 {
   LineTypePtr Line;
@@ -488,9 +488,9 @@ CreateNewLineOnLayer (LayerTypePtr Layer,
  * creates a new rat-line
  */
 RatTypePtr
-CreateNewRat (DataTypePtr Data, LocationType X1, LocationType Y1,
-	      LocationType X2, LocationType Y2, Cardinal group1,
-	      Cardinal group2, BDimension Thickness, FlagType Flags)
+CreateNewRat (DataTypePtr Data, Coord X1, Coord Y1,
+	      Coord X2, Coord Y2, Cardinal group1,
+	      Cardinal group2, Coord Thickness, FlagType Flags)
 {
   RatTypePtr Line = GetRatMemory (Data);
 
@@ -521,12 +521,12 @@ CreateNewRat (DataTypePtr Data, LocationType X1, LocationType Y1,
  */
 ArcTypePtr
 CreateNewArcOnLayer (LayerTypePtr Layer,
-		     LocationType X1, LocationType Y1,
-		     BDimension width,
-		     BDimension height,
-		     int sa,
-		     int dir, BDimension Thickness,
-		     BDimension Clearance, FlagType Flags)
+		     Coord X1, Coord Y1,
+		     Coord width,
+		     Coord height,
+		     Angle sa,
+		     Angle dir, Coord Thickness,
+		     Coord Clearance, FlagType Flags)
 {
   ArcTypePtr Arc;
 
@@ -565,8 +565,8 @@ CreateNewArcOnLayer (LayerTypePtr Layer,
  */
 PolygonTypePtr
 CreateNewPolygonFromRectangle (LayerTypePtr Layer,
-			       LocationType X1, LocationType Y1,
-			       LocationType X2, LocationType Y2,
+			       Coord X1, Coord Y1,
+			       Coord X2, Coord Y2,
 			       FlagType Flags)
 {
   PolygonTypePtr polygon = CreateNewPolygon (Layer, Flags);
@@ -589,8 +589,8 @@ CreateNewPolygonFromRectangle (LayerTypePtr Layer,
  */
 TextTypePtr
 CreateNewText (LayerTypePtr Layer, FontTypePtr PCBFont,
-	       LocationType X, LocationType Y,
-	       BYTE Direction, int Scale, char *TextString, FlagType Flags)
+	       Coord X, Coord Y,
+	       unsigned Direction, int Scale, char *TextString, FlagType Flags)
 {
   TextType *text;
 
@@ -641,8 +641,7 @@ CreateNewPolygon (LayerTypePtr Layer, FlagType Flags)
  * creates a new point in a polygon
  */
 PointTypePtr
-CreateNewPointInPolygon (PolygonTypePtr Polygon, LocationType X,
-			 LocationType Y)
+CreateNewPointInPolygon (PolygonTypePtr Polygon, Coord X, Coord Y)
 {
   PointTypePtr point = GetPointMemoryInPolygon (Polygon);
 
@@ -673,7 +672,7 @@ CreateNewElement (DataTypePtr Data, ElementTypePtr Element,
 		  FontTypePtr PCBFont,
 		  FlagType Flags,
 		  char *Description, char *NameOnPCB, char *Value,
-		  LocationType TextX, LocationType TextY, BYTE Direction,
+		  Coord TextX, Coord TextY, BYTE Direction,
 		  int TextScale, FlagType TextFlags, bool uniqueName)
 {
 #ifdef DEBUG
@@ -711,9 +710,9 @@ CreateNewElement (DataTypePtr Data, ElementTypePtr Element,
  */
 ArcTypePtr
 CreateNewArcInElement (ElementTypePtr Element,
-		       LocationType X, LocationType Y,
-		       BDimension Width, BDimension Height,
-		       int Angle, int Delta, BDimension Thickness)
+		       Coord X, Coord Y,
+		       Coord Width, Coord Height,
+		       Angle angle, Angle delta, Coord Thickness)
 {
   ArcType *arc;
 
@@ -722,23 +721,18 @@ CreateNewArcInElement (ElementTypePtr Element,
   Element->ArcN ++;
 
   /* set Delta (0,360], StartAngle in [0,360) */
-  if ((Delta = Delta % 360) == 0)
-    Delta = 360;
-  if (Delta < 0)
-    {
-      Angle += Delta;
-      Delta = -Delta;
-    }
-  if ((Angle = Angle % 360) < 0)
-    Angle += 360;
+  angle = NormalizeAngle (angle);
+  delta = NormalizeAngle (delta);
+  if (delta == 0)
+    delta = 360;
 
   /* copy values */
   arc->X = X;
   arc->Y = Y;
   arc->Width = Width;
   arc->Height = Height;
-  arc->StartAngle = Angle;
-  arc->Delta = Delta;
+  arc->StartAngle = angle;
+  arc->Delta = delta;
   arc->Thickness = Thickness;
   arc->ID = ID++;
   return arc;
@@ -749,9 +743,9 @@ CreateNewArcInElement (ElementTypePtr Element,
  */
 LineTypePtr
 CreateNewLineInElement (ElementTypePtr Element,
-			LocationType X1, LocationType Y1,
-			LocationType X2, LocationType Y2,
-			BDimension Thickness)
+			Coord X1, Coord Y1,
+			Coord X2, Coord Y2,
+			Coord Thickness)
 {
   LineType *line;
 
@@ -778,9 +772,9 @@ CreateNewLineInElement (ElementTypePtr Element,
  */
 PinTypePtr
 CreateNewPin (ElementTypePtr Element,
-	      LocationType X, LocationType Y,
-	      BDimension Thickness, BDimension Clearance, BDimension Mask,
-	      BDimension DrillingHole, char *Name, char *Number,
+	      Coord X, Coord Y,
+	      Coord Thickness, Coord Clearance, Coord Mask,
+	      Coord DrillingHole, char *Name, char *Number,
 	      FlagType Flags)
 {
   PinTypePtr pin = GetPinMemory (Element);
@@ -810,27 +804,21 @@ CreateNewPin (ElementTypePtr Element,
     {
       if (pin->DrillingHole < MIN_PINORVIASIZE)
 	{
-	  Message (_
-		   ("Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum allowed size\n"),
-		   UNKNOWN (Number), UNKNOWN (Name),
-		   0.01 * pin->DrillingHole);
+	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is below the minimum allowed size\n"),
+		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
 	  pin->DrillingHole = DrillingHole;
 	}
       else if (pin->DrillingHole > MAX_PINORVIASIZE)
 	{
-	  Message (_
-		   ("Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum allowed size\n"),
-		   UNKNOWN (Number), UNKNOWN (Name),
-		   0.01 * pin->DrillingHole);
+	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is above the maximum allowed size\n"),
+		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
 	  pin->DrillingHole = DrillingHole;
 	}
       else if (!TEST_FLAG (HOLEFLAG, pin)
 	       && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER))
 	{
-	  Message (_
-		   ("Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough copper\n"),
-		   UNKNOWN (Number), UNKNOWN (Name),
-		   0.01 * pin->DrillingHole);
+	  Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS does not leave enough copper\n"),
+		   Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole);
 	  pin->DrillingHole = DrillingHole;
 	}
     }
@@ -841,9 +829,8 @@ CreateNewPin (ElementTypePtr Element,
 
   if (pin->DrillingHole != DrillingHole)
     {
-      Message (_
-	       ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n"),
-	       0.01 * pin->DrillingHole, 0.01 * DrillingHole);
+      Message (_("%m+Mapped pin drill hole to %$mS from %$mS per vendor table\n"),
+	       Settings.grid_unit->allow, pin->DrillingHole, DrillingHole);
     }
 
   return (pin);
@@ -854,9 +841,9 @@ CreateNewPin (ElementTypePtr Element,
  */
 PadTypePtr
 CreateNewPad (ElementTypePtr Element,
-	      LocationType X1, LocationType Y1, LocationType X2,
-	      LocationType Y2, BDimension Thickness, BDimension Clearance,
-	      BDimension Mask, char *Name, char *Number, FlagType Flags)
+	      Coord X1, Coord Y1, Coord X2,
+	      Coord Y2, Coord Thickness, Coord Clearance,
+	      Coord Mask, char *Name, char *Number, FlagType Flags)
 {
   PadTypePtr pad = GetPadMemory (Element);
 
@@ -893,8 +880,8 @@ CreateNewPad (ElementTypePtr Element,
  */
 static void
 AddTextToElement (TextTypePtr Text, FontTypePtr PCBFont,
-		  LocationType X, LocationType Y,
-		  BYTE Direction, char *TextString, int Scale, FlagType Flags)
+		  Coord X, Coord Y,
+		  unsigned Direction, char *TextString, int Scale, FlagType Flags)
 {
   free (Text->TextString);
   Text->TextString = (TextString && *TextString) ? strdup (TextString) : NULL;
@@ -914,8 +901,8 @@ AddTextToElement (TextTypePtr Text, FontTypePtr PCBFont,
  */
 LineTypePtr
 CreateNewLineInSymbol (SymbolTypePtr Symbol,
-		       LocationType X1, LocationType Y1,
-		       LocationType X2, LocationType Y2, BDimension Thickness)
+		       Coord X1, Coord Y1,
+		       Coord X2, Coord Y2, Coord Thickness)
 {
   LineTypePtr line = Symbol->Line;
 
diff --git a/src/create.h b/src/create.h
index ec964fa..ccab272 100644
--- a/src/create.h
+++ b/src/create.h
@@ -44,48 +44,41 @@ PCBTypePtr CreateNewPCB (bool);
 /* Called after PCB->Data->LayerN is set.  Returns zero if no errors,
    else nonzero.  */
 int CreateNewPCBPost (PCBTypePtr, int /* set defaults */);
-PinTypePtr CreateNewVia (DataTypePtr, LocationType, LocationType, BDimension,
-			 BDimension, BDimension, BDimension, char *,
-			 FlagType);
-LineTypePtr CreateDrawnLineOnLayer (LayerTypePtr, LocationType, LocationType,
-				    LocationType, LocationType, BDimension,
-				    BDimension, FlagType);
-LineTypePtr CreateNewLineOnLayer (LayerTypePtr, LocationType, LocationType,
-				  LocationType, LocationType, BDimension,
-				  BDimension, FlagType);
-RatTypePtr CreateNewRat (DataTypePtr, LocationType, LocationType,
-			 LocationType, LocationType, Cardinal, Cardinal,
-			 BDimension, FlagType);
-ArcTypePtr CreateNewArcOnLayer (LayerTypePtr, LocationType, LocationType,
-				BDimension, BDimension, int, int, BDimension, BDimension,
-				FlagType);
-PolygonTypePtr CreateNewPolygonFromRectangle (LayerTypePtr, LocationType,
-					      LocationType, LocationType,
-					      LocationType, FlagType);
-TextTypePtr CreateNewText (LayerTypePtr, FontTypePtr, LocationType,
-			   LocationType, BYTE, int, char *, FlagType);
+PinTypePtr CreateNewVia (DataTypePtr, Coord, Coord, Coord, Coord,
+			 Coord, Coord, char *, FlagType);
+LineTypePtr CreateDrawnLineOnLayer (LayerTypePtr, Coord, Coord, Coord,
+				    Coord, Coord, Coord, FlagType);
+LineTypePtr CreateNewLineOnLayer (LayerTypePtr, Coord, Coord, Coord,
+				  Coord, Coord, Coord, FlagType);
+RatTypePtr CreateNewRat (DataTypePtr, Coord, Coord, Coord,
+			 Coord, Cardinal, Cardinal, Coord, FlagType);
+ArcTypePtr CreateNewArcOnLayer (LayerTypePtr, Coord, Coord, Coord, Coord,
+				Angle, Angle, Coord, Coord, FlagType);
+PolygonTypePtr CreateNewPolygonFromRectangle (LayerTypePtr, Coord,
+					      Coord, Coord,
+					      Coord, FlagType);
+TextTypePtr CreateNewText (LayerTypePtr, FontTypePtr, Coord,
+			   Coord, unsigned, int, char *, FlagType);
 PolygonTypePtr CreateNewPolygon (LayerTypePtr, FlagType);
 PointTypePtr CreateNewPointInPolygon (PolygonTypePtr,
-				      LocationType, LocationType);
+				      Coord, Coord);
 PolygonType *CreateNewHoleInPolygon (PolygonType *polygon);
 ElementTypePtr CreateNewElement (DataTypePtr, ElementTypePtr,
 				 FontTypePtr, FlagType, char *, char *,
-				 char *, LocationType, LocationType, BYTE,
+				 char *, Coord, Coord, BYTE,
 				 int, FlagType, bool);
-LineTypePtr CreateNewLineInElement (ElementTypePtr, LocationType,
-				    LocationType, LocationType, LocationType,
-				    BDimension);
-ArcTypePtr CreateNewArcInElement (ElementTypePtr, LocationType, LocationType,
-				  BDimension, BDimension, int, int,
-				  BDimension);
-PinTypePtr CreateNewPin (ElementTypePtr, LocationType, LocationType,
-			 BDimension, BDimension, BDimension, BDimension,
+LineTypePtr CreateNewLineInElement (ElementTypePtr, Coord, Coord,
+				    Coord, Coord, Coord);
+ArcTypePtr CreateNewArcInElement (ElementTypePtr, Coord, Coord,
+				  Coord, Coord, Angle, Angle, Coord);
+PinTypePtr CreateNewPin (ElementTypePtr, Coord, Coord,
+			 Coord, Coord, Coord, Coord,
 			 char *, char *, FlagType);
-PadTypePtr CreateNewPad (ElementTypePtr, LocationType, LocationType,
-			 LocationType, LocationType, BDimension, BDimension,
-			 BDimension, char *, char *, FlagType);
-LineTypePtr CreateNewLineInSymbol (SymbolTypePtr, LocationType, LocationType,
-				   LocationType, LocationType, BDimension);
+PadTypePtr CreateNewPad (ElementTypePtr, Coord, Coord,
+			 Coord, Coord, Coord, Coord,
+			 Coord, char *, char *, FlagType);
+LineTypePtr CreateNewLineInSymbol (SymbolTypePtr, Coord, Coord,
+				   Coord, Coord, Coord);
 void CreateDefaultFont (PCBTypePtr);
 RubberbandTypePtr CreateNewRubberbandEntry (LayerTypePtr,
 					    LineTypePtr, PointTypePtr);

commit 8c1777bf0e9fbcbb06d448847dcc09052fd030e6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit line.[ch], intersect.c, implement Coord

diff --git a/src/intersect.c b/src/intersect.c
index e7612e9..a3ee03f 100644
--- a/src/intersect.c
+++ b/src/intersect.c
@@ -66,9 +66,9 @@ static int nextpwrof2 (int i);
  */
 typedef struct
 {
-  LocationType left, right;
+  Coord left, right;
   int covered;
-  int area;
+  Coord area;
 }
 SegmentTreeNode;
 
@@ -81,7 +81,7 @@ SegmentTree;
 
 typedef struct
 {
-  LocationType *p;
+  Coord *p;
   int size;
 }
 LocationList;
@@ -93,11 +93,11 @@ static LocationList
 createSortedYList (BoxListTypePtr boxlist)
 {
   LocationList yCoords;
-  LocationType last;
+  Coord last;
   int i, n;
   /* create sorted list of Y coordinates */
   yCoords.size = 2 * boxlist->BoxN;
-  yCoords.p = (LocationType *)calloc (yCoords.size, sizeof (*yCoords.p));
+  yCoords.p = (Coord *)calloc (yCoords.size, sizeof (*yCoords.p));
   for (i = 0; i < boxlist->BoxN; i++)
     {
       yCoords.p[2 * i] = boxlist->Box[i].Y1;
@@ -117,7 +117,7 @@ createSortedYList (BoxListTypePtr boxlist)
  * Create an empty segment tree from the given sorted list of uniq y coords.
  */
 static SegmentTree
-createSegmentTree (LocationType * yCoords, int N)
+createSegmentTree (Coord * yCoords, int N)
 {
   SegmentTree st;
   int i;
@@ -144,9 +144,9 @@ createSegmentTree (LocationType * yCoords, int N)
 }
 
 void
-insertSegment (SegmentTree * st, int n, LocationType Y1, LocationType Y2)
+insertSegment (SegmentTree * st, int n, Coord Y1, Coord Y2)
 {
-  LocationType discriminant;
+  Coord discriminant;
   if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2)
     {
       st->nodes[n].covered++;
@@ -168,9 +168,9 @@ insertSegment (SegmentTree * st, int n, LocationType Y1, LocationType Y2)
 }
 
 void
-deleteSegment (SegmentTree * st, int n, LocationType Y1, LocationType Y2)
+deleteSegment (SegmentTree * st, int n, Coord Y1, Coord Y2)
 {
-  LocationType discriminant;
+  Coord discriminant;
   if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2)
     {
       assert (st->nodes[n].covered);
@@ -223,7 +223,7 @@ ComputeUnionArea (BoxListTypePtr boxlist)
   Cardinal i, j;
   LocationList yCoords;
   SegmentTree segtree;
-  LocationType lastX;
+  Coord lastX;
   double area = 0.0;
 
   if (boxlist->BoxN == 0)
@@ -300,7 +300,7 @@ compareright (const void *ptr1, const void *ptr2)
 static int
 comparepos (const void *ptr1, const void *ptr2)
 {
-  return *((LocationType *) ptr1) - *((LocationType *) ptr2);
+  return *((Coord *) ptr1) - *((Coord *) ptr2);
 }
 static int
 nextpwrof2 (int n)
diff --git a/src/line.c b/src/line.c
index 7da09dc..22efc2b 100644
--- a/src/line.c
+++ b/src/line.c
@@ -50,7 +50,7 @@
 
 RCSID ("$Id$");
 
-static float drc_lines (PointTypePtr end, bool way);
+static double drc_lines (PointTypePtr end, bool way);
 
 /* ---------------------------------------------------------------------------
  * Adjust the attached line to 45 degrees if necessary
@@ -95,9 +95,9 @@ AdjustAttachedLine (void)
 void
 FortyFiveLine (AttachedLineTypePtr Line)
 {
-  LocationType dx, dy, min;
-  BYTE direction = 0;
-  float m;
+  Coord dx, dy, min;
+  unsigned direction = 0;
+  double m;
 
   /* first calculate direction of line */
   dx = Crosshair.X - Line->Point1.X;
@@ -113,7 +113,7 @@ FortyFiveLine (AttachedLineTypePtr Line)
     }
   else
     {
-      m = (float) dy / (float) dx;
+      m = (double) dy / dx;
       direction = 2;
       if (m > TAN_30_DEGREE)
 	direction = m > TAN_60_DEGREE ? 0 : 1;
@@ -168,9 +168,9 @@ FortyFiveLine (AttachedLineTypePtr Line)
  *  adjusts the insert lines to make them 45 degrees as necessary
  */
 void
-AdjustTwoLine (int way)
+AdjustTwoLine (bool way)
 {
-  LocationType dx, dy;
+  Coord dx, dy;
   AttachedLineTypePtr line = &Crosshair.AttachedLine;
 
   if (Crosshair.AttachedLine.State == STATE_FIRST)
@@ -284,12 +284,12 @@ drcArc_callback (const BoxType * b, void *cl)
  * changes the position of the input point to the best answer.
  */
 
-static float
+static double
 drc_lines (PointTypePtr end, bool way)
 {
-  float f, s, f2, s2, len, best;
-  LocationType dx, dy, temp, last, length;
-  LocationType temp2, last2, length2;
+  double f, s, f2, s2, len, best;
+  Coord dx, dy, temp, last, length;
+  Coord temp2, last2, length2;
   LineType line1, line2;
   Cardinal group, comp;
   struct drc_info info;
@@ -444,7 +444,7 @@ drc_lines (PointTypePtr end, bool way)
 	      f2 += s2;
 	      len = (line2.Point2.X - line1.Point1.X);
 	      len *= len;
-	      len += (float) (line2.Point2.Y - line1.Point1.Y) *
+	      len += (double) (line2.Point2.Y - line1.Point1.Y) *
 		(line2.Point2.Y - line1.Point1.Y);
 	      if (len > best)
 		{
@@ -485,7 +485,7 @@ EnforceLineDRC (void)
 {
   PointType r45, rs;
   bool shift;
-  float r1, r2;
+  double r1, r2;
 
   /* Silence a bogus compiler warning by storing this in a variable */
   int layer_idx = INDEXOFCURRENT;
diff --git a/src/line.h b/src/line.h
index a59f1bb..82db33a 100644
--- a/src/line.h
+++ b/src/line.h
@@ -38,7 +38,7 @@
  * prototypes
  */
 void AdjustAttachedLine (void);
-void AdjustTwoLine (int);
+void AdjustTwoLine (bool);
 void FortyFiveLine (AttachedLineTypePtr);
 void EnforceLineDRC (void);
 #endif

commit 3d0d2c0a0edd60ec445a64e1be53cd7c6628dcea
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit find.[ch], implement Coord
    
    Note that this commits brings major simplifications to some
    DRC functions. My tests show everything okay, but there will
    likely be some bugs (or bug fixes) as a result of this
    commit.

diff --git a/src/find.c b/src/find.c
index a3fbc1c..2b47874 100644
--- a/src/find.c
+++ b/src/find.c
@@ -332,7 +332,7 @@ static bool PrintAndSelectUnusedPinsAndPadsOfElement (ElementTypePtr,
                                                          FILE *);
 static void DrawNewConnections (void);
 static void DumpList (void);
-static void LocateError (LocationType *, LocationType *);
+static void LocateError (Coord *, Coord *);
 static void BuildObjectList (int *, long int **, int **);
 static void GotoError (void);
 static bool DRCFind (int, void *, void *, void *);
@@ -1313,7 +1313,7 @@ PVTouchesLine (LineTypePtr line)
 
 /* reduce arc start angle and delta to 0..360 */
 static void
-normalize_angles (int *sa, int *d)
+normalize_angles (Angle *sa, Angle *d)
 {
   if (*d < 0)
     {
@@ -1322,44 +1322,30 @@ normalize_angles (int *sa, int *d)
     }
   if (*d > 360) /* full circle */
     *d = 360;
-  if (*sa < 0)
-    *sa = 360 - ((-*sa) % 360);
-  if (*sa >= 360)
-    *sa %= 360;
+  *sa = NormalizeAngle (*sa);
 }
 
 static int
 radius_crosses_arc (double x, double y, ArcTypePtr arc)
 {
   double alpha = atan2 (y - arc->Y, -x + arc->X) * RAD_TO_DEG;
-  int sa = arc->StartAngle, d = arc->Delta;
+  Angle sa = arc->StartAngle, d = arc->Delta;
 
   normalize_angles (&sa, &d);
   if (alpha < 0)
     alpha += 360;
-  if ((double)sa <= alpha)
-    return (double)(sa + d) >= alpha;
-  return (double)(sa + d - 360) >= alpha;
+  if (sa <= alpha)
+    return (sa + d) >= alpha;
+  return (sa + d - 360) >= alpha;
 }
 
 static void
-get_arc_ends (double *box, ArcTypePtr arc)
+get_arc_ends (Coord *box, ArcTypePtr arc)
 {
-  double ca, sa, angle;
-
-  angle  = arc->StartAngle;
-  angle *= M180;
-  ca = cos (angle);
-  sa = sin (angle);
-  box[0] = arc->X - arc->Width * ca;
-  box[1] = arc->Y + arc->Height * sa;
-
-  angle  = arc->StartAngle + arc->Delta;
-  angle *= M180;
-  ca = cos (angle);
-  sa = sin (angle);
-  box[2] = arc->X - arc->Width * ca;
-  box[3] = arc->Y + arc->Height * sa;
+  box[0] = arc->X - arc->Width  * cos (M180 * arc->StartAngle);
+  box[1] = arc->Y + arc->Height * sin (M180 * arc->StartAngle);
+  box[2] = arc->X - arc->Width  * cos (M180 * (arc->StartAngle + arc->Delta));
+  box[3] = arc->Y + arc->Height * sin (M180 * (arc->StartAngle + arc->Delta));
 }
 /* ---------------------------------------------------------------------------
  * check if two arcs intersect
@@ -1390,70 +1376,60 @@ static bool
 ArcArcIntersect (ArcTypePtr Arc1, ArcTypePtr Arc2)
 {
   double x, y, dx, dy, r1, r2, a, d, l, t, t1, t2, dl;
-  LocationType pdx, pdy;
-  double box[4];
+  Coord pdx, pdy;
+  Coord box[8];
 
-  t = 0.5 * Arc1->Thickness + Bloat;
-  if (t < 0) /* too thin arc */
-    return (false);
+  t  = 0.5 * Arc1->Thickness + Bloat;
   t2 = 0.5 * Arc2->Thickness;
   t1 = t2 + Bloat;
-  if (t1 < 0) /* too thin arc */
-    return (false);
+
+  /* too thin arc */
+  if (t < 0 || t1 < 0)
+    return false;
+
   /* try the end points first */
-  get_arc_ends (box, Arc1);
-  if (IsPointOnArc ((float) box[0], (float) box[1], (float)t, Arc2)
-      || IsPointOnArc ((float) box[2], (float) box[3], (float)t, Arc2))
-    return (true);
+  get_arc_ends (&box[0], Arc1);
+  get_arc_ends (&box[4], Arc2);
+  if (IsPointOnArc (box[0], box[1], t, Arc2)
+      || IsPointOnArc (box[2], box[3], t, Arc2)
+      || IsPointOnArc (box[4], box[5], t, Arc1)
+      || IsPointOnArc (box[6], box[7], t, Arc1))
+    return true;
 
-  get_arc_ends (box, Arc2);
-  if (IsPointOnArc ((float) box[0], (float) box[1], (float)t1, Arc1)
-      || IsPointOnArc ((float) box[2], (float) box[3], (float)t1, Arc1))
-    return (true);
   pdx = Arc2->X - Arc1->X;
   pdy = Arc2->Y - Arc1->Y;
-  l = pdx * pdx + pdy * pdy;
+  dl = Distance (Arc1->X, Arc1->Y, Arc2->X, Arc2->Y);
   /* concentric arcs, simpler intersection conditions */
-  if (l < 0.5)
+  if (dl < 0.5)
     {
       if ((Arc1->Width - t >= Arc2->Width - t2
-           && Arc1->Width - t <=
-           Arc2->Width + t2)
-          || (Arc1->Width + t >=
-              Arc2->Width - t2 && Arc1->Width + t <= Arc2->Width + t2))
+           && Arc1->Width - t <= Arc2->Width + t2)
+          || (Arc1->Width + t >= Arc2->Width - t2
+              && Arc1->Width + t <= Arc2->Width + t2))
         {
-	  int sa1 = Arc1->StartAngle, d1 = Arc1->Delta;
-	  int sa2 = Arc2->StartAngle, d2 = Arc2->Delta;
+	  Angle sa1 = Arc1->StartAngle, d1 = Arc1->Delta;
+	  Angle sa2 = Arc2->StartAngle, d2 = Arc2->Delta;
 	  /* NB the endpoints have already been checked,
 	     so we just compare the angles */
 
 	  normalize_angles (&sa1, &d1);
 	  normalize_angles (&sa2, &d2);
-	  /* cases like sa1 == sa2 are catched when checking the endpoints */
+	  /* sa1 == sa2 was caught when checking endpoints */
 	  if (sa1 > sa2)
-	    {
-	      if (sa1 < sa2 + d2)
-		return (true);
-	      if (sa1 + d1 > 360 && sa1 + d1 - 360 > sa2)
-		return (true);
-	    }
+            if (sa1 < sa2 + d2 || sa1 + d1 - 360 > sa2)
+              return true;
 	  if (sa2 > sa1)
-	    {
-	      if (sa2 < sa1 + d1)
-		return (true);
-	      if (sa2 + d2 > 360 && sa2 + d2 - 360 > sa1)
-		return (true);
-	    }
+	    if (sa2 < sa1 + d1 || sa2 + d2 - 360 > sa1)
+              return true;
         }
-      return (false);
+      return false;
     }
   r1 = Arc1->Width;
   r2 = Arc2->Width;
-  dl = sqrt (l);
-  if (dl > r1 + r2 || dl + r1 < r2
-      || dl + r2 < r1) /* arcs centerlines are too far or too near */
+  /* arcs centerlines are too far or too near */
+  if (dl > r1 + r2 || dl + r1 < r2 || dl + r2 < r1)
     {
-      /* check the nearst to the other arc center point */
+      /* check the nearest to the other arc's center point */
       dx = pdx * r1 / dl;
       dy = pdy * r1 / dl;
       if (dl + r1 < r2) /* Arc1 inside Arc2 */
@@ -1463,9 +1439,8 @@ ArcArcIntersect (ArcTypePtr Arc1, ArcTypePtr Arc2)
 	}
 
       if (radius_crosses_arc (Arc1->X + dx, Arc1->Y + dy, Arc1)
-	  && IsPointOnArc ((float)(Arc1->X + dx), (float)(Arc1->Y + dy),
-			   (float)t, Arc2))
-	return (true);
+	  && IsPointOnArc (Arc1->X + dx, Arc1->Y + dy, t, Arc2))
+	return true;
 
       dx = - pdx * r2 / dl;
       dy = - pdy * r2 / dl;
@@ -1476,12 +1451,12 @@ ArcArcIntersect (ArcTypePtr Arc1, ArcTypePtr Arc2)
 	}
 
       if (radius_crosses_arc (Arc2->X + dx, Arc2->Y + dy, Arc2)
-	  && IsPointOnArc ((float)(Arc2->X + dx), (float)(Arc2->Y + dy),
-			   (float)t1, Arc1))
-	return (true);
-      return (false);
+	  && IsPointOnArc (Arc2->X + dx, Arc2->Y + dy, t1, Arc1))
+	return true;
+      return false;
     }
 
+  l = dl * dl;
   r1 *= r1;
   r2 *= r2;
   a = 0.5 * (r1 - r2 + l) / l;
@@ -1498,19 +1473,19 @@ ArcArcIntersect (ArcTypePtr Arc1, ArcTypePtr Arc2)
   dx = d * pdx;
   dy = d * pdy;
   if (radius_crosses_arc (x + dy, y - dx, Arc1)
-      && IsPointOnArc ((float)(x + dy), (float)(y - dx), (float)t, Arc2))
-    return (true);
+      && IsPointOnArc (x + dy, y - dx, t, Arc2))
+    return true;
   if (radius_crosses_arc (x + dy, y - dx, Arc2)
-      && IsPointOnArc ((float)(x + dy), (float)(y - dx), (float)t1, Arc1))
-    return (true);
+      && IsPointOnArc (x + dy, y - dx, t1, Arc1))
+    return true;
 
   if (radius_crosses_arc (x - dy, y + dx, Arc1)
-      && IsPointOnArc ((float)(x - dy), (float)(y + dx), (float)t, Arc2))
-    return (true);
+      && IsPointOnArc (x - dy, y + dx, t, Arc2))
+    return true;
   if (radius_crosses_arc (x - dy, y + dx, Arc2)
-      && IsPointOnArc ((float)(x - dy), (float)(y + dx), (float)t1, Arc1))
-    return (true);
-  return (false);
+      && IsPointOnArc (x - dy, y + dx, t1, Arc1))
+    return true;
+  return false;
 }
 
 /* ---------------------------------------------------------------------------
@@ -1527,23 +1502,21 @@ IsRatPointOnLineEnd (PointTypePtr Point, LineTypePtr Line)
 }
 
 static void 
-form_slanted_rectangle(PointType p[4],LineTypePtr l)
+form_slanted_rectangle (PointType p[4], LineTypePtr l)
 /* writes vertices of a squared line */
 {
-   int dX= l->Point2.X - l->Point1.X, dY = l->Point2.Y - l->Point1.Y, 
-     w = l->Thickness;
-   double dwx, dwy;
-   if (dY == 0)
-     {
-       dwx = w / 2; dwy = 0;
-     }
-    else if (dX == 0)
+   double dwx = 0, dwy = 0;
+   if (l->Point1.Y == l->Point2.Y)
+     dwx = l->Thickness / 2.0;
+   else if (l->Point1.X == l->Point2.X)
+     dwy = l->Thickness / 2.0;
+   else 
      {
-       dwx = 0; dwy = w / 2;
-     }
-    else 
-     {double r = sqrt (dX * (double) dX + dY * (double) dY) * 2;
-       dwx = w / r * dX; dwy =  w / r * dY;
+       Coord dX = l->Point2.X - l->Point1.X;
+       Coord dY = l->Point2.Y - l->Point1.Y;
+       double r = Distance (l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y);
+       dwx = l->Thickness / 2.0 / r * dX;
+       dwy = l->Thickness / 2.0 / r * dY;
      }
     p[0].X = l->Point1.X - dwx + dwy; p[0].Y = l->Point1.Y - dwy - dwx;
     p[1].X = l->Point1.X - dwx - dwy; p[1].Y = l->Point1.Y - dwy + dwx;
@@ -1608,167 +1581,83 @@ form_slanted_rectangle(PointType p[4],LineTypePtr l)
 bool
 LineLineIntersect (LineTypePtr Line1, LineTypePtr Line2)
 {
-  register float dx, dy, dx1, dy1, s, r;
+  double s, r;
+  double line1_dx, line1_dy, line2_dx, line2_dy,
+         point1_dx, point1_dy, point2_dx, point2_dy;
   if (TEST_FLAG (SQUAREFLAG, Line1))/* pretty reckless recursion */
     {
-      PointType p[4];form_slanted_rectangle(p,Line1);
-      return IsLineInQuadrangle(p,Line2);
+      PointType p[4];
+      form_slanted_rectangle (p, Line1);
+      return IsLineInQuadrangle (p, Line2);
     }
   /* here come only round Line1 because IsLineInQuadrangle()
      calls LineLineIntersect() with first argument rounded*/
   if (TEST_FLAG (SQUAREFLAG, Line2))
     {
-      PointType p[4];form_slanted_rectangle(p,Line2);
-      return IsLineInQuadrangle(p,Line1);
+      PointType p[4];
+      form_slanted_rectangle (p, Line2);
+      return IsLineInQuadrangle (p, Line1);
     }
   /* now all lines are round */
 
-#if 0
-  if (Line1->BoundingBox.X1 - Bloat > Line2->BoundBoxing.X2
-      || Line1->BoundingBox.X2 + Bloat < Line2->BoundingBox.X1
-      || Line1->BoundingBox.Y1 - Bloat < Line2->BoundingBox.Y2
-      || Line1->BoundingBox.Y2 + Bloat < Line2->BoundingBox.Y1)
-    return false;
-#endif
+  /* Check endpoints: this provides a quick exit, catches
+   *  cases where the "real" lines don't intersect but the
+   *  thick lines touch, and ensures that the dx/dy business
+   *  below does not cause a divide-by-zero. */
+  if (IsPointInPad (Line2->Point1.X, Line2->Point1.Y,
+                    MAX (Line2->Thickness / 2 + Bloat, 0),
+                    (PadTypePtr) Line1)
+       || IsPointInPad (Line2->Point2.X, Line2->Point2.Y,
+                        MAX (Line2->Thickness / 2 + Bloat, 0),
+                        (PadTypePtr) Line1)
+       || IsPointInPad (Line1->Point1.X, Line1->Point1.Y,
+                        MAX (Line1->Thickness / 2 + Bloat, 0),
+                        (PadTypePtr) Line2)
+       || IsPointInPad (Line1->Point2.X, Line1->Point2.Y,
+                        MAX (Line1->Thickness / 2 + Bloat, 0),
+                        (PadTypePtr) Line2))
+    return true;
 
   /* setup some constants */
-  dx = (float) (Line1->Point2.X - Line1->Point1.X);
-  dy = (float) (Line1->Point2.Y - Line1->Point1.Y);
-  dx1 = (float) (Line1->Point1.X - Line2->Point1.X);
-  dy1 = (float) (Line1->Point1.Y - Line2->Point1.Y);
-  s = dy1 * dx - dx1 * dy;
-
-  r =
-    dx * (float) (Line2->Point2.Y -
-                  Line2->Point1.Y) -
-    dy * (float) (Line2->Point2.X - Line2->Point1.X);
-
-  /* handle parallel lines */
+  line1_dx = Line1->Point2.X - Line1->Point1.X;
+  line1_dy = Line1->Point2.Y - Line1->Point1.Y;
+  line2_dx = Line2->Point2.X - Line2->Point1.X;
+  line2_dy = Line2->Point2.Y - Line2->Point1.Y;
+  point1_dx = Line1->Point1.X - Line2->Point1.X;
+  point1_dy = Line1->Point1.Y - Line2->Point1.Y;
+  point2_dx = Line1->Point2.X - Line2->Point2.X;
+  point2_dy = Line1->Point2.Y - Line2->Point2.Y;
+
+  /* If either line is a point, we have failed already, since the
+   *   endpoint check above will have caught an "intersection". */
+  if ((line1_dx == 0 && line1_dy == 0)
+      || (line2_dx == 0 && line2_dy == 0))
+    return false;
+
+  /* set s to cross product of Line1 and the line
+   *   Line1.Point1--Line2.Point1 (as vectors) */
+  s = point1_dy * line1_dx - point1_dx * line1_dy;
+
+  /* set r to cross product of both lines (as vectors) */
+  r = line1_dx * line2_dy - line1_dy * line2_dx;
+
+  /* No cross product means parallel lines, or maybe Line2 is
+   *  zero-length. In either case, since we did a bounding-box
+   *  check before getting here, the above IsPointInPad() checks
+   *  will have caught any intersections. */
   if (r == 0.0)
-    {
-      /* at least one of the two end points of one segment
-       * has to have a minimum distance to the other segment
-       *
-       * a first quick check is to see if the distance between
-       * the two lines is less then their half total thickness
-       */
-      register float distance;
-
-      /* perhaps line 1 is really just a point */
-      if ((dx == 0) && (dy == 0))
-        return IsPointInPad
-                (Line1->Point1.X,
-                 Line1->Point1.Y,
-                 MAX (Line1->Thickness / 2 +
-                      Bloat, 0),
-                 (PadTypePtr) Line2);
-      s = s * s / (dx * dx + dy * dy);
-
-
-      distance =
-        MAX ((float) 0.5 *
-             (Line1->Thickness + Line2->Thickness) + Bloat, 0.0);
-      distance *= distance;
-      if (s > distance)
-        return (false);
-      if (IsPointInPad (Line2->Point1.
-                               X,
-                               Line2->Point1.
-                               Y,
-                               MAX (Line2->
-                                    Thickness
-                                    / 2 +
-                                    Bloat, 0),
-                               (PadTypePtr)
-                               Line1)
-           || IsPointInPad (Line2->
-                                  Point2.X,
-                                  Line2->
-                                  Point2.Y,
-                                  MAX (Line2->
-                                       Thickness
-                                       / 2 + Bloat, 0), (PadTypePtr) Line1))
-        return (true);
-      return ((IsPointInPad (Line1->Point1.
-                               X,
-                               Line1->Point1.
-                               Y,
-                               MAX (Line1->
-                                    Thickness
-                                    / 2 +
-                                    Bloat, 0),
-                               (PadTypePtr)
-                               Line2)
-           || IsPointInPad (Line1->
-                                  Point2.X,
-                                  Line1->
-                                  Point2.Y,
-                                  MAX (Line1->
-                                       Thickness
-                                       / 2 + Bloat, 0), (PadTypePtr) Line2)));
-    }
-  else
-    {
-      s /= r;
-      r =
-        (dy1 *
-         (float) (Line2->Point2.X -
-                  Line2->Point1.X) -
-         dx1 * (float) (Line2->Point2.Y - Line2->Point1.Y)) / r;
-
-      /* intersection is at least on AB */
-      if (r >= 0.0 && r <= 1.0)
-        {
-          if (s >= 0.0 && s <= 1.0)
-            return (true);
+    return false;
 
-          /* intersection on AB and extension of CD */
-          return (s < 0.0 ?
-                  IsPointInPad
-                  (Line2->Point1.X,
-                   Line2->Point1.Y,
-                   MAX (0.5 *
-                        Line2->Thickness +
-                        Bloat, 0.0),
-                   (PadTypePtr)Line1) :
-                  IsPointInPad
-                  (Line2->Point2.X,
-                   Line2->Point2.Y,
-                   MAX (0.5 * Line2->Thickness + Bloat, 0.0), (PadTypePtr)Line1));
-        }
+  s /= r;
+  r = (point1_dy * line2_dx - point1_dx * line2_dy) / r;
 
-      /* intersection is at least on CD */
-      if (s >= 0.0 && s <= 1.0)
-        {
-          /* intersection on CD and extension of AB */
-          return (r < 0.0 ?
-                  IsPointInPad
-                  (Line1->Point1.X,
-                   Line1->Point1.Y,
-                   MAX (Line1->Thickness /
-                        2.0 + Bloat, 0.0),
-                   (PadTypePtr)Line2) :
-                  IsPointInPad
-                  (Line1->Point2.X,
-                   Line1->Point2.Y,
-                   MAX (Line1->Thickness / 2.0 + Bloat, 0.0), (PadTypePtr)Line2));
-        }
+  /* intersection is at least on AB */
+  if (r >= 0.0 && r <= 1.0)
+    return (s >= 0.0 && s <= 1.0);
 
-      /* no intersection of zero-width lines but maybe of thick lines;
-       * Must check each end point to exclude intersection
-       */
-      if (IsPointInPad (Line1->Point1.X, Line1->Point1.Y,
-                         Line1->Thickness / 2.0 + Bloat, (PadTypePtr)Line2))
-        return true;
-      if (IsPointInPad (Line1->Point2.X, Line1->Point2.Y,
-                         Line1->Thickness / 2.0 + Bloat, (PadTypePtr)Line2))
-        return true;
-      if (IsPointInPad (Line2->Point1.X, Line2->Point1.Y,
-                         Line2->Thickness / 2.0 + Bloat, (PadTypePtr)Line1))
-        return true;
-      return IsPointInPad (Line2->Point2.X, Line2->Point2.Y,
-                            Line2->Thickness / 2.0 + Bloat, (PadTypePtr)Line1);
-    }
+  /* intersection is at least on CD */
+  /* [removed this case since it always returns false --asp] */
+  return false;
 }
 
 /*---------------------------------------------------
@@ -2912,13 +2801,10 @@ DoIt (bool AndRats, bool AndDraw)
       /* lookup connections; these are the steps (2) to (4)
        * from the description
        */
-      newone = LookupPVConnectionsToPVList ();
-      if (!newone)
-        newone = LookupLOConnectionsToPVList (AndRats);
-      if (!newone)
-        newone = LookupLOConnectionsToLOList (AndRats);
-      if (!newone)
-        newone = LookupPVConnectionsToLOList (AndRats);
+      newone = LookupPVConnectionsToPVList () ||
+               LookupLOConnectionsToPVList (AndRats) ||
+               LookupLOConnectionsToLOList (AndRats) ||
+               LookupPVConnectionsToLOList (AndRats);
       if (AndDraw)
         DrawNewConnections ();
     }
@@ -3172,8 +3058,7 @@ DrawNewConnections (void)
           /* draw all new polygons */
           position = PolygonList[layer].DrawLocation;
           for (; position < PolygonList[layer].Number; position++)
-            DrawPolygon
-              (LAYER_PTR (layer), POLYGONLIST_ENTRY (layer, position));
+            DrawPolygon (LAYER_PTR (layer), POLYGONLIST_ENTRY (layer, position));
           PolygonList[layer].DrawLocation = PolygonList[layer].Number;
         }
     }
@@ -3340,8 +3225,7 @@ ListStart (int type, void *ptr1, void *ptr2, void *ptr3)
  * also the action is marked as undoable if AndDraw is true
  */
 void
-LookupConnection (LocationType X, LocationType Y, bool AndDraw,
-                  BDimension Range, int which_flag)
+LookupConnection (Coord X, Coord Y, bool AndDraw, Coord Range, int which_flag)
 {
   void *ptr1, *ptr2, *ptr3;
   char *name;
@@ -3619,7 +3503,7 @@ DumpList (void)
 static bool
 DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
 {
-  LocationType x, y;
+  Coord x, y;
   int object_count;
   long int *object_id_list;
   int *object_type_list;
@@ -3779,7 +3663,7 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
               int type, void *ptr1, void *ptr2)
 {
   char *message;
-  LocationType x, y;
+  Coord x, y;
   int object_count;
   long int *object_id_list;
   int *object_type_list;
@@ -3887,7 +3771,7 @@ doIsBad:
 int
 DRCAll (void)
 {
-  LocationType x, y;
+  Coord x, y;
   int object_count;
   long int *object_id_list;
   int *object_type_list;
@@ -4371,7 +4255,7 @@ DRCAll (void)
  * Locate the coordinatates of offending item (thing)
  */
 static void
-LocateError (LocationType *x, LocationType *y)
+LocateError (Coord *x, Coord *y)
 {
   switch (thing_type)
     {
@@ -4469,7 +4353,7 @@ BuildObjectList (int *object_count, long int **object_id_list, int **object_type
 static void
 GotoError (void)
 {
-  LocationType X, Y;
+  Coord X, Y;
 
   LocateError (&X, &Y);
 
diff --git a/src/find.h b/src/find.h
index 9560bd9..d2be7ac 100644
--- a/src/find.h
+++ b/src/find.h
@@ -52,7 +52,7 @@ bool ArcPadIntersect (ArcTypePtr, PadTypePtr);
 bool IsPolygonInPolygon (PolygonTypePtr, PolygonTypePtr);
 void LookupElementConnections (ElementTypePtr, FILE *);
 void LookupConnectionsToAllElements (FILE *);
-void LookupConnection (LocationType, LocationType, bool, BDimension, int);
+void LookupConnection (Coord, Coord, bool, Coord, int);
 void LookupUnusedPins (FILE *);
 bool ResetFoundLinesAndPolygons (bool);
 bool ResetFoundPinsViasAndPads (bool);

commit 44db9c716a572748a7f5fc5f1bc7e5c1d84bb8fe
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove fBloat from find.c
    
    fBloat does nothing except act as a floating point copy
    of the integer Bloat variable. It should not be (and is
    not) necessary.

diff --git a/src/find.c b/src/find.c
index b7ab673..a3fbc1c 100644
--- a/src/find.c
+++ b/src/find.c
@@ -153,7 +153,7 @@ RCSID ("$Id$");
 			(PV)->X -MAX(((PV)->Thickness+1)/2 +Bloat,0), (PV)->Y -MAX(((PV)->Thickness+1)/2 +Bloat,0), \
 			(PV)->X +MAX(((PV)->Thickness+1)/2 +Bloat,0), (PV)->Y +MAX(((PV)->Thickness+1)/2 +Bloat,0), \
 			(Arc)) : \
-		IsPointOnArc((PV)->X,(PV)->Y,MAX((PV)->Thickness/2.0 + fBloat,0.0), (Arc)))
+		IsPointOnArc((PV)->X,(PV)->Y,MAX((PV)->Thickness/2.0 + Bloat,0.0), (Arc)))
 
 #define	IS_PV_ON_PAD(PV,Pad) \
 	( IsPointInPad((PV)->X, (PV)->Y, MAX((PV)->Thickness/2 +Bloat,0), (Pad)))
@@ -291,8 +291,7 @@ ListType, *ListTypePtr;
 /* ---------------------------------------------------------------------------
  * some local identifiers
  */
-static float fBloat = 0.0;
-static LocationType Bloat = 0;
+static Coord Bloat = 0;
 static int TheFlag = FOUNDFLAG;
 static int OldFlag = FOUNDFLAG;
 static void *thing_ptr1, *thing_ptr2, *thing_ptr3;
@@ -481,7 +480,7 @@ PinLineIntersect (PinTypePtr PV, LineTypePtr Line)
 								   MAX (PIN_SIZE (PV)
                                                                          /
                                                                          2.0 +
-                                                                         fBloat,
+                                                                         Bloat,
                                                                          0.0),
                                                                     (PadTypePtr)Line);
 }
@@ -521,11 +520,11 @@ PadPadIntersect (PadTypePtr p1, PadTypePtr p2)
 static inline bool
 PV_TOUCH_PV (PinTypePtr PV1, PinTypePtr PV2)
 {
-  float t1, t2;
+  double t1, t2;
   BoxType b1, b2;
 
-  t1 = MAX (PV1->Thickness / 2.0 + fBloat, 0);
-  t2 = MAX (PV2->Thickness / 2.0 + fBloat, 0);
+  t1 = MAX (PV1->Thickness / 2.0 + Bloat, 0);
+  t2 = MAX (PV2->Thickness / 2.0 + Bloat, 0);
   if (IsPointOnPin (PV1->X, PV1->Y, t1, PV2)
       || IsPointOnPin (PV2->X, PV2->Y, t2, PV1))
     return true;
@@ -754,14 +753,13 @@ LOCtoPVpoly_callback (const BoxType * b, void *cl)
                                                        polygon)
                                         || !i->pv.Clearance))
     {
-      float wide = 0.5 * i->pv.Thickness + fBloat;
-      wide = MAX (wide, 0);
+      double wide = MAX (0.5 * i->pv.Thickness + Bloat, 0);
       if (TEST_FLAG (SQUAREFLAG, &i->pv))
         {
-          LocationType x1 = i->pv.X - (i->pv.Thickness + 1 + Bloat) / 2;
-          LocationType x2 = i->pv.X + (i->pv.Thickness + 1 + Bloat) / 2;
-          LocationType y1 = i->pv.Y - (i->pv.Thickness + 1 + Bloat) / 2;
-          LocationType y2 = i->pv.Y + (i->pv.Thickness + 1 + Bloat) / 2;
+          Coord x1 = i->pv.X - (i->pv.Thickness + 1 + Bloat) / 2;
+          Coord x2 = i->pv.X + (i->pv.Thickness + 1 + Bloat) / 2;
+          Coord y1 = i->pv.Y - (i->pv.Thickness + 1 + Bloat) / 2;
+          Coord y2 = i->pv.Y + (i->pv.Thickness + 1 + Bloat) / 2;
           if (IsRectangleInPolygon (x1, y1, x2, y2, polygon)
               && ADD_POLYGON_TO_LIST (i->layer, polygon))
             longjmp (i->env, 1);
@@ -1106,7 +1104,7 @@ pv_poly_callback (const BoxType * b, void *cl)
     {
       if (TEST_FLAG (SQUAREFLAG, pv))
         {
-          LocationType x1, x2, y1, y2;
+          Coord x1, x2, y1, y2;
           x1 = pv->X - (PIN_SIZE (pv) + 1 + Bloat) / 2;
           x2 = pv->X + (PIN_SIZE (pv) + 1 + Bloat) / 2;
           y1 = pv->Y - (PIN_SIZE (pv) + 1 + Bloat) / 2;
@@ -1124,7 +1122,7 @@ pv_poly_callback (const BoxType * b, void *cl)
       else
         {
           if (IsPointInPolygon
-              (pv->X, pv->Y, PIN_SIZE (pv) * 0.5 + fBloat, &i->polygon)
+              (pv->X, pv->Y, PIN_SIZE (pv) * 0.5 + Bloat, &i->polygon)
               && ADD_PV_TO_LIST (pv))
             longjmp (i->env, 1);
         }
@@ -1395,11 +1393,11 @@ ArcArcIntersect (ArcTypePtr Arc1, ArcTypePtr Arc2)
   LocationType pdx, pdy;
   double box[4];
 
-  t = 0.5 * Arc1->Thickness + fBloat;
+  t = 0.5 * Arc1->Thickness + Bloat;
   if (t < 0) /* too thin arc */
     return (false);
   t2 = 0.5 * Arc2->Thickness;
-  t1 = t2 + fBloat;
+  t1 = t2 + Bloat;
   if (t1 < 0) /* too thin arc */
     return (false);
   /* try the end points first */
@@ -1669,7 +1667,7 @@ LineLineIntersect (LineTypePtr Line1, LineTypePtr Line2)
 
       distance =
         MAX ((float) 0.5 *
-             (Line1->Thickness + Line2->Thickness) + fBloat, 0.0);
+             (Line1->Thickness + Line2->Thickness) + Bloat, 0.0);
       distance *= distance;
       if (s > distance)
         return (false);
@@ -1731,12 +1729,12 @@ LineLineIntersect (LineTypePtr Line1, LineTypePtr Line2)
                    Line2->Point1.Y,
                    MAX (0.5 *
                         Line2->Thickness +
-                        fBloat, 0.0),
+                        Bloat, 0.0),
                    (PadTypePtr)Line1) :
                   IsPointInPad
                   (Line2->Point2.X,
                    Line2->Point2.Y,
-                   MAX (0.5 * Line2->Thickness + fBloat, 0.0), (PadTypePtr)Line1));
+                   MAX (0.5 * Line2->Thickness + Bloat, 0.0), (PadTypePtr)Line1));
         }
 
       /* intersection is at least on CD */
@@ -1748,28 +1746,28 @@ LineLineIntersect (LineTypePtr Line1, LineTypePtr Line2)
                   (Line1->Point1.X,
                    Line1->Point1.Y,
                    MAX (Line1->Thickness /
-                        2.0 + fBloat, 0.0),
+                        2.0 + Bloat, 0.0),
                    (PadTypePtr)Line2) :
                   IsPointInPad
                   (Line1->Point2.X,
                    Line1->Point2.Y,
-                   MAX (Line1->Thickness / 2.0 + fBloat, 0.0), (PadTypePtr)Line2));
+                   MAX (Line1->Thickness / 2.0 + Bloat, 0.0), (PadTypePtr)Line2));
         }
 
       /* no intersection of zero-width lines but maybe of thick lines;
        * Must check each end point to exclude intersection
        */
       if (IsPointInPad (Line1->Point1.X, Line1->Point1.Y,
-                         Line1->Thickness / 2.0 + fBloat, (PadTypePtr)Line2))
+                         Line1->Thickness / 2.0 + Bloat, (PadTypePtr)Line2))
         return true;
       if (IsPointInPad (Line1->Point2.X, Line1->Point2.Y,
-                         Line1->Thickness / 2.0 + fBloat, (PadTypePtr)Line2))
+                         Line1->Thickness / 2.0 + Bloat, (PadTypePtr)Line2))
         return true;
       if (IsPointInPad (Line2->Point1.X, Line2->Point1.Y,
-                         Line2->Thickness / 2.0 + fBloat, (PadTypePtr)Line1))
+                         Line2->Thickness / 2.0 + Bloat, (PadTypePtr)Line1))
         return true;
       return IsPointInPad (Line2->Point2.X, Line2->Point2.Y,
-                            Line2->Thickness / 2.0 + fBloat, (PadTypePtr)Line1);
+                            Line2->Thickness / 2.0 + Bloat, (PadTypePtr)Line1);
     }
 }
 
@@ -1805,20 +1803,20 @@ LineLineIntersect (LineTypePtr Line1, LineTypePtr Line2)
 bool
 LineArcIntersect (LineTypePtr Line, ArcTypePtr Arc)
 {
-  register float dx, dy, dx1, dy1, l, d, r, r2, Radius;
+  double dx, dy, dx1, dy1, l, d, r, r2, Radius;
   BoxTypePtr box;
 
-  dx = (float) (Line->Point2.X - Line->Point1.X);
-  dy = (float) (Line->Point2.Y - Line->Point1.Y);
-  dx1 = (float) (Line->Point1.X - Arc->X);
-  dy1 = (float) (Line->Point1.Y - Arc->Y);
+  dx = Line->Point2.X - Line->Point1.X;
+  dy = Line->Point2.Y - Line->Point1.Y;
+  dx1 = Line->Point1.X - Arc->X;
+  dy1 = Line->Point1.Y - Arc->Y;
   l = dx * dx + dy * dy;
   d = dx * dy1 - dy * dx1;
   d *= d;
 
   /* use the larger diameter circle first */
   Radius =
-    Arc->Width + MAX (0.5 * (Arc->Thickness + Line->Thickness) + fBloat, 0.0);
+    Arc->Width + MAX (0.5 * (Arc->Thickness + Line->Thickness) + Bloat, 0.0);
   Radius *= Radius;
   r2 = Radius * l - d;
   /* projection doesn't even intersect circle when r2 < 0 */
@@ -1828,11 +1826,11 @@ LineArcIntersect (LineTypePtr Line, ArcTypePtr Arc)
   /* of intersection is beyond the line end */
   if (IsPointOnArc
       (Line->Point1.X, Line->Point1.Y,
-       MAX (0.5 * Line->Thickness + fBloat, 0.0), Arc))
+       MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc))
     return (true);
   if (IsPointOnArc
       (Line->Point2.X, Line->Point2.Y,
-       MAX (0.5 * Line->Thickness + fBloat, 0.0), Arc))
+       MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc))
     return (true);
   if (l == 0.0)
     return (false);
@@ -1842,19 +1840,19 @@ LineArcIntersect (LineTypePtr Line, ArcTypePtr Arc)
   if (r >= 0 && r <= 1
       && IsPointOnArc (Line->Point1.X + r * dx,
                        Line->Point1.Y + r * dy,
-                       MAX (0.5 * Line->Thickness + fBloat, 0.0), Arc))
+                       MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc))
     return (true);
   r = (Radius - r2) / l;
   if (r >= 0 && r <= 1
       && IsPointOnArc (Line->Point1.X + r * dx,
                        Line->Point1.Y + r * dy,
-                       MAX (0.5 * Line->Thickness + fBloat, 0.0), Arc))
+                       MAX (0.5 * Line->Thickness + Bloat, 0.0), Arc))
     return (true);
   /* check arc end points */
   box = GetArcEnds (Arc);
-  if (IsPointInPad (box->X1, box->Y1, Arc->Thickness * 0.5 + fBloat, (PadTypePtr)Line))
+  if (IsPointInPad (box->X1, box->Y1, Arc->Thickness * 0.5 + Bloat, (PadTypePtr)Line))
     return true;
-  if (IsPointInPad (box->X2, box->Y2, Arc->Thickness * 0.5 + fBloat, (PadTypePtr)Line))
+  if (IsPointInPad (box->X2, box->Y2, Arc->Thickness * 0.5 + Bloat, (PadTypePtr)Line))
     return true;
   return false;
 }
@@ -2660,8 +2658,8 @@ IsLineInPolygon (LineTypePtr Line, PolygonTypePtr Polygon)
     return false;
   if (TEST_FLAG(SQUAREFLAG,Line)&&(Line->Point1.X==Line->Point2.X||Line->Point1.Y==Line->Point2.Y))
      {
-       BDimension wid = (Line->Thickness + Bloat + 1) / 2;
-       LocationType x1, x2, y1, y2;
+       Coord wid = (Line->Thickness + Bloat + 1) / 2;
+       Coord x1, x2, y1, y2;
 
        x1 = MIN (Line->Point1.X, Line->Point2.X) - wid;
        y1 = MIN (Line->Point1.Y, Line->Point2.Y) - wid;
@@ -3630,7 +3628,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
   if (PCB->Shrink != 0)
     {
       Bloat = -PCB->Shrink;
-      fBloat = (float) -PCB->Shrink;
       TheFlag = DRCFLAG | SELECTEDFLAG;
       ListStart (What, ptr1, ptr2, ptr3);
       DoIt (true, false);
@@ -3639,7 +3636,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
       TheFlag = FOUNDFLAG;
       ListStart (What, ptr1, ptr2, ptr3);
       Bloat = 0;
-      fBloat = 0.0;
       drc = true;               /* abort the search if we find anything not already found */
       if (DoIt (true, false))
         {
@@ -3650,7 +3646,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
           User = true;
           drc = false;
           Bloat = -PCB->Shrink;
-          fBloat = (float) -PCB->Shrink;
           TheFlag = SELECTEDFLAG;
           RestoreUndoSerialNumber ();
           ListStart (What, ptr1, ptr2, ptr3);
@@ -3659,7 +3654,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
           ListStart (What, ptr1, ptr2, ptr3);
           TheFlag = FOUNDFLAG;
           Bloat = 0;
-          fBloat = 0.0;
           drc = true;
           DoIt (true, true);
           DumpList ();
@@ -3697,7 +3691,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
   TheFlag = FOUNDFLAG;
   ListStart (What, ptr1, ptr2, ptr3);
   Bloat = PCB->Bloat;
-  fBloat = (float) PCB->Bloat;
   drc = true;
   while (DoIt (true, false))
     {
@@ -3708,7 +3701,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
       User = true;
       drc = false;
       Bloat = 0;
-      fBloat = 0.0;
       RestoreUndoSerialNumber ();
       TheFlag = SELECTEDFLAG;
       ListStart (What, ptr1, ptr2, ptr3);
@@ -3717,7 +3709,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
       TheFlag = FOUNDFLAG;
       ListStart (What, ptr1, ptr2, ptr3);
       Bloat = PCB->Bloat;
-      fBloat = (float) PCB->Bloat;
       drc = true;
       DoIt (true, true);
       DumpList ();
@@ -3748,13 +3739,11 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
       /* highlight the rest of the encroaching net so it's not reported again */
       TheFlag |= SELECTEDFLAG;
       Bloat = 0;
-      fBloat = 0.0;
       ListStart (thing_type, thing_ptr1, thing_ptr2, thing_ptr3);
       DoIt (true, true);
       DumpList ();
       drc = true;
       Bloat = PCB->Bloat;
-      fBloat = (float) PCB->Bloat;
       ListStart (What, ptr1, ptr2, ptr3);
     }
   drc = false;
@@ -4253,7 +4242,6 @@ DRCAll (void)
   FreeConnectionLookupMemory ();
   TheFlag = FOUNDFLAG;
   Bloat = 0;
-  fBloat = 0.0;
 
   /* check silkscreen minimum widths outside of elements */
   /* XXX - need to check text and polygons too! */

commit 2c737bfc51c420b9ef173860c31ef57ccde6edf6
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Fix g_string_free (NULL) error

diff --git a/src/find.c b/src/find.c
index 5cd0df1..b7ab673 100644
--- a/src/find.c
+++ b/src/find.c
@@ -199,7 +199,8 @@ static GString *drc_dialog_message;
 static void
 reset_drc_dialog_message(void)
 {
-  g_string_free (drc_dialog_message, FALSE);
+  if (drc_dialog_message)
+    g_string_free (drc_dialog_message, FALSE);
   drc_dialog_message = g_string_new ("");
   if (gui->drc_gui != NULL)
     {

commit 06f059a973d4320f078de7a0e75023e1690baaee
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove coord suffix/precision from DRC error struct
    
    Display units for DRC errors are now handled by the UI,
    rather than in the error struct. The struct now stores
    everything in Coord's, and pcb-printf worries about how
    to display them.

diff --git a/src/global.h b/src/global.h
index 5b7ac4c..666d0cf 100644
--- a/src/global.h
+++ b/src/global.h
@@ -771,10 +771,8 @@ struct drc_violation_st
   Coord x, y;
   Angle angle;
   int have_measured;
-  double measured_value;
-  double required_value;
-  int value_digits;
-  const char *value_units;
+  Coord measured_value;
+  Coord required_value;
   int object_count;
   long int *object_id_list;
   int *object_type_list;
diff --git a/src/hid/gtk/gui-drc-window.c b/src/hid/gtk/gui-drc-window.c
index 6d50d16..65e64a2 100644
--- a/src/hid/gtk/gui-drc-window.c
+++ b/src/hid/gtk/gui-drc-window.c
@@ -33,6 +33,7 @@
 #include "error.h"
 #include "search.h"
 #include "draw.h"
+#include "pcb-printf.h"
 #include "undo.h"
 #include "set.h"
 #include "gui.h"
@@ -274,8 +275,6 @@ enum
   PROP_HAVE_MEASURED,
   PROP_MEASURED_VALUE,
   PROP_REQUIRED_VALUE,
-  PROP_VALUE_DIGITS,
-  PROP_VALUE_UNITS,
   PROP_OBJECT_LIST,
   PROP_PIXMAP
 };
@@ -299,7 +298,6 @@ ghid_drc_violation_finalize (GObject * object)
 
   g_free (violation->title);
   g_free (violation->explanation);
-  g_free (violation->value_units);
   g_free (violation->object_id_list);
   g_free (violation->object_type_list);
   if (violation->pixmap != NULL)
@@ -351,23 +349,16 @@ ghid_drc_violation_set_property (GObject * object, guint property_id,
       violation->y_coord = g_value_get_int (value);
       break;
     case PROP_ANGLE:
-      violation->angle = g_value_get_int (value);
+      violation->angle = g_value_get_double (value);
       break;
     case PROP_HAVE_MEASURED:
-      violation->have_measured = g_value_get_int (value);
+      violation->have_measured = g_value_get_boolean (value);
       break;
     case PROP_MEASURED_VALUE:
-      violation->measured_value = g_value_get_double (value);
+      violation->measured_value = g_value_get_int (value);
       break;
     case PROP_REQUIRED_VALUE:
-      violation->required_value = g_value_get_double (value);
-      break;
-    case PROP_VALUE_DIGITS:
-      violation->value_digits = g_value_get_int (value);
-      break;
-    case PROP_VALUE_UNITS:
-      g_free (violation->value_units);
-      violation->value_units = g_value_dup_string (value);
+      violation->required_value = g_value_get_int (value);
       break;
     case PROP_OBJECT_LIST:
       /* Copy the passed data to make new lists */
@@ -467,7 +458,7 @@ ghid_drc_violation_class_init (GhidViolationRendererClass * klass)
 						     0,
 						     G_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class, PROP_ANGLE,
-				   g_param_spec_int ("angle",
+				   g_param_spec_double ("angle",
 						     "",
 						     "",
 						     G_MININT,
@@ -475,43 +466,27 @@ ghid_drc_violation_class_init (GhidViolationRendererClass * klass)
 						     0,
 						     G_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class, PROP_HAVE_MEASURED,
-				   g_param_spec_int ("have-measured",
+				   g_param_spec_boolean ("have-measured",
 						     "",
 						     "",
-						     G_MININT,
-						     G_MAXINT,
 						     0,
 						     G_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class, PROP_MEASURED_VALUE,
-				   g_param_spec_double ("measured-value",
+				   g_param_spec_int ("measured-value",
 						     "",
 						     "",
-						     -G_MAXDOUBLE,
-						     G_MAXDOUBLE,
+						     G_MININT,
+						     G_MAXINT,
 						     0.,
 						     G_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class, PROP_REQUIRED_VALUE,
-				   g_param_spec_double ("required-value",
-						     "",
-						     "",
-						     -G_MINDOUBLE,
-						     G_MAXDOUBLE,
-						     0.,
-						     G_PARAM_WRITABLE));
-  g_object_class_install_property (gobject_class, PROP_VALUE_DIGITS,
-				   g_param_spec_int ("value-digits",
+				   g_param_spec_int ("required-value",
 						     "",
 						     "",
-						     0,
+						     G_MININT,
 						     G_MAXINT,
-						     0,
+						     0.,
 						     G_PARAM_WRITABLE));
-  g_object_class_install_property (gobject_class, PROP_VALUE_UNITS,
-				   g_param_spec_string ("value-units",
-							"",
-							"",
-							"",
-							G_PARAM_WRITABLE));
   g_object_class_install_property (gobject_class, PROP_OBJECT_LIST,
 				   g_param_spec_pointer ("object-list",
 							 "",
@@ -582,8 +557,6 @@ GhidDrcViolation *ghid_drc_violation_new (DrcViolationType *violation,
 		       "have-measured",    violation->have_measured,
 		       "measured-value",   violation->measured_value,
 		       "required-value",   violation->required_value,
-		       "value-digits",     violation->value_digits,
-		       "value-units",      violation->value_units,
 		       "object-list",      &obj_list,
 		       "pixmap",           pixmap,
 		       NULL);
@@ -654,36 +627,32 @@ ghid_violation_renderer_set_property (GObject * object, guint property_id,
 
   if (renderer->violation->have_measured)
     {
-      markup = g_strdup_printf ("<b>%s (%.*f %s)</b>\n"
+      markup = pcb_g_strdup_printf ("%m+<b>%s (%$mS)</b>\n"
 				"<span size='1024'> </span>\n"
 				"<small>"
 				  "<i>%s</i>\n"
 				  "<span size='5120'> </span>\n"
-				  "Required: %.*f %s"
+				  "Required: %$mS"
 				"</small>",
+                                Settings.grid_unit->allow,
 				renderer->violation->title,
-				renderer->violation->value_digits,
 				renderer->violation->measured_value,
-				renderer->violation->value_units,
 				renderer->violation->explanation,
-				renderer->violation->value_digits,
-				renderer->violation->required_value,
-				renderer->violation->value_units);
+				renderer->violation->required_value);
     }
   else
     {
-      markup = g_strdup_printf ("<b>%s</b>\n"
+      markup = pcb_g_strdup_printf ("%m+<b>%s</b>\n"
 				"<span size='1024'> </span>\n"
 				"<small>"
 				  "<i>%s</i>\n"
 				  "<span size='5120'> </span>\n"
-				  "Required: %.*f %s"
+				  "Required: %$mS"
 				"</small>",
+                                Settings.grid_unit->allow,
 				renderer->violation->title,
 				renderer->violation->explanation,
-				renderer->violation->value_digits,
-				renderer->violation->required_value,
-				renderer->violation->value_units);
+				renderer->violation->required_value);
     }
 
   g_object_set (object, "markup", markup, NULL);
diff --git a/src/hid/gtk/gui-drc-window.h b/src/hid/gtk/gui-drc-window.h
index 9bd26cf..8b3558a 100644
--- a/src/hid/gtk/gui-drc-window.h
+++ b/src/hid/gtk/gui-drc-window.h
@@ -51,14 +51,12 @@ struct _GhidDrcViolation
 
   char *title;
   char *explanation;
-  int x_coord;
-  int y_coord;
-  int angle;
-  int have_measured;
-  double measured_value;
-  double required_value;
-  int value_digits;
-  char *value_units;
+  Coord x_coord;
+  Coord y_coord;
+  Angle angle;
+  bool have_measured;
+  Coord measured_value;
+  Coord required_value;
   int object_count;
   long int *object_id_list;
   int *object_type_list;

commit 4545d537e6db4bf418ffecaf9bdfecd3ec22854f
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit file.c, implement Coord

diff --git a/src/file.c b/src/file.c
index 8f9bee5..1c68abc 100644
--- a/src/file.c
+++ b/src/file.c
@@ -417,9 +417,8 @@ LoadPCB (char *Filename)
       ResetStackAndVisibility ();
 
       /* update cursor location */
-      Crosshair.X = MAX (0, MIN (PCB->CursorX, (LocationType) PCB->MaxWidth));
-      Crosshair.Y =
-	MAX (0, MIN (PCB->CursorY, (LocationType) PCB->MaxHeight));
+      Crosshair.X = CLAMP (PCB->CursorX, 0, PCB->MaxWidth);
+      Crosshair.Y = CLAMP (PCB->CursorY, 0, PCB->MaxHeight);
 
       /* update cursor confinement and output area (scrollbars) */
       ChangePCBSize (PCB->MaxWidth, PCB->MaxHeight);

commit 656f5925148e5a747bc55c618ff3843eddc65d07
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use pcb-printf in DRC code in find.c
    
    Also, expose pcb_vprintf in pcb_printf.h.

diff --git a/src/find.c b/src/find.c
index 5b30e93..5cd0df1 100644
--- a/src/find.c
+++ b/src/find.c
@@ -158,21 +158,14 @@ RCSID ("$Id$");
 #define	IS_PV_ON_PAD(PV,Pad) \
 	( IsPointInPad((PV)->X, (PV)->Y, MAX((PV)->Thickness/2 +Bloat,0), (Pad)))
 
-#define LENGTH_TO_HUMAN(value) coord_to_unit (Settings.grid_unit, value)
-#define LENGTH_DIGITS (Settings.grid_unit->default_prec)
-#define LENGTH_UNITS_STRING (Settings.grid_unit->suffix)
-
-
 static DrcViolationType
-*pcb_drc_violation_new (char *title,
-                        char *explanation,
-                        int x, int y,
-                        int angle,
-                        int have_measured,
-                        double measured_value,
-                        double required_value,
-                        int value_digits,
-                        const char *value_units,
+*pcb_drc_violation_new (const char *title,
+                        const char *explanation,
+                        Coord x, Coord y,
+                        Angle angle,
+                        bool have_measured,
+                        Coord measured_value,
+                        Coord required_value,
                         int object_count,
                         long int *object_id_list,
                         int *object_type_list)
@@ -187,8 +180,6 @@ static DrcViolationType
   violation->have_measured = have_measured;
   violation->measured_value = measured_value;
   violation->required_value = required_value;
-  violation->value_digits = value_digits;
-  violation->value_units = value_units;
   violation->object_count = object_count;
   violation->object_id_list = object_id_list;
   violation->object_type_list = object_type_list;
@@ -204,33 +195,27 @@ pcb_drc_violation_free (DrcViolationType *violation)
   free (violation);
 }
 
-static char drc_dialog_message[289] = {0};
+static GString *drc_dialog_message;
 static void
 reset_drc_dialog_message(void)
 {
-  drc_dialog_message[0] = 0;
+  g_string_free (drc_dialog_message, FALSE);
+  drc_dialog_message = g_string_new ("");
   if (gui->drc_gui != NULL)
     {
       gui->drc_gui->reset_drc_dialog_message ();
     }
 }
-#ifdef __GNUC__
-static void append_drc_dialog_message(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-#endif
 static void
 append_drc_dialog_message(const char *fmt, ...)
 {
-  size_t len = strlen (drc_dialog_message),
-         remained = sizeof (drc_dialog_message) - len - 1;
+  gchar *new_str;
   va_list ap;
   va_start (ap, fmt);
-#ifdef HAVE_VSNPRINTF
-  vsnprintf (drc_dialog_message + len, remained, fmt, ap);
-#else
-  vsprintf (drc_dialog_message + len, fmt, ap);
-#endif
+  new_str = pcb_vprintf (fmt, ap);
+  g_string_append (drc_dialog_message, new_str);
   va_end (ap);
+  g_free (new_str);
 }
 
 static void GotoError (void);
@@ -246,18 +231,18 @@ append_drc_violation (DrcViolationType *violation)
     {
       /* Fallback to formatting the violation message as text */
       append_drc_dialog_message ("%s\n", violation->title);
-      append_drc_dialog_message (_("near (%.*f, %.*f)\n"),
-                                 LENGTH_DIGITS, LENGTH_TO_HUMAN (violation->x),
-                                 LENGTH_DIGITS, LENGTH_TO_HUMAN (violation->y));
+      append_drc_dialog_message (_("%m+near %$mD\n"),
+                                 Settings.grid_unit->allow,
+                                 violation->x, violation->y);
       GotoError ();
     }
 
   if (gui->drc_gui == NULL || gui->drc_gui->log_drc_violations )
     {
       Message (_("WARNING!  Design Rule error - %s\n"), violation->title);
-      Message (_("near location (%.*f, %.*f)\n"),
-               LENGTH_DIGITS, LENGTH_TO_HUMAN (violation->x),
-               LENGTH_DIGITS, LENGTH_TO_HUMAN (violation->y));
+      Message (_("%m+near location %$mD\n"),
+               Settings.grid_unit->allow,
+               violation->x, violation->y);
     }
 }
 /*
@@ -281,7 +266,7 @@ throw_drc_dialog(void)
     {
       /* Fallback to formatting the violation message as text */
       append_drc_dialog_message (DRC_CONTINUE);
-      r = gui->confirm_dialog (drc_dialog_message, DRC_CANCEL, DRC_NEXT);
+      r = gui->confirm_dialog (drc_dialog_message->str, DRC_CANCEL, DRC_NEXT);
       reset_drc_dialog_message();
     }
   return r;
@@ -3689,9 +3674,7 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
                                              0,     /* ANGLE OF ERROR UNKNOWN */
                                              FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
                                              0,     /* MAGNITUDE OF ERROR UNKNOWN */
-                                             LENGTH_TO_HUMAN(PCB->Shrink),
-                                             LENGTH_DIGITS,
-                                             LENGTH_UNITS_STRING,
+                                             PCB->Shrink,
                                              object_count,
                                              object_id_list,
                                              object_type_list);
@@ -3747,9 +3730,7 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
                                          0,     /* ANGLE OF ERROR UNKNOWN */
                                          FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
                                          0,     /* MAGNITUDE OF ERROR UNKNOWN */
-                                         LENGTH_TO_HUMAN(PCB->Bloat),
-                                         LENGTH_DIGITS,
-                                         LENGTH_UNITS_STRING,
+                                         PCB->Bloat,
                                          object_count,
                                          object_id_list,
                                          object_type_list);
@@ -3891,9 +3872,7 @@ doIsBad:
                                      0,     /* ANGLE OF ERROR UNKNOWN */
                                      FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
                                      0,     /* MAGNITUDE OF ERROR UNKNOWN */
-                                     LENGTH_TO_HUMAN(PCB->Bloat),
-                                     LENGTH_DIGITS,
-                                     LENGTH_UNITS_STRING,
+                                     PCB->Bloat,
                                      object_count,
                                      object_id_list,
                                      object_type_list);
@@ -4017,10 +3996,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(line->Thickness),
-                                               LENGTH_TO_HUMAN(PCB->minWid),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               line->Thickness,
+                                               PCB->minWid,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4061,10 +4038,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(arc->Thickness),
-                                               LENGTH_TO_HUMAN(PCB->minWid),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               arc->Thickness,
+                                               PCB->minWid,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4106,10 +4081,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN((pin->Thickness - pin->DrillingHole) / 2),
-                                               LENGTH_TO_HUMAN(PCB->minRing),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               (pin->Thickness - pin->DrillingHole) / 2,
+                                               PCB->minRing,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4139,10 +4112,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(pin->DrillingHole),
-                                               LENGTH_TO_HUMAN(PCB->minDrill),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               pin->DrillingHole,
+                                               PCB->minDrill,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4183,10 +4154,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(pad->Thickness),
-                                               LENGTH_TO_HUMAN(PCB->minWid),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               pad->Thickness,
+                                               PCB->minWid,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4228,10 +4197,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN((via->Thickness - via->DrillingHole) / 2),
-                                               LENGTH_TO_HUMAN(PCB->minRing),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               (via->Thickness - via->DrillingHole) / 2,
+                                               PCB->minRing,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4261,10 +4228,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(via->DrillingHole),
-                                               LENGTH_TO_HUMAN(PCB->minDrill),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               via->DrillingHole,
+                                               PCB->minDrill,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4310,10 +4275,8 @@ DRCAll (void)
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(line->Thickness),
-                                               LENGTH_TO_HUMAN(PCB->minSlk),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               line->Thickness,
+                                               PCB->minSlk,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
@@ -4374,11 +4337,9 @@ DRCAll (void)
                                                "feature-width that can reliably be reproduced"),
                                                x, y,
                                                0,    /* ANGLE OF ERROR UNKNOWN */
-                                               0,    /* MINIMUM OFFENDING WIDTH UNKNOWN */
                                                TRUE, /* MEASUREMENT OF ERROR KNOWN */
-                                               LENGTH_TO_HUMAN(PCB->minSlk),
-                                               LENGTH_DIGITS,
-                                               LENGTH_UNITS_STRING,
+                                               0,    /* MINIMUM OFFENDING WIDTH UNKNOWN */
+                                               PCB->minSlk,
                                                object_count,
                                                object_id_list,
                                                object_type_list);
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 7baffbb..5df42af 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -368,7 +368,7 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
   return g_string_free (buff, FALSE);
 }
 
-static gchar *pcb_vprintf(const char *fmt, va_list args)
+gchar *pcb_vprintf(const char *fmt, va_list args)
 {
   GString *string = g_string_new ("");
   GString *spec   = g_string_new ("");
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index 6534945..ed81060 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -150,6 +150,7 @@ int pcb_fprintf(FILE *f, const char *fmt, ...);
 int pcb_sprintf(char *string, const char *fmt, ...);
 int pcb_printf(const char *fmt, ...);
 char *pcb_g_strdup_printf(const char *fmt, ...);
+gchar *pcb_vprintf(const char *fmt, va_list args);
 
 #endif
 

commit 5ff5b13ab3cd84247281190492dd834f24226893
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit draw.[ch], implement Coord

diff --git a/src/draw.c b/src/draw.c
index ef465cb..8950539 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -86,7 +86,7 @@ static void DrawPPV (int group, const BoxType *);
 static int DrawLayerGroup (int, const BoxType *);
 static void AddPart (void *);
 static void SetPVColor (PinTypePtr, int);
-static void DrawEMark (ElementTypePtr, LocationType, LocationType, bool);
+static void DrawEMark (ElementTypePtr, Coord, Coord, bool);
 static void DrawMask (int side, BoxType *);
 static void DrawPaste (int side, BoxType *);
 static void DrawRats (BoxType *);
@@ -809,10 +809,9 @@ DrawEverything (BoxTypePtr drawn_area)
 }
 
 static void
-DrawEMark (ElementTypePtr e, LocationType X, LocationType Y,
-	   bool invisible)
+DrawEMark (ElementTypePtr e, Coord X, Coord Y, bool invisible)
 {
-  int mark_size = EMARK_SIZE;
+  Coord mark_size = EMARK_SIZE;
   if (!PCB->InvisibleObjectsOn && invisible)
     return;
 
@@ -1243,9 +1242,9 @@ GatherPadName (PadTypePtr Pad)
  * lowlevel drawing routine for text objects
  */
 void
-DrawTextLowLevel (TextTypePtr Text, int min_line_width)
+DrawTextLowLevel (TextTypePtr Text, Coord min_line_width)
 {
-  LocationType x = 0;
+  Coord x = 0;
   unsigned char *string = (unsigned char *) Text->TextString;
   Cardinal n;
   FontTypePtr font = &PCB->Font;
@@ -1297,7 +1296,7 @@ DrawTextLowLevel (TextTypePtr Text, int min_line_width)
 	{
 	  /* the default symbol is a filled box */
 	  BoxType defaultsymbol = PCB->Font.DefaultSymbol;
-	  LocationType size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5;
+	  Coord size = (defaultsymbol.X2 - defaultsymbol.X1) * 6 / 5;
 
 	  defaultsymbol.X1 = (defaultsymbol.X1 + x) * Text->Scale / 100;
 	  defaultsymbol.Y1 = defaultsymbol.Y1 * Text->Scale / 100;
@@ -1403,7 +1402,7 @@ DrawRat (RatTypePtr Rat)
   /* rats.c set VIAFLAG if this rat goes to a containing poly: draw a donut */
   if (TEST_FLAG(VIAFLAG, Rat))
     {
-      int w = Rat->Thickness;
+      Coord w = Rat->Thickness;
 
       BoxType b;
 
@@ -1523,7 +1522,7 @@ EraseRat (RatTypePtr Rat)
 {
   if (TEST_FLAG(VIAFLAG, Rat))
     {
-      int w = Rat->Thickness;
+      Coord w = Rat->Thickness;
 
       BoxType b;
 
diff --git a/src/draw.h b/src/draw.h
index bda02f8..484ae98 100644
--- a/src/draw.h
+++ b/src/draw.h
@@ -47,7 +47,7 @@ void DrawPadName (PadTypePtr);
 void DrawLine (LayerTypePtr, LineTypePtr);
 void DrawArc (LayerTypePtr, ArcTypePtr);
 void DrawText (LayerTypePtr, TextTypePtr);
-void DrawTextLowLevel (TextTypePtr, int);
+void DrawTextLowLevel (TextTypePtr, Coord);
 void DrawPolygon (LayerTypePtr, PolygonTypePtr);
 void DrawElement (ElementTypePtr);
 void DrawElementName (ElementTypePtr);

commit 1f802a7f01378217d519d2da25234fa0e105ddda
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit change.[ch], box.h, implement Coord

diff --git a/src/box.h b/src/box.h
index 3dc779e..1c8311a 100644
--- a/src/box.h
+++ b/src/box.h
@@ -40,17 +40,19 @@
 #include <assert.h>
 #include "global.h"
 
+#include "misc.h"
+
 typedef enum
 { NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3, NE = 4, SE = 5, SW = 6, NW =
     7, ALL = 8 } direction_t;
 
 /* rotates box 90-degrees cw */
 /* that's a strange rotation! */
-#define ROTATEBOX_CW(box) { LocationType t;\
+#define ROTATEBOX_CW(box) { Coord t;\
     t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\
     (box).X2 = -(box).Y1; (box).Y1 = t;\
 }
-#define ROTATEBOX_TO_NORTH(box, dir) do { LocationType t;\
+#define ROTATEBOX_TO_NORTH(box, dir) do { Coord t;\
   switch(dir) {\
   case EAST: \
    t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\
@@ -65,7 +67,7 @@ typedef enum
   default: assert(0);\
   }\
   } while (0)
-#define ROTATEBOX_FROM_NORTH(box, dir) do { LocationType t;\
+#define ROTATEBOX_FROM_NORTH(box, dir) do { Coord t;\
   switch(dir) {\
   case WEST: \
    t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\
@@ -88,7 +90,7 @@ typedef enum
 
 typedef struct cheap_point
 {
-  LocationType X, Y;
+  Coord X, Y;
 } CheapPointType;
 
 
@@ -96,13 +98,13 @@ typedef struct cheap_point
 /* this means that top-left corner is in box, *but bottom-right corner is
  * not*.  */
 static inline bool
-point_in_box (const BoxType * box, LocationType X, LocationType Y)
+point_in_box (const BoxType * box, Coord X, Coord Y)
 {
   return (X >= box->X1) && (Y >= box->Y1) && (X < box->X2) && (Y < box->Y2);
 }
 
 static inline bool
-point_in_closed_box (const BoxType * box, LocationType X, LocationType Y)
+point_in_closed_box (const BoxType * box, Coord X, Coord Y)
 {
   return (X >= box->X1) && (Y >= box->Y1) && (X <= box->X2) && (Y <= box->Y2);
 }
@@ -157,7 +159,7 @@ clip_box (const BoxType * box, const BoxType * clipbox)
 }
 
 static inline BoxType
-shrink_box (const BoxType * box, LocationType amount)
+shrink_box (const BoxType * box, Coord amount)
 {
   BoxType r = *box;
   r.X1 += amount;
@@ -168,7 +170,7 @@ shrink_box (const BoxType * box, LocationType amount)
 }
 
 static inline BoxType
-bloat_box (const BoxType * box, LocationType amount)
+bloat_box (const BoxType * box, Coord amount)
 {
   return shrink_box (box, -amount);
 }
@@ -199,7 +201,7 @@ box_corner (const BoxType * box)
 
 /* construct a box that holds a single point */
 static inline BoxType
-point_box (LocationType X, LocationType Y)
+point_box (Coord X, Coord Y)
 {
   BoxType r;
   r.X1 = X;
@@ -220,13 +222,11 @@ close_box (BoxType * r)
 /* return the square of the minimum distance from a point to some point
  * inside a box.  The box is half-closed!  That is, the top-left corner
  * is considered in the box, but the bottom-right corner is not. */
-static inline float
+static inline double
 dist2_to_box (const CheapPointType * p, const BoxType * b)
 {
   CheapPointType r = closest_point_in_box (p, b);
-  float x_dist = (r.X - p->X);
-  float y_dist = (r.Y - p->Y);
-  return (x_dist * x_dist) + (y_dist * y_dist);
+  return Distance (r.X, r.Y, p->X, p->Y);
 }
 
 #endif /* __BOX_H_INCLUDED__ */
diff --git a/src/change.c b/src/change.c
index 70e5470..fb6e62c 100644
--- a/src/change.c
+++ b/src/change.c
@@ -393,7 +393,7 @@ ChangePinThermal (ElementTypePtr element, PinTypePtr Pin)
 static void *
 ChangeViaSize (PinTypePtr Via)
 {
-  BDimension value = Absolute ? Absolute : Via->Thickness + Delta;
+  Coord value = Absolute ? Absolute : Via->Thickness + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Via))
     return (NULL);
@@ -428,7 +428,7 @@ ChangeViaSize (PinTypePtr Via)
 static void *
 ChangeVia2ndSize (PinTypePtr Via)
 {
-  BDimension value = (Absolute) ? Absolute : Via->DrillingHole + Delta;
+  Coord value = (Absolute) ? Absolute : Via->DrillingHole + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Via))
     return (NULL);
@@ -461,7 +461,7 @@ ChangeVia2ndSize (PinTypePtr Via)
 static void *
 ChangeViaClearSize (PinTypePtr Via)
 {
-  BDimension value = (Absolute) ? Absolute : Via->Clearance + Delta;
+  Coord value = (Absolute) ? Absolute : Via->Clearance + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Via))
     return (NULL);
@@ -495,7 +495,7 @@ ChangeViaClearSize (PinTypePtr Via)
 static void *
 ChangePinSize (ElementTypePtr Element, PinTypePtr Pin)
 {
-  BDimension value = (Absolute) ? Absolute : Pin->Thickness + Delta;
+  Coord value = (Absolute) ? Absolute : Pin->Thickness + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Pin))
     return (NULL);
@@ -527,7 +527,7 @@ ChangePinSize (ElementTypePtr Element, PinTypePtr Pin)
 static void *
 ChangePinClearSize (ElementTypePtr Element, PinTypePtr Pin)
 {
-  BDimension value = (Absolute) ? Absolute : Pin->Clearance + Delta;
+  Coord value = (Absolute) ? Absolute : Pin->Clearance + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Pin))
     return (NULL);
@@ -559,7 +559,7 @@ ChangePinClearSize (ElementTypePtr Element, PinTypePtr Pin)
 static void *
 ChangePadSize (ElementTypePtr Element, PadTypePtr Pad)
 {
-  BDimension value = (Absolute) ? Absolute : Pad->Thickness + Delta;
+  Coord value = (Absolute) ? Absolute : Pad->Thickness + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Pad))
     return (NULL);
@@ -588,7 +588,7 @@ ChangePadSize (ElementTypePtr Element, PadTypePtr Pad)
 static void *
 ChangePadClearSize (ElementTypePtr Element, PadTypePtr Pad)
 {
-  BDimension value = (Absolute) ? Absolute : Pad->Clearance + Delta;
+  Coord value = (Absolute) ? Absolute : Pad->Clearance + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Pad))
     return (NULL);
@@ -621,7 +621,7 @@ static void *
 ChangeElement2ndSize (ElementTypePtr Element)
 {
   bool changed = false;
-  BDimension value;
+  Coord value;
 
   if (TEST_FLAG (LOCKFLAG, Element))
     return (NULL);
@@ -663,7 +663,7 @@ ChangeElement2ndSize (ElementTypePtr Element)
 static void *
 ChangePin2ndSize (ElementTypePtr Element, PinTypePtr Pin)
 {
-  BDimension value = (Absolute) ? Absolute : Pin->DrillingHole + Delta;
+  Coord value = (Absolute) ? Absolute : Pin->DrillingHole + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Pin))
     return (NULL);
@@ -696,7 +696,7 @@ ChangePin2ndSize (ElementTypePtr Element, PinTypePtr Pin)
 static void *
 ChangeLineSize (LayerTypePtr Layer, LineTypePtr Line)
 {
-  BDimension value = (Absolute) ? Absolute : Line->Thickness + Delta;
+  Coord value = (Absolute) ? Absolute : Line->Thickness + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Line))
     return (NULL);
@@ -724,7 +724,7 @@ ChangeLineSize (LayerTypePtr Layer, LineTypePtr Line)
 static void *
 ChangeLineClearSize (LayerTypePtr Layer, LineTypePtr Line)
 {
-  BDimension value = (Absolute) ? Absolute : Line->Clearance + Delta;
+  Coord value = (Absolute) ? Absolute : Line->Clearance + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Line) || !TEST_FLAG (CLEARLINEFLAG, Line))
     return (NULL);
@@ -777,7 +777,7 @@ ChangePolygonClearSize (LayerTypePtr Layer, PolygonTypePtr poly)
 static void *
 ChangeArcSize (LayerTypePtr Layer, ArcTypePtr Arc)
 {
-  BDimension value = (Absolute) ? Absolute : Arc->Thickness + Delta;
+  Coord value = (Absolute) ? Absolute : Arc->Thickness + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Arc))
     return (NULL);
@@ -805,7 +805,7 @@ ChangeArcSize (LayerTypePtr Layer, ArcTypePtr Arc)
 static void *
 ChangeArcClearSize (LayerTypePtr Layer, ArcTypePtr Arc)
 {
-  BDimension value = (Absolute) ? Absolute : Arc->Clearance + Delta;
+  Coord value = (Absolute) ? Absolute : Arc->Clearance + Delta;
 
   if (TEST_FLAG (LOCKFLAG, Arc) || !TEST_FLAG (CLEARLINEFLAG, Arc))
     return (NULL);
@@ -838,7 +838,7 @@ ChangeArcClearSize (LayerTypePtr Layer, ArcTypePtr Arc)
 static void *
 ChangeTextSize (LayerTypePtr Layer, TextTypePtr Text)
 {
-  BDimension value = (Absolute) ? Absolute / 45 : Text->Scale + Delta / 45;
+  Coord value = (Absolute) ? Absolute / 45 : Text->Scale + Delta / 45;
 
   if (TEST_FLAG (LOCKFLAG, Text))
     return (NULL);
@@ -866,7 +866,7 @@ ChangeTextSize (LayerTypePtr Layer, TextTypePtr Text)
 static void *
 ChangeElementSize (ElementTypePtr Element)
 {
-  BDimension value;
+  Coord value;
   bool changed = false;
 
   if (TEST_FLAG (LOCKFLAG, Element))
@@ -913,7 +913,7 @@ ChangeElementSize (ElementTypePtr Element)
 static void *
 ChangeElementNameSize (ElementTypePtr Element)
 {
-  BDimension value =
+  Coord value =
     (Absolute) ? Absolute / 45 : DESCRIPTION_TEXT (Element).Scale +
     Delta / 45;
 
@@ -1099,7 +1099,7 @@ ChangeLayoutName (char *Name)
  * returns TRUE if done
  */
 bool
-ChangeElementSide (ElementTypePtr Element, LocationType yoff)
+ChangeElementSide (ElementTypePtr Element, Coord yoff)
 {
   if (TEST_FLAG (LOCKFLAG, Element))
     return (false);
@@ -1691,7 +1691,7 @@ ChangeSelectedThermals (int types, int therm_style)
  * returns true if anything has changed
  */
 bool
-ChangeSelectedSize (int types, LocationType Difference, bool fixIt)
+ChangeSelectedSize (int types, Coord Difference, bool fixIt)
 {
   bool change = false;
 
@@ -1713,7 +1713,7 @@ ChangeSelectedSize (int types, LocationType Difference, bool fixIt)
  * returns true if anything has changed
  */
 bool
-ChangeSelectedClearSize (int types, LocationType Difference, bool fixIt)
+ChangeSelectedClearSize (int types, Coord Difference, bool fixIt)
 {
   bool change = false;
 
@@ -1737,7 +1737,7 @@ ChangeSelectedClearSize (int types, LocationType Difference, bool fixIt)
  * returns true if anything has changed
  */
 bool
-ChangeSelected2ndSize (int types, LocationType Difference, bool fixIt)
+ChangeSelected2ndSize (int types, Coord Difference, bool fixIt)
 {
   bool change = false;
 
@@ -1969,7 +1969,7 @@ ChangeSelectedPaste (void)
  */
 bool
 ChangeObjectSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-		  LocationType Difference, bool fixIt)
+		  Coord Difference, bool fixIt)
 {
   bool change;
 
@@ -1992,7 +1992,7 @@ ChangeObjectSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 bool
 ChangeObjectClearSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-		       LocationType Difference, bool fixIt)
+		       Coord Difference, bool fixIt)
 {
   bool change;
 
@@ -2044,7 +2044,7 @@ ChangeObjectThermal (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 bool
 ChangeObject2ndSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-		     LocationType Difference, bool fixIt, bool incundo)
+		     Coord Difference, bool fixIt, bool incundo)
 {
   bool change;
 
@@ -2069,7 +2069,7 @@ ChangeObject2ndSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 bool
 ChangeObjectMaskSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-		      LocationType Difference, bool fixIt)
+		      Coord Difference, bool fixIt)
 {
   bool change;
 
@@ -2326,7 +2326,7 @@ QueryInputAndChangeObjectName (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
  * and adjusts the cursor confinement box
  */
 void
-ChangePCBSize (BDimension Width, BDimension Height)
+ChangePCBSize (Coord Width, Coord Height)
 {
   PCB->MaxWidth = Width;
   PCB->MaxHeight = Height;
@@ -2346,7 +2346,7 @@ ChangePCBSize (BDimension Width, BDimension Height)
 							     PASTEBUFFER->
 							     Y)));
   else
-    SetCrosshairRange (0, 0, (LocationType) Width, (LocationType) Height);
+    SetCrosshairRange (0, 0, Width, Height);
   hid_action ("PCBChanged");
 }
 
@@ -2357,7 +2357,7 @@ ChangePCBSize (BDimension Width, BDimension Height)
 static void *
 ChangePadMaskSize (ElementTypePtr Element, PadTypePtr Pad)
 {
-  BDimension value = (Absolute) ? Absolute : Pad->Mask + Delta;
+  Coord value = (Absolute) ? Absolute : Pad->Mask + Delta;
 
   value = MAX (value, 0);
   if (value == Pad->Mask && Absolute == 0)
@@ -2382,7 +2382,7 @@ ChangePadMaskSize (ElementTypePtr Element, PadTypePtr Pad)
 static void *
 ChangePinMaskSize (ElementTypePtr Element, PinTypePtr Pin)
 {
-  BDimension value = (Absolute) ? Absolute : Pin->Mask + Delta;
+  Coord value = (Absolute) ? Absolute : Pin->Mask + Delta;
 
   value = MAX (value, 0);
   if (value == Pin->Mask && Absolute == 0)
@@ -2407,7 +2407,7 @@ ChangePinMaskSize (ElementTypePtr Element, PinTypePtr Pin)
 static void *
 ChangeViaMaskSize (PinTypePtr Via)
 {
-  BDimension value;
+  Coord value;
 
   value = (Absolute) ? Absolute : Via->Mask + Delta;
   value = MAX (value, 0);
diff --git a/src/change.h b/src/change.h
index 94a0e21..64c44ff 100644
--- a/src/change.h
+++ b/src/change.h
@@ -67,10 +67,10 @@
 
 bool ChangeLayoutName (char *);
 bool ChangeLayerName (LayerTypePtr, char *);
-bool ChangeSelectedSize (int, LocationType, bool);
-bool ChangeSelectedClearSize (int, LocationType, bool);
-bool ChangeSelected2ndSize (int, LocationType, bool);
-bool ChangeSelectedMaskSize (int, LocationType, bool);
+bool ChangeSelectedSize (int, Coord, bool);
+bool ChangeSelectedClearSize (int, Coord, bool);
+bool ChangeSelected2ndSize (int, Coord, bool);
+bool ChangeSelectedMaskSize (int, Coord, bool);
 bool ChangeSelectedJoin (int);
 bool SetSelectedJoin (int);
 bool ClrSelectedJoin (int);
@@ -84,16 +84,16 @@ bool ChangeSelectedOctagon (int);
 bool SetSelectedOctagon (int);
 bool ClrSelectedOctagon (int);
 bool ChangeSelectedElementSide (void);
-bool ChangeElementSide (ElementTypePtr, LocationType);
+bool ChangeElementSide (ElementTypePtr, Coord);
 bool ChangeHole (PinTypePtr);
 bool ChangePaste (PadTypePtr);
-bool ChangeObjectSize (int, void *, void *, void *, LocationType, bool);
+bool ChangeObjectSize (int, void *, void *, void *, Coord, bool);
 bool ChangeObjectThermal (int, void *, void *, void *, int);
-bool ChangeObjectClearSize (int, void *, void *, void *, LocationType,
+bool ChangeObjectClearSize (int, void *, void *, void *, Coord,
 			       bool);
-bool ChangeObject2ndSize (int, void *, void *, void *, LocationType,
+bool ChangeObject2ndSize (int, void *, void *, void *, Coord,
 			     bool, bool);
-bool ChangeObjectMaskSize (int, void *, void *, void *, LocationType,
+bool ChangeObjectMaskSize (int, void *, void *, void *, Coord,
 			      bool);
 bool ChangeObjectJoin (int, void *, void *, void *);
 bool SetObjectJoin (int, void *, void *, void *);
@@ -106,7 +106,7 @@ bool SetObjectOctagon (int, void *, void *, void *);
 bool ClrObjectOctagon (int, void *, void *, void *);
 void *ChangeObjectName (int, void *, void *, void *, char *);
 void *QueryInputAndChangeObjectName (int, void *, void *, void *);
-void ChangePCBSize (BDimension, BDimension);
+void ChangePCBSize (Coord, Coord);
 
 /* Change the specified text on an element, either on the board (give
    PCB, PCB->Data) or in a buffer (give NULL, Buffer->Data).  The old

commit b59ab044afe3ac362f8cb4da10ea410280b4323a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit copy.[ch], insert.[ch], mirror.[ch], implement Coord

diff --git a/src/copy.c b/src/copy.c
index 4091389..29ac62f 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -72,7 +72,7 @@ static void *CopyElement (ElementTypePtr);
 /* ---------------------------------------------------------------------------
  * some local identifiers
  */
-static LocationType DeltaX, DeltaY;	/* movement vector */
+static Coord DeltaX, DeltaY;	/* movement vector */
 static ObjectFunctionType CopyFunctions = {
   CopyLine,
   CopyText,
@@ -119,8 +119,8 @@ CopyPolygonLowLevel (PolygonTypePtr Dest, PolygonTypePtr Src)
  */
 ElementTypePtr
 CopyElementLowLevel (DataTypePtr Data, ElementTypePtr Dest,
-		     ElementTypePtr Src, bool uniqueName, LocationType dx,
-		     LocationType dy)
+		     ElementTypePtr Src, bool uniqueName, Coord dx,
+		     Coord dy)
 {
   int i;
   /* release old memory if necessary */
@@ -322,7 +322,7 @@ CopyElement (ElementTypePtr Element)
  * are handled by the routine.
  */
 bool
-CopyPastebufferToLayout (LocationType X, LocationType Y)
+CopyPastebufferToLayout (Coord X, Coord Y)
 {
   Cardinal i;
   bool changed = false;
@@ -418,7 +418,7 @@ CopyPastebufferToLayout (LocationType X, LocationType Y)
  */
 void *
 CopyObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-	    LocationType DX, LocationType DY)
+	    Coord DX, Coord DY)
 {
   void *ptr;
 
diff --git a/src/copy.h b/src/copy.h
index bd2ea80..e65c272 100644
--- a/src/copy.h
+++ b/src/copy.h
@@ -43,8 +43,8 @@
 
 PolygonTypePtr CopyPolygonLowLevel (PolygonTypePtr, PolygonTypePtr);
 ElementTypePtr CopyElementLowLevel (DataTypePtr, ElementTypePtr,
-				    ElementTypePtr, bool, LocationType, LocationType);
-bool CopyPastebufferToLayout (LocationType, LocationType);
-void *CopyObject (int, void *, void *, void *, LocationType, LocationType);
+				    ElementTypePtr, bool, Coord, Coord);
+bool CopyPastebufferToLayout (Coord, Coord);
+void *CopyObject (int, void *, void *, void *, Coord, Coord);
 
 #endif
diff --git a/src/insert.c b/src/insert.c
index 9313807..514754f 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -71,8 +71,7 @@ static void *InsertPointIntoRat (RatTypePtr);
 /* ---------------------------------------------------------------------------
  * some local identifiers
  */
-static LocationType InsertX,	/* used by local routines as offset */
-  InsertY;
+static Coord InsertX, InsertY;	/* used by local routines as offset */
 static Cardinal InsertAt;
 static bool InsertLast;
 static bool Forcible;
@@ -127,7 +126,7 @@ static void *
 InsertPointIntoLine (LayerTypePtr Layer, LineTypePtr Line)
 {
   LineTypePtr line;
-  LocationType X, Y;
+  Coord X, Y;
 
   if (((Line->Point1.X == InsertX) && (Line->Point1.Y == InsertY)) ||
       ((Line->Point2.X == InsertX) && (Line->Point2.Y == InsertY)))
@@ -219,7 +218,7 @@ InsertPointIntoPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon)
  */
 void *
 InsertPointIntoObject (int Type, void *Ptr1, void *Ptr2, Cardinal * Ptr3,
-		       LocationType DX, LocationType DY, bool Force,
+		       Coord DX, Coord DY, bool Force,
 		       bool insert_last)
 {
   void *ptr;
@@ -245,8 +244,8 @@ PointTypePtr
 AdjustInsertPoint (void)
 {
   static PointType InsertedPoint;
-  float m;
-  LocationType x, y, dx, dy, m1, m2;
+  double m;
+  Coord x, y, m1, m2;
   LineTypePtr line = (LineTypePtr) Crosshair.AttachedObject.Ptr2;
 
   if (Crosshair.AttachedObject.State == STATE_FIRST)
@@ -255,13 +254,9 @@ AdjustInsertPoint (void)
   if (gui->shift_is_pressed ())
     {
       AttachedLineType myline;
-      dx = Crosshair.X - line->Point1.X;
-      dy = Crosshair.Y - line->Point1.Y;
-      m = dx * dx + dy * dy;
-      dx = Crosshair.X - line->Point2.X;
-      dy = Crosshair.Y - line->Point2.Y;
       /* only force 45 degree for nearest point */
-      if (m < (dx * dx + dy * dy))
+      if (Distance (Crosshair.X, Crosshair.Y, line->Point1.X, line->Point1.Y) <
+          Distance (Crosshair.X, Crosshair.Y, line->Point2.X, line->Point2.Y))
 	myline.Point1 = myline.Point2 = line->Point1;
       else
 	myline.Point1 = myline.Point2 = line->Point2;
@@ -276,26 +271,22 @@ AdjustInsertPoint (void)
       InsertedPoint.Y = Crosshair.Y;
       return &InsertedPoint;
     }
-  dx = Crosshair.X - line->Point1.X;
-  dy = Crosshair.Y - line->Point1.Y;
-  if (!dx)
+  if (Crosshair.X == line->Point1.X)
     m1 = 2;			/* 2 signals infinite slope */
   else
     {
-      m = (float) dy / (float) dx;
+      m = (double) (Crosshair.X - line->Point1.X) / (Crosshair.Y - line->Point1.Y);
       m1 = 0;
       if (m > TAN_30_DEGREE)
 	m1 = (m > TAN_60_DEGREE) ? 2 : 1;
       else if (m < -TAN_30_DEGREE)
 	m1 = (m < -TAN_60_DEGREE) ? 2 : -1;
     }
-  dx = Crosshair.X - line->Point2.X;
-  dy = Crosshair.Y - line->Point2.Y;
-  if (!dx)
+  if (Crosshair.X == line->Point2.X)
     m2 = 2;			/* 2 signals infinite slope */
   else
     {
-      m = (float) dy / (float) dx;
+      m = (double) (Crosshair.X - line->Point1.X) / (Crosshair.Y - line->Point1.Y);
       m2 = 0;
       if (m > TAN_30_DEGREE)
 	m2 = (m > TAN_60_DEGREE) ? 2 : 1;
diff --git a/src/insert.h b/src/insert.h
index 51c75e4..0476e8d 100644
--- a/src/insert.h
+++ b/src/insert.h
@@ -38,8 +38,8 @@
 /* ---------------------------------------------------------------------------
  * prototypes
  */
-void *InsertPointIntoObject (int, void *, void *, Cardinal *, LocationType,
-			     LocationType, bool, bool);
+void *InsertPointIntoObject (int, void *, void *, Cardinal *, Coord,
+			     Coord, bool, bool);
 PointTypePtr AdjustInsertPoint (void);
 
 #endif
diff --git a/src/mirror.c b/src/mirror.c
index 7ef7d41..c48ebf3 100644
--- a/src/mirror.c
+++ b/src/mirror.c
@@ -65,7 +65,7 @@ RCSID ("$Id$");
  */
 void
 MirrorElementCoordinates (DataTypePtr Data, ElementTypePtr Element,
-			  LocationType yoff)
+			  Coord yoff)
 {
   r_delete_element (Data, Element);
   ELEMENTLINE_LOOP (Element);
diff --git a/src/mirror.h b/src/mirror.h
index 94d17c1..da61744 100644
--- a/src/mirror.h
+++ b/src/mirror.h
@@ -41,6 +41,6 @@
 #define	MIRROR_TYPES	(TEXT_TYPE | ELEMENTNAME_TYPE)
 
 
-void MirrorElementCoordinates (DataTypePtr, ElementTypePtr, LocationType);
+void MirrorElementCoordinates (DataTypePtr, ElementTypePtr, Coord);
 
 #endif

commit a2af8aa83d106a9f0800ea5fe502e8d0e99ac651
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit misc.[ch], implement Coord

diff --git a/src/misc.c b/src/misc.c
index 97937aa..7c6f958 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -85,9 +85,8 @@ RCSID ("$Id$");
 
 /*	forward declarations	*/
 static char *BumpName (char *);
-static void RightAngles (int, float *, float *);
 static void GetGridLockCoordinates (int, void *, void *, void *,
-                                    LocationType *, LocationType *);
+                                    Coord *, Coord *);
 
 
 /* Local variables */
@@ -231,16 +230,15 @@ SetPointBoundingBox (PointTypePtr Pnt)
 void
 SetPinBoundingBox (PinTypePtr Pin)
 {
-  BDimension width;
+  Coord width;
 
   /* the bounding box covers the extent of influence
    * so it must include the clearance values too
    */
-  width = (Pin->Clearance + PIN_SIZE (Pin) + 1) / 2;
-  width = MAX (width, (Pin->Mask + 1) / 2);
+  width = MAX (Pin->Clearance + PIN_SIZE (Pin), Pin->Mask) / 2;
 
   /* Adjust for our discrete polygon approximation */
-  width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+  width = (double)width * POLY_CIRC_RADIUS_ADJ + 0.5;
 
   Pin->BoundingBox.X1 = Pin->X - width;
   Pin->BoundingBox.Y1 = Pin->Y - width;
@@ -255,9 +253,9 @@ SetPinBoundingBox (PinTypePtr Pin)
 void
 SetPadBoundingBox (PadTypePtr Pad)
 {
-  BDimension width;
-  BDimension deltax;
-  BDimension deltay;
+  Coord width;
+  Coord deltax;
+  Coord deltay;
 
   /* the bounding box covers the extent of influence
    * so it must include the clearance values too
@@ -270,19 +268,15 @@ SetPadBoundingBox (PadTypePtr Pad)
   if (TEST_FLAG (SQUAREFLAG, Pad) && deltax != 0 && deltay != 0)
     {
       /* slanted square pad */
-      float tx, ty, theta;
-      BDimension btx, bty;
-
-      theta = atan2 (deltay, deltax);
+      double theta;
+      Coord btx, bty;
 
       /* T is a vector half a thickness long, in the direction of
           one of the corners.  */
-      tx = width * cos (theta + M_PI/4) * sqrt(2.0);
-      ty = width * sin (theta + M_PI/4) * sqrt(2.0);
+      theta = atan2 (deltay, deltax);
+      btx = width * cos (theta + M_PI/4) * sqrt(2.0);
+      bty = width * sin (theta + M_PI/4) * sqrt(2.0);
 
-      /* cast back to this integer type */
-      btx = tx;
-      bty = ty;
 
       Pad->BoundingBox.X1 = MIN (MIN (Pad->Point1.X - btx, Pad->Point1.X - bty),
                                  MIN (Pad->Point2.X + btx, Pad->Point2.X + bty));
@@ -296,7 +290,7 @@ SetPadBoundingBox (PadTypePtr Pad)
   else
     {
       /* Adjust for our discrete polygon approximation */
-      width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+      width = (double)width * POLY_CIRC_RADIUS_ADJ + 0.5;
 
       Pad->BoundingBox.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - width;
       Pad->BoundingBox.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + width;
@@ -312,12 +306,10 @@ SetPadBoundingBox (PadTypePtr Pad)
 void
 SetLineBoundingBox (LineTypePtr Line)
 {
-  BDimension width;
-
-  width = (Line->Thickness + Line->Clearance + 1) / 2;
+  Coord width = (Line->Thickness + Line->Clearance + 1) / 2;
 
   /* Adjust for our discrete polygon approximation */
-  width = (int)((float)width * POLY_CIRC_RADIUS_ADJ + 0.5);
+  width = (double)width * POLY_CIRC_RADIUS_ADJ + 0.5;
 
   Line->BoundingBox.X1 = MIN (Line->Point1.X, Line->Point2.X) - width;
   Line->BoundingBox.X2 = MAX (Line->Point1.X, Line->Point2.X) + width;
@@ -505,14 +497,15 @@ SetTextBoundingBox (FontTypePtr FontPtr, TextTypePtr Text)
 {
   SymbolTypePtr symbol = FontPtr->Symbol;
   unsigned char *s = (unsigned char *) Text->TextString;
-  BDimension minThick = 0;
+  Coord minThick = 0;
   int i;
   int space = 0;
 
-  LocationType minx=0, miny=0, maxx=0, maxy=0;
-  LocationType tx;
+  Coord minx, miny, maxx, maxy, tx;
   int first_time = 1;
 
+  minx = miny = maxx = maxy = tx = 0;
+
   if (PCB->minSlk < PCB->minWid)
     minThick = PCB->minWid;
   else
@@ -520,8 +513,6 @@ SetTextBoundingBox (FontTypePtr FontPtr, TextTypePtr Text)
 
   minThick /= Text->Scale / 50.0;
 
-  tx = 0;
-
   /* calculate size of the bounding box */
   for (; s && *s; s++)
     {
@@ -530,7 +521,7 @@ SetTextBoundingBox (FontTypePtr FontPtr, TextTypePtr Text)
 	  LineTypePtr line = symbol[*s].Line;
 	  for (i = 0; i < symbol[*s].LineN; line++, i++)
 	    {
-	      int t = line->Thickness / 4;
+	      Coord t = line->Thickness / 4;
 	      if (t < minThick)
 		t = minThick;
 
@@ -555,7 +546,7 @@ SetTextBoundingBox (FontTypePtr FontPtr, TextTypePtr Text)
       else
 	{
 	  BoxType *ds = &FontPtr->DefaultSymbol;
-	  int w = ds->X2 - ds->X1;
+	  Coord w = ds->X2 - ds->X1;
 
 	  minx = MIN (minx, ds->X1 + tx);
 	  miny = MIN (miny, ds->Y1);
@@ -783,7 +774,7 @@ SetFontInfo (FontTypePtr Ptr)
   Cardinal i, j;
   SymbolTypePtr symbol;
   LineTypePtr line;
-  LocationType totalminy = MAX_COORD;
+  Coord totalminy = MAX_COORD;
 
   /* calculate cell with and height (is at least DEFAULT_CELLSIZE)
    * maximum cell width and height
@@ -793,7 +784,7 @@ SetFontInfo (FontTypePtr Ptr)
   Ptr->MaxHeight = DEFAULT_CELLSIZE;
   for (i = 0, symbol = Ptr->Symbol; i <= MAX_FONTPOSITION; i++, symbol++)
     {
-      LocationType minx, miny, maxx, maxy;
+      Coord minx, miny, maxx, maxy;
 
       /* next one if the index isn't used or symbol is empty (SPACE) */
       if (!symbol->Valid || !symbol->LineN)
@@ -842,12 +833,11 @@ SetFontInfo (FontTypePtr Ptr)
   Ptr->DefaultSymbol.Y2 = Ptr->DefaultSymbol.Y1 + Ptr->MaxHeight;
 }
 
-static BDimension
+static Coord
 GetNum (char **s, const char *default_unit)
 {
-  BDimension ret_val;
   /* Read value */
-  ret_val = GetValueEx(*s, NULL, NULL, NULL, default_unit);
+  Coord ret_val = GetValueEx (*s, NULL, NULL, NULL, default_unit);
   /* Advance pointer */
   while(isalnum(**s) || **s == '.')
      (*s)++;
@@ -1414,78 +1404,56 @@ SetArcBoundingBox (ArcTypePtr Arc)
 {
   double ca1, ca2, sa1, sa2;
   double minx, maxx, miny, maxy;
-  LocationType ang1, ang2, delta, a;
-  LocationType width;
+  Angle ang1, ang2;
+  Coord width;
 
-  /* first put angles into standard form */
-  if (Arc->Delta > 360)
-    Arc->Delta = 360;
-  if (Arc->Delta < -360)
-    Arc->Delta = -360;
+  /* first put angles into standard form:
+   *  ang1 < ang2, both angles between 0 and 720 */
+  Arc->Delta = CLAMP (Arc->Delta, -360, 360);
 
   if (Arc->Delta > 0)
     {
-      ang1 = Arc->StartAngle;
-      delta = Arc->Delta;
+      ang1 = NormalizeAngle (Arc->StartAngle);
+      ang2 = NormalizeAngle (Arc->StartAngle + Arc->Delta);
     }
   else
     {
-      ang1 = Arc->StartAngle + Arc->Delta;
-      delta = -Arc->Delta;
+      ang1 = NormalizeAngle (Arc->StartAngle + Arc->Delta);
+      ang2 = NormalizeAngle (Arc->StartAngle);
     }
-  if (ang1 < 0)
-    ang1 = 360 - ((-ang1) % 360);
-  else
-    ang1 = ang1 % 360;
-
-  ang2 = ang1 + delta;
+  if (ang1 > ang2)
+    ang2 += 360;
+  /* Make sure full circles aren't treated as zero-length arcs */
+  if (Arc->Delta == 360 || Arc->Delta == -360)
+    ang2 = ang1 + 360;
 
   /* calculate sines, cosines */
-  ca1 = M180 * (double) ang1;
-  sa1 = sin (ca1);
-  ca1 = cos (ca1);
-
-  minx = maxx = ca1;
-  miny = maxy = sa1;
-
-  ca2 = M180 * (double) ang2;
-  sa2 = sin (ca2);
-  ca2 = cos (ca2);
-
-  minx = MIN (minx, ca2);
-  maxx = MAX (maxx, ca2);
-  miny = MIN (miny, sa2);
-  maxy = MAX (maxy, sa2);
-
-  for (a = ang1 - ang1 % 90 + 90; a < ang2; a += 90)
-    {
-      switch (a % 360)
-	{
-	case 0:
-	  maxx = 1;
-	  break;
-	case 90:
-	  maxy = 1;
-	  break;
-	case 180:
-	  minx = -1;
-	  break;
-	case 270:
-	  miny = -1;
-	  break;
-	}
-    }
-
-  Arc->BoundingBox.X2 = Arc->X - Arc->Width * minx;
+  sa1 = sin (M180 * ang1);
+  ca1 = cos (M180 * ang1);
+  sa2 = sin (M180 * ang2);
+  ca2 = cos (M180 * ang2);
+
+  minx = MIN (ca1, ca2);
+  maxx = MAX (ca1, ca2);
+  miny = MIN (sa1, sa2);
+  maxy = MAX (sa1, sa2);
+
+  /* Check for extreme angles */
+  if ((ang1 <= 0   && ang2 >= 0)   || (ang1 <= 360 && ang2 >= 360)) maxx = 1;
+  if ((ang1 <= 90  && ang2 >= 90)  || (ang1 <= 450 && ang2 >= 450)) maxy = 1;
+  if ((ang1 <= 180 && ang2 >= 180) || (ang1 <= 540 && ang2 >= 540)) minx = -1;
+  if ((ang1 <= 270 && ang2 >= 270) || (ang1 <= 630 && ang2 >= 630)) miny = -1;
+
+  /* Finally, calcate bounds, converting sane geometry into pcb geometry */
   Arc->BoundingBox.X1 = Arc->X - Arc->Width * maxx;
-  Arc->BoundingBox.Y2 = Arc->Y + Arc->Height * maxy;
+  Arc->BoundingBox.X2 = Arc->X - Arc->Width * minx;
   Arc->BoundingBox.Y1 = Arc->Y + Arc->Height * miny;
+  Arc->BoundingBox.Y2 = Arc->Y + Arc->Height * maxy;
 
   width = (Arc->Thickness + Arc->Clearance) / 2;
 
   /* Adjust for our discrete polygon approximation */
-  width = (int)((float)width * MAX (POLY_CIRC_RADIUS_ADJ,
-                                     (1.0 + POLY_ARC_MAX_DEVIATION)) + 0.5);
+  width = (double)width * MAX (POLY_CIRC_RADIUS_ADJ, (1.0 + POLY_ARC_MAX_DEVIATION)) + 0.5;
 
   Arc->BoundingBox.X1 -= width;
   Arc->BoundingBox.X2 += width;
@@ -1626,34 +1594,22 @@ CreateQuotedString (DynamicStringTypePtr DS, char *S)
   DSAddCharacter (DS, '"');
 }
 
-
-static void
-RightAngles (int Angle, float *cosa, float *sina)
-{
-  *cosa = (float) cos ((double) Angle * M180);
-  *sina = (float) sin ((double) Angle * M180);
-}
-
 BoxTypePtr
 GetArcEnds (ArcTypePtr Arc)
 {
   static BoxType box;
-  float ca, sa;
-
-  RightAngles (Arc->StartAngle, &ca, &sa);
-  box.X1 = Arc->X - Arc->Width * ca;
-  box.Y1 = Arc->Y + Arc->Height * sa;
-  RightAngles (Arc->StartAngle + Arc->Delta, &ca, &sa);
-  box.X2 = Arc->X - Arc->Width * ca;
-  box.Y2 = Arc->Y + Arc->Height * sa;
-  return (&box);
+  box.X1 = Arc->X - Arc->Width * cos (Arc->StartAngle * M180);
+  box.Y1 = Arc->Y + Arc->Height * sin (Arc->StartAngle * M180);
+  box.X2 = Arc->X - Arc->Width * cos ((Arc->StartAngle + Arc->Delta) * M180);
+  box.Y2 = Arc->Y + Arc->Height * sin ((Arc->StartAngle + Arc->Delta) * M180);
+  return &box;
 }
 
 
 /* doesn't this belong in change.c ?? */
 void
 ChangeArcAngles (LayerTypePtr Layer, ArcTypePtr a,
-                 long int new_sa, long int new_da)
+                 Angle new_sa, Angle new_da)
 {
   if (new_da >= 360)
     {
@@ -1730,8 +1686,8 @@ UniqueElementName (DataTypePtr Data, char *Name)
 
 static void
 GetGridLockCoordinates (int type, void *ptr1,
-                        void *ptr2, void *ptr3, LocationType * x,
-                        LocationType * y)
+                        void *ptr2, void *ptr3, Coord * x,
+                        Coord * y)
 {
   switch (type)
     {
@@ -1775,10 +1731,10 @@ GetGridLockCoordinates (int type, void *ptr1,
 }
 
 void
-AttachForCopy (LocationType PlaceX, LocationType PlaceY)
+AttachForCopy (Coord PlaceX, Coord PlaceY)
 {
   BoxTypePtr box;
-  LocationType mx = 0, my = 0;
+  Coord mx = 0, my = 0;
 
   Crosshair.AttachedObject.RubberbandN = 0;
   if (! TEST_FLAG (SNAPPINFLAG, PCB))
@@ -2094,8 +2050,8 @@ AttributeRemoveFromList(AttributeListType *list, char *name)
       }
 }
 
-
-
+/* In future all use of this should be supplanted by
+ * pcb-printf and %mr/%m# spec */
 const char *
 c_dtostr (double d)
 {
@@ -2120,71 +2076,6 @@ c_dtostr (double d)
   return buf;
 }
 
-double
-c_strtod (const char *s)
-{
-  double rv = 0;
-  double sign = 1.0;
-  double scale;
-
-  /* leading whitespace */
-  while (*s && (*s == ' ' || *s == '\t'))
-    s++;
-
-  /* optional sign */
-  if (*s == '-')
-    {
-      sign = -1.0;
-      s++;
-    }
-  else if (*s == '+')
-    s++;
-
-  /* integer portion */
-  while (*s >= '0' && *s <= '9')
-    {
-      rv *= 10.0;
-      rv += *s - '0';
-      s++;
-    }
-
-  /* fractional portion */
-  if (*s == '.')
-    {
-      s++;
-      scale = 0.1;
-      while (*s >= '0' && *s <= '9')
-        {
-          rv += (*s - '0') * scale;
-          scale *= 0.1;
-          s++;
-        }
-    }
-
-  /* exponent */
-  if (*s == 'E' || *s == 'e')
-    {
-      int e;
-      if (sscanf (s + 1, "%d", &e) == 1)
-        {
-          scale = 1.0;
-          while (e > 0)
-            {
-              scale *= 10.0;
-              e--;
-            }
-          while (e < 0)
-            {
-              scale *= 0.1;
-              e++;
-            }
-          rv *= scale;
-        }
-    }
-
-  return rv * sign;
-}
-
 void
 r_delete_element (DataType * data, ElementType * element)
 {
@@ -2320,9 +2211,9 @@ pcb_mkdir (const char *path, int mode)
 int 
 ElementOrientation (ElementType *e)
 {
-  int pin1x, pin1y, pin2x, pin2y, dx, dy;
-  int found_pin1 = 0;
-  int found_pin2 = 0;
+  Coord pin1x, pin1y, pin2x, pin2y, dx, dy;
+  bool found_pin1 = 0;
+  bool found_pin2 = 0;
 
   /* in case we don't find pin 1 or 2, make sure we have initialized these variables */
   pin1x = 0;
diff --git a/src/misc.h b/src/misc.h
index 21fec7e..deaca84 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -85,9 +85,9 @@ void RestoreStackAndVisibility (void);
 char *GetWorkingDirectory (char *);
 void CreateQuotedString (DynamicStringTypePtr, char *);
 BoxTypePtr GetArcEnds (ArcTypePtr);
-void ChangeArcAngles (LayerTypePtr, ArcTypePtr, long int, long int);
+void ChangeArcAngles (LayerTypePtr, ArcTypePtr, Angle, Angle);
 char *UniqueElementName (DataTypePtr, char *);
-void AttachForCopy (LocationType, LocationType);
+void AttachForCopy (Coord, Coord);
 double GetValue (const char *, const char *, bool *);
 double GetValueEx (const char *, const char *, bool *, UnitList, const char *);
 int FileExists (const char *);
@@ -128,7 +128,6 @@ char *LayerGroupsToString (LayerGroupTypePtr);
 void MakeLayerGroupsDefault ();
 
 /* These act like you'd expect, except always in the C locale.  */
-extern double c_strtod(const char *s);
 extern const char *c_dtostr(double d);
 
 /* Returns a string with info about this copy of pcb. */

commit 27de2a3b9075415d6664bdb39c6e59cba970c441
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit move.[ch], implement Coord

diff --git a/src/move.c b/src/move.c
index 3477af1..6b6359a 100644
--- a/src/move.c
+++ b/src/move.c
@@ -84,8 +84,7 @@ static void *MovePolygonToLayer (LayerTypePtr, PolygonTypePtr);
 /* ---------------------------------------------------------------------------
  * some local identifiers
  */
-static LocationType DeltaX,	/* used by local routines as offset */
-  DeltaY;
+static Coord DeltaX, DeltaY;	/* used by local routines as offset */
 static LayerTypePtr Dest;
 static bool MoreToCome;
 static ObjectFunctionType MoveFunctions = {
@@ -114,7 +113,7 @@ MoveLineToLayer,
  */
 void
 MoveElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
-		     LocationType DX, LocationType DY)
+		     Coord DX, Coord DY)
 {
   if (Data)
     r_delete_entry (Data->element_tree, (BoxType *)Element);
@@ -334,8 +333,7 @@ MoveText (LayerTypePtr Layer, TextTypePtr Text)
  * low level routine to move a polygon
  */
 void
-MovePolygonLowLevel (PolygonTypePtr Polygon, LocationType DeltaX,
-		     LocationType DeltaY)
+MovePolygonLowLevel (PolygonTypePtr Polygon, Coord DeltaX, Coord DeltaY)
 {
   POLYGONPOINT_LOOP (Polygon);
   {
@@ -512,8 +510,8 @@ static void *
 MoveRatToLayer (RatType *Rat)
 {
   LineTypePtr newone;
-  //LocationType X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
-  //LocationType X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
+  //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
+  //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
   // if VIAFLAG
   //   if we're on a pin, add a thermal
   //   else make a via and a wire, but 0-length wire not good
@@ -542,7 +540,7 @@ MoveRatToLayer (RatType *Rat)
 
 struct via_info
 {
-  LocationType X, Y;
+  Coord X, Y;
   jmp_buf env;
 };
 
@@ -777,8 +775,7 @@ MovePolygonToLayer (LayerType *Layer, PolygonType *Polygon)
  * not we don't bump the undo serial number
  */
 void *
-MoveObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-	    LocationType DX, LocationType DY)
+MoveObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3, Coord DX, Coord DY)
 {
   void *result;
   /* setup offset */
@@ -795,7 +792,7 @@ MoveObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 void *
 MoveObjectAndRubberband (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-			 LocationType DX, LocationType DY)
+			 Coord DX, Coord DY)
 {
   RubberbandTypePtr ptr;
   void *ptr2;
diff --git a/src/move.h b/src/move.h
index 2b41bce..e617eca 100644
--- a/src/move.h
+++ b/src/move.h
@@ -93,13 +93,12 @@
 /* ---------------------------------------------------------------------------
  * prototypes
  */
-void MovePolygonLowLevel (PolygonTypePtr, LocationType, LocationType);
-void MoveElementLowLevel (DataTypePtr, ElementTypePtr, LocationType,
-			  LocationType);
-void *MoveObject (int, void *, void *, void *, LocationType, LocationType);
+void MovePolygonLowLevel (PolygonTypePtr, Coord, Coord);
+void MoveElementLowLevel (DataTypePtr, ElementTypePtr, Coord, Coord);
+void *MoveObject (int, void *, void *, void *, Coord, Coord);
 void *MoveObjectToLayer (int, void *, void *, void *, LayerTypePtr, bool);
 void *MoveObjectAndRubberband (int, void *, void *, void *,
-			       LocationType, LocationType);
+			       Coord, Coord);
 bool MoveSelectedObjectsToLayer (LayerTypePtr);
 
 /* index is 0..MAX_LAYER-1.  If old_index is -1, a new layer is

commit 6d08a5996f48dece369b278b1ca41cd8250b4e3c
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit polygon*, polyarea.h, implement Coord

diff --git a/src/polyarea.h b/src/polyarea.h
index 413f519..43fd93d 100644
--- a/src/polyarea.h
+++ b/src/polyarea.h
@@ -51,7 +51,7 @@ enum {
 #endif
 
 
-typedef int vertex[2];  /* longing point representation of
+typedef Coord vertex[2];  /* longing point representation of
                              coordinates */
 typedef vertex Vector;
 
@@ -93,16 +93,15 @@ struct VNODE
 typedef struct PLINE PLINE;
 struct PLINE
 {
-    int xmin, ymin, xmax, ymax;
+    Coord xmin, ymin, xmax, ymax;
     PLINE *next;
     VNODE head;
     unsigned int Count;
     double area;
     rtree_t *tree;
-    int is_round;
-    int cx;
-    int cy;
-    int radius;
+    bool is_round;
+    Coord cx, cy;
+    Coord radius;
     struct {
       unsigned int status:3;
       unsigned int orient:1;
diff --git a/src/polygon.c b/src/polygon.c
index 72a9299..7367968 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -330,7 +330,7 @@ PolygonToPoly (PolygonType *p)
 }
 
 POLYAREA *
-RectPoly (LocationType x1, LocationType x2, LocationType y1, LocationType y2)
+RectPoly (Coord x1, Coord x2, Coord y1, Coord y2)
 {
   PLINE *contour = NULL;
   Vector v;
@@ -354,7 +354,7 @@ RectPoly (LocationType x1, LocationType x2, LocationType y1, LocationType y2)
 }
 
 POLYAREA *
-OctagonPoly (LocationType x, LocationType y, BDimension radius)
+OctagonPoly (Coord x, Coord y, Coord radius)
 {
   PLINE *contour = NULL;
   Vector v;
@@ -392,7 +392,7 @@ OctagonPoly (LocationType x, LocationType y, BDimension radius)
  * or 4 for a quarter circle
  */
 void
-frac_circle (PLINE * c, LocationType X, LocationType Y, Vector v, int range)
+frac_circle (PLINE * c, Coord X, Coord Y, Vector v, int range)
 {
   double e1, e2, t1;
   int i;
@@ -418,7 +418,7 @@ frac_circle (PLINE * c, LocationType X, LocationType Y, Vector v, int range)
 
 /* create a circle approximation from lines */
 POLYAREA *
-CirclePoly (LocationType x, LocationType y, BDimension radius)
+CirclePoly (Coord x, Coord y, Coord radius)
 {
   PLINE *contour;
   Vector v;
@@ -439,8 +439,7 @@ CirclePoly (LocationType x, LocationType y, BDimension radius)
 
 /* make a rounded-corner rectangle with radius t beyond x1,x2,y1,y2 rectangle */
 POLYAREA *
-RoundRect (LocationType x1, LocationType x2, LocationType y1, LocationType y2,
-           BDimension t)
+RoundRect (Coord x1, Coord x2, Coord y1, Coord y2, Coord t)
 {
   PLINE *contour = NULL;
   Vector v;
@@ -469,7 +468,7 @@ RoundRect (LocationType x1, LocationType x2, LocationType y1, LocationType y2,
 
 #define ARC_ANGLE 5
 static POLYAREA *
-ArcPolyNoIntersect (ArcType * a, BDimension thick)
+ArcPolyNoIntersect (ArcType * a, Coord thick)
 {
   PLINE *contour = NULL;
   POLYAREA *np = NULL;
@@ -543,7 +542,7 @@ ArcPolyNoIntersect (ArcType * a, BDimension thick)
 
 #define MIN_CLEARANCE_BEFORE_BISECT 10.
 POLYAREA *
-ArcPoly (ArcType * a, BDimension thick)
+ArcPoly (ArcType * a, Coord thick)
 {
   double delta;
   ArcType seg1, seg2;
@@ -573,7 +572,7 @@ ArcPoly (ArcType * a, BDimension thick)
 }
 
 POLYAREA *
-LinePoly (LineType * L, BDimension thick)
+LinePoly (LineType * L, Coord thick)
 {
   PLINE *contour = NULL;
   POLYAREA *np = NULL;
@@ -635,7 +634,7 @@ LinePoly (LineType * L, BDimension thick)
 
 /* make a rounded-corner rectangle */
 POLYAREA *
-SquarePadPoly (PadType * pad, BDimension clear)
+SquarePadPoly (PadType * pad, Coord clear)
 {
   PLINE *contour = NULL;
   POLYAREA *np = NULL;
@@ -753,7 +752,7 @@ Subtract (POLYAREA * np1, PolygonType * p, bool fnp)
 
 /* create a polygon of the pin clearance */
 POLYAREA *
-PinPoly (PinType * pin, BDimension thick, BDimension clear)
+PinPoly (PinType * pin, Coord thick, Coord clear)
 {
   int size;
 
@@ -775,7 +774,7 @@ PinPoly (PinType * pin, BDimension thick, BDimension clear)
 }
 
 POLYAREA *
-BoxPolyBloated (BoxType *box, BDimension bloat)
+BoxPolyBloated (BoxType *box, Coord bloat)
 {
   return RectPoly (box->X1 - bloat, box->X2 + bloat,
                    box->Y1 - bloat, box->Y2 + bloat);
@@ -1030,7 +1029,7 @@ Group (DataTypePtr Data, Cardinal layer)
 
 static int
 clearPoly (DataTypePtr Data, LayerTypePtr Layer, PolygonType * polygon,
-           const BoxType * here, BDimension expand)
+           const BoxType * here, Coord expand)
 {
   int r = 0;
   BoxType region;
@@ -1251,7 +1250,7 @@ RemoveExcessPolygonPoints (LayerTypePtr Layer, PolygonTypePtr Polygon)
       line.Point1 = Polygon->Points[prev];
       line.Point2 = Polygon->Points[next];
       line.Thickness = 0;
-      if (IsPointOnLine ((float) p->X, (float) p->Y, 0.0, &line))
+      if (IsPointOnLine (p->X, p->Y, 0.0, &line))
         {
           RemoveObject (POLYGONPOINT_TYPE, Layer, Polygon, p);
           changed = true;
@@ -1266,8 +1265,7 @@ RemoveExcessPolygonPoints (LayerTypePtr Layer, PolygonTypePtr Polygon)
  * coordinates
  */
 Cardinal
-GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, LocationType X,
-                               LocationType Y)
+GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, Coord X, Coord Y)
 {
   double mindistance = (double) MAX_COORD * MAX_COORD;
   PointTypePtr ptr1, ptr2;
@@ -1282,7 +1280,7 @@ GetLowestDistancePolygonPoint (PolygonTypePtr Polygon, LocationType X,
 
   for (n = 0; n < Polygon->PointN; n++)
     {
-      register double u, dx, dy;
+      double u, dx, dy;
       ptr1 = &Polygon->Points[prev_contour_point (Polygon, n)];
       ptr2 = &Polygon->Points[n];
 
@@ -1365,7 +1363,7 @@ ClosePolygon (void)
        */
       if (!TEST_FLAG (ALLDIRECTIONFLAG, PCB))
         {
-          BDimension dx, dy;
+          Coord dx, dy;
 
           dx = abs (Crosshair.AttachedPolygon.Points[n - 1].X -
                     Crosshair.AttachedPolygon.Points[0].X);
@@ -1656,8 +1654,7 @@ isects (POLYAREA * a, PolygonTypePtr p, bool fr)
 
 
 bool
-IsPointInPolygon (LocationType X, LocationType Y, BDimension r,
-                  PolygonTypePtr p)
+IsPointInPolygon (Coord X, Coord Y, Coord r, PolygonTypePtr p)
 {
   POLYAREA *c;
   Vector v;
@@ -1674,7 +1671,7 @@ IsPointInPolygon (LocationType X, LocationType Y, BDimension r,
 
 
 bool
-IsPointInPolygonIgnoreHoles (LocationType X, LocationType Y, PolygonTypePtr p)
+IsPointInPolygonIgnoreHoles (Coord X, Coord Y, PolygonTypePtr p)
 {
   Vector v;
   v[0] = X;
@@ -1683,8 +1680,7 @@ IsPointInPolygonIgnoreHoles (LocationType X, LocationType Y, PolygonTypePtr p)
 }
 
 bool
-IsRectangleInPolygon (LocationType X1, LocationType Y1, LocationType X2,
-                      LocationType Y2, PolygonTypePtr p)
+IsRectangleInPolygon (Coord X1, Coord Y1, Coord X2, Coord Y2, PolygonTypePtr p)
 {
   POLYAREA *s;
   if (!
diff --git a/src/polygon.h b/src/polygon.h
index e3b31c0..bdbef46 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -55,7 +55,7 @@ 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);
+					Coord, Coord);
 bool RemoveExcessPolygonPoints (LayerTypePtr, PolygonTypePtr);
 void GoToPreviousPoint (void);
 void ClosePolygon (void);
@@ -68,22 +68,21 @@ int PlowsPolygon (DataType *, 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);
-POLYAREA * LinePoly(LineType *l, BDimension thick);
-POLYAREA * ArcPoly(ArcType *l, BDimension thick);
-POLYAREA * PinPoly(PinType *l, BDimension thick, BDimension clear);
-POLYAREA * BoxPolyBloated (BoxType *box, BDimension radius);
-void frac_circle (PLINE *, LocationType, LocationType, Vector, int);
+POLYAREA * RectPoly (Coord x1, Coord x2, Coord y1, Coord y2);
+POLYAREA * CirclePoly (Coord x, Coord y, Coord radius);
+POLYAREA * OctagonPoly(Coord x, Coord y, Coord radius);
+POLYAREA * LinePoly(LineType *l, Coord thick);
+POLYAREA * ArcPoly(ArcType *l, Coord thick);
+POLYAREA * PinPoly(PinType *l, Coord thick, Coord clear);
+POLYAREA * BoxPolyBloated (BoxType *box, Coord radius);
+void frac_circle (PLINE *, Coord, Coord, Vector, int);
 int InitClip(DataType *d, LayerType *l, PolygonType *p);
 void RestoreToPolygon(DataType *, int, void *, void *);
 void ClearFromPolygon(DataType *, int, void *, void *);
 
-bool IsPointInPolygon (LocationType, LocationType, BDimension, PolygonTypePtr);
-bool IsPointInPolygonIgnoreHoles (LocationType, LocationType, PolygonTypePtr);
-bool IsRectangleInPolygon (LocationType, LocationType, LocationType,
-			      LocationType, PolygonTypePtr);
+bool IsPointInPolygon (Coord, Coord, Coord, PolygonTypePtr);
+bool IsPointInPolygonIgnoreHoles (Coord, Coord, PolygonTypePtr);
+bool IsRectangleInPolygon (Coord, Coord, Coord, Coord, PolygonTypePtr);
 bool isects (POLYAREA *, PolygonTypePtr, bool);
 bool MorphPolygon (LayerTypePtr, PolygonTypePtr);
 void NoHolesPolygonDicer (PolygonType *p, const BoxType *clip,
diff --git a/src/polygon1.c b/src/polygon1.c
index ffb1542..9da353e 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -2490,7 +2490,7 @@ VNODE *
 poly_CreateNode (Vector v)
 {
   VNODE *res;
-  register int *c;
+  Coord *c;
 
   assert (v);
   res = (VNODE *) calloc (1, sizeof (VNODE));

commit 912ce4d8601d2cb81eabc41629cb1645ee8ded9a
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit rotate.[ch], implement Coord

diff --git a/src/rotate.c b/src/rotate.c
index 1667985..11b8fd9 100644
--- a/src/rotate.c
+++ b/src/rotate.c
@@ -73,9 +73,8 @@ static void *RotateLinePoint (LayerTypePtr, LineTypePtr, PointTypePtr);
 /* ----------------------------------------------------------------------
  * some local identifiers
  */
-static LocationType CenterX,	/* center of rotation */
-  CenterY;
-static BYTE Number;		/* number of rotations */
+static Coord CenterX, CenterY;	/* center of rotation */
+static unsigned Number;		/* number of rotations */
 static ObjectFunctionType RotateFunctions = {
   NULL,
   RotateText,
@@ -95,8 +94,7 @@ static ObjectFunctionType RotateFunctions = {
  * rotates a point in 90 degree steps
  */
 void
-RotatePointLowLevel (PointTypePtr Point, LocationType X, LocationType Y,
-		     BYTE Number)
+RotatePointLowLevel (PointTypePtr Point, Coord X, Coord Y, unsigned Number)
 {
   ROTATE (Point->X, Point->Y, X, Y, Number);
 }
@@ -105,8 +103,7 @@ RotatePointLowLevel (PointTypePtr Point, LocationType X, LocationType Y,
  * rotates a line in 90 degree steps
  */
 void
-RotateLineLowLevel (LineTypePtr Line, LocationType X, LocationType Y,
-		    BYTE Number)
+RotateLineLowLevel (LineTypePtr Line, Coord X, Coord Y, unsigned Number)
 {
   ROTATE (Line->Point1.X, Line->Point1.Y, X, Y, Number);
   ROTATE (Line->Point2.X, Line->Point2.Y, X, Y, Number);
@@ -115,7 +112,7 @@ RotateLineLowLevel (LineTypePtr Line, LocationType X, LocationType Y,
     {
       if (Line->Point1.Y > Line->Point2.Y)
 	{
-	  LocationType t;
+	  Coord t;
 	  t = Line->Point1.Y;
 	  Line->Point1.Y = Line->Point2.Y;
 	  Line->Point2.Y = t;
@@ -125,7 +122,7 @@ RotateLineLowLevel (LineTypePtr Line, LocationType X, LocationType Y,
     {
       if (Line->Point1.X > Line->Point2.X)
 	{
-	  LocationType t;
+	  Coord t;
 	  t = Line->Point1.X;
 	  Line->Point1.X = Line->Point2.X;
 	  Line->Point2.X = t;
@@ -141,8 +138,7 @@ RotateLineLowLevel (LineTypePtr Line, LocationType X, LocationType Y,
  * is done by the drawing routines
  */
 void
-RotateTextLowLevel (TextTypePtr Text, LocationType X, LocationType Y,
-		    BYTE Number)
+RotateTextLowLevel (TextTypePtr Text, Coord X, Coord Y, unsigned Number)
 {
   BYTE number;
 
@@ -161,8 +157,7 @@ RotateTextLowLevel (TextTypePtr Text, LocationType X, LocationType Y,
  * rotates a polygon in 90 degree steps
  */
 void
-RotatePolygonLowLevel (PolygonTypePtr Polygon,
-		       LocationType X, LocationType Y, BYTE Number)
+RotatePolygonLowLevel (PolygonTypePtr Polygon, Coord X, Coord Y, unsigned Number)
 {
   POLYGONPOINT_LOOP (Polygon);
   {
@@ -193,10 +188,9 @@ RotateText (LayerTypePtr Layer, TextTypePtr Text)
  * rotates an arc
  */
 void
-RotateArcLowLevel (ArcTypePtr Arc, LocationType X, LocationType Y,
-		   BYTE Number)
+RotateArcLowLevel (ArcTypePtr Arc, Coord X, Coord Y, unsigned Number)
 {
-  BDimension save;
+  Coord save;
 
   /* add Number*90 degrees (i.e., Number quarter-turns) */
   Arc->StartAngle = NormalizeAngle (Arc->StartAngle + Number * 90);
@@ -217,7 +211,7 @@ RotateArcLowLevel (ArcTypePtr Arc, LocationType X, LocationType Y,
  */
 void
 RotateElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
-		       LocationType X, LocationType Y, BYTE Number)
+		       Coord X, Coord Y, unsigned Number)
 {
   /* solder side objects need a different orientation */
 
@@ -347,10 +341,9 @@ RotateElementName (ElementTypePtr Element)
  * rotates a box in 90 degree steps 
  */
 void
-RotateBoxLowLevel (BoxTypePtr Box, LocationType X, LocationType Y,
-		   BYTE Number)
+RotateBoxLowLevel (BoxTypePtr Box, Coord X, Coord Y, unsigned Number)
 {
-  LocationType x1 = Box->X1, y1 = Box->Y1, x2 = Box->X2, y2 = Box->Y2;
+  Coord x1 = Box->X1, y1 = Box->Y1, x2 = Box->X2, y2 = Box->Y2;
 
   ROTATE (x1, y1, X, Y, Number);
   ROTATE (x2, y2, X, Y, Number);
@@ -366,7 +359,7 @@ RotateBoxLowLevel (BoxTypePtr Box, LocationType X, LocationType Y,
  */
 void *
 RotateObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-	      LocationType X, LocationType Y, BYTE Steps)
+	      Coord X, Coord Y, unsigned Steps)
 {
   RubberbandTypePtr ptr;
   void *ptr2;
@@ -422,7 +415,7 @@ RotateObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
 }
 
 void
-RotateScreenObject (LocationType X, LocationType Y, BYTE Steps)
+RotateScreenObject (Coord X, Coord Y, unsigned Steps)
 {
   int type;
   void *ptr1, *ptr2, *ptr3;
diff --git a/src/rotate.h b/src/rotate.h
index c9c78b8..7748b19 100644
--- a/src/rotate.h
+++ b/src/rotate.h
@@ -38,7 +38,7 @@
  */
 #define	ROTATE(x,y,x0,y0,n)							\
 	{												\
-		LocationType	dx = (x)-(x0),					\
+		Coord	dx = (x)-(x0),					\
 					dy = (y)-(y0);					\
 													\
 		switch(n & 0x03)									\
@@ -60,15 +60,14 @@
 #define	ROTATE_TYPES	(ELEMENT_TYPE | TEXT_TYPE | ELEMENTNAME_TYPE | ARC_TYPE)
 
 
-void RotateLineLowLevel (LineTypePtr, LocationType, LocationType, BYTE);
-void RotateArcLowLevel (ArcTypePtr, LocationType, LocationType, BYTE);
-void RotateBoxLowLevel (BoxTypePtr, LocationType, LocationType, BYTE);
-void RotateTextLowLevel (TextTypePtr, LocationType, LocationType, BYTE);
-void RotatePolygonLowLevel (PolygonTypePtr, LocationType, LocationType, BYTE);
-void RotateElementLowLevel (DataTypePtr, ElementTypePtr, LocationType,
-			    LocationType, BYTE);
-void *RotateObject (int, void *, void *, void *, LocationType, LocationType,
-		    BYTE);
-void RotateScreenObject (LocationType, LocationType, BYTE);
+void RotateLineLowLevel (LineTypePtr, Coord, Coord, unsigned);
+void RotateArcLowLevel (ArcTypePtr, Coord, Coord, unsigned);
+void RotateBoxLowLevel (BoxTypePtr, Coord, Coord, unsigned);
+void RotateTextLowLevel (TextTypePtr, Coord, Coord, unsigned);
+void RotatePolygonLowLevel (PolygonTypePtr, Coord, Coord, unsigned);
+void RotateElementLowLevel (DataTypePtr, ElementTypePtr, Coord, Coord, unsigned);
+void *RotateObject (int, void *, void *, void *, Coord, Coord,
+		    unsigned);
+void RotateScreenObject (Coord, Coord, unsigned);
 
 #endif

commit 8de8bc583834d843933b78db1b2c39540e5008f4
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit search.[ch], implement Coord unit
    
    This does not affect the "IsPointOnArc assumes circular
    arc" bug; it is just more obvious now with the cleaner
    code.
    
    Affects-bug: lp-815527

diff --git a/src/search.c b/src/search.c
index ef9b9a7..f12f473 100644
--- a/src/search.c
+++ b/src/search.c
@@ -60,9 +60,8 @@ RCSID ("$Id$");
 /* ---------------------------------------------------------------------------
  * some local identifiers
  */
-static float PosX,		/* search position for subroutines */
-  PosY;
-static BDimension SearchRadius;
+static double PosX, PosY;		/* search position for subroutines */
+static Coord SearchRadius;
 static BoxType SearchBox;
 static LayerTypePtr SearchLayer;
 
@@ -104,7 +103,7 @@ struct ans_info
 {
   void **ptr1, **ptr2, **ptr3;
   bool BackToo;
-  float area;
+  double area;
   jmp_buf env;
   int locked;			/* This will be zero or LOCKFLAG */
 };
@@ -232,7 +231,7 @@ struct line_info
 {
   LineTypePtr *Line;
   PointTypePtr *Point;
-  float least;
+  double least;
   jmp_buf env;
   int locked;
 };
@@ -285,8 +284,8 @@ rat_callback (const BoxType * box, void *cl)
     return 0;
 
   if (TEST_FLAG (VIAFLAG, line) ?
-      (SQUARE (line->Point1.X - PosX) + SQUARE (line->Point1.Y - PosY) <=
-	   SQUARE (line->Thickness * 2 + SearchRadius)) :
+      (Distance (line->Point1.X, line->Point1.Y, PosX, PosY) <=
+	   line->Thickness * 2 + SearchRadius) :
       IsPointOnLine (PosX, PosY, SearchRadius, line))
     {
       *i->ptr1 = *i->ptr2 = *i->ptr3 = line;
@@ -451,13 +450,13 @@ linepoint_callback (const BoxType * b, void *cl)
   LineTypePtr line = (LineTypePtr) b;
   struct line_info *i = (struct line_info *) cl;
   int ret_val = 0;
-  float d;
+  double d;
 
   if (TEST_FLAG (i->locked, line))
     return 0;
 
   /* some stupid code to check both points */
-  d = SQUARE (PosX - line->Point1.X) + SQUARE (PosY - line->Point1.Y);
+  d = Distance (PosX, PosY, line->Point1.X, line->Point1.Y);
   if (d < i->least)
     {
       i->least = d;
@@ -466,7 +465,7 @@ linepoint_callback (const BoxType * b, void *cl)
       ret_val = 1;
     }
 
-  d = SQUARE (PosX - line->Point2.X) + SQUARE (PosY - line->Point2.Y);
+  d = Distance (PosX, PosY, line->Point2.X, line->Point2.Y);
   if (d < i->least)
     {
       i->least = d;
@@ -489,9 +488,7 @@ SearchLinePointByLocation (int locked, LayerTypePtr * Layer,
   info.Line = Line;
   info.Point = Point;
   *Point = NULL;
-  info.least =
-    (MAX_LINE_POINT_DISTANCE + SearchRadius) * (MAX_LINE_POINT_DISTANCE +
-						SearchRadius);
+  info.least = MAX_LINE_POINT_DISTANCE + SearchRadius;
   info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG;
   if (r_search
       (SearchLayer->line_tree, &SearchBox, NULL, linepoint_callback, &info))
@@ -507,16 +504,16 @@ static bool
 SearchPointByLocation (int locked, LayerTypePtr * Layer,
 		       PolygonTypePtr * Polygon, PointTypePtr * Point)
 {
-  float d, least;
+  double d, least;
   bool found = false;
 
-  least = SQUARE (SearchRadius + MAX_POLYGON_POINT_DISTANCE);
+  least = SearchRadius + MAX_POLYGON_POINT_DISTANCE;
   *Layer = SearchLayer;
   POLYGON_LOOP (*Layer);
   {
     POLYGONPOINT_LOOP (polygon);
     {
-      d = SQUARE (point->X - PosX) + SQUARE (point->Y - PosY);
+      d = Distance (point->X, point->Y, PosX, PosY);
       if (d < least)
 	{
 	  least = d;
@@ -539,7 +536,7 @@ name_callback (const BoxType * box, void *cl)
   TextTypePtr text = (TextTypePtr) box;
   struct ans_info *i = (struct ans_info *) cl;
   ElementTypePtr element = (ElementTypePtr) text->Element;
-  float newarea;
+  double newarea;
 
   if (TEST_FLAG (i->locked, text))
     return 0;
@@ -549,7 +546,7 @@ name_callback (const BoxType * box, void *cl)
     {
       /* use the text with the smallest bounding box */
       newarea = (text->BoundingBox.X2 - text->BoundingBox.X1) *
-	(float) (text->BoundingBox.Y2 - text->BoundingBox.Y1);
+	(double) (text->BoundingBox.Y2 - text->BoundingBox.Y1);
       if (newarea < i->area)
 	{
 	  i->area = newarea;
@@ -593,7 +590,7 @@ element_callback (const BoxType * box, void *cl)
 {
   ElementTypePtr element = (ElementTypePtr) box;
   struct ans_info *i = (struct ans_info *) cl;
-  float newarea;
+  double newarea;
 
   if (TEST_FLAG (i->locked, element))
     return 0;
@@ -603,7 +600,7 @@ element_callback (const BoxType * box, void *cl)
     {
       /* use the element with the smallest bounding box */
       newarea = (element->VBox.X2 - element->VBox.X1) *
-	(float) (element->VBox.Y2 - element->VBox.Y1);
+	(double) (element->VBox.Y2 - element->VBox.Y1);
       if (newarea < i->area)
 	{
 	  i->area = newarea;
@@ -648,31 +645,30 @@ SearchElementByLocation (int locked,
  * checks if a point is on a pin
  */
 bool
-IsPointOnPin (float X, float Y, float Radius, PinTypePtr pin)
+IsPointOnPin (Coord X, Coord Y, Coord Radius, PinTypePtr pin)
 {
+  Coord t = PIN_SIZE (pin) / 2;
   if (TEST_FLAG (SQUAREFLAG, pin))
     {
       BoxType b;
-      BDimension t = PIN_SIZE (pin) / 2;
 
       b.X1 = pin->X - t;
       b.X2 = pin->X + t;
       b.Y1 = pin->Y - t;
       b.Y2 = pin->Y + t;
       if (IsPointInBox (X, Y, &b, Radius))
-	return (true);
+	return true;
     }
-  else if (SQUARE (pin->X - X) + SQUARE (pin->Y - Y) <=
-	   SQUARE (PIN_SIZE (pin) / 2 + Radius))
-    return (true);
-  return (false);
+  else if (Distance (pin->X, pin->Y, X, Y) <= Radius + t)
+    return true;
+  return false;
 }
 
 /* ---------------------------------------------------------------------------
  * checks if a rat-line end is on a PV
  */
 bool
-IsPointOnLineEnd (LocationType X, LocationType Y, RatTypePtr Line)
+IsPointOnLineEnd (Coord X, Coord Y, RatTypePtr Line)
 {
   if (((X == Line->Point1.X) && (Y == Line->Point1.Y)) ||
       ((X == Line->Point2.X) && (Y == Line->Point2.Y)))
@@ -682,77 +678,65 @@ IsPointOnLineEnd (LocationType X, LocationType Y, RatTypePtr Line)
 
 /* ---------------------------------------------------------------------------
  * checks if a line intersects with a PV
- * constant recognition by the optimizer is assumed
  *
  * let the point be (X,Y) and the line (X1,Y1)(X2,Y2)
  * the length of the line is
  *
- *   l = ((X2-X1)^2 + (Y2-Y1)^2)^0.5
+ *   L = ((X2-X1)^2 + (Y2-Y1)^2)^0.5
  * 
  * let Q be the point of perpendicular projection of (X,Y) onto the line
  *
- *   QX = X1 +r*(X2-X1)
- *   QY = Y1 +r*(Y2-Y1)
+ *   QX = X1 + D1*(X2-X1) / L
+ *   QY = Y1 + D1*(Y2-Y1) / L
  * 
  * with (from vector geometry)
  *
- *       (Y1-Y)(Y1-Y2)+(X1-X)(X1-X2)
- *   r = ---------------------------
- *                   l*l
+ *        (Y1-Y)(Y1-Y2)+(X1-X)(X1-X2)
+ *   D1 = ---------------------------
+ *                     L
  *
- *   r < 0     Q is on backward extension of the line
- *   r > 1     Q is on forward extension of the line
- *   else      Q is on the line
+ *   D1 < 0   Q is on backward extension of the line
+ *   D1 > L   Q is on forward extension of the line
+ *   else     Q is on the line
  *
  * the signed distance from (X,Y) to Q is
  *
- *       (Y2-Y1)(X-X1)-(X2-X1)(Y-Y1)
- *   d = ----------------------------
- *                    l
+ *        (Y2-Y1)(X-X1)-(X2-X1)(Y-Y1)
+ *   D2 = ----------------------------
+ *                     L
+ *
+ * Finally, D1 and D2 are orthogonal, so we can sum them easily
+ * by pythagorean theorem.
  */
 bool
-IsPointOnLine (float X, float Y, float Radius, LineTypePtr Line)
+IsPointOnLine (Coord X, Coord Y, Coord Radius, LineTypePtr Line)
 {
-  register float dx, dy, dx1, dy1, l, d, r;
-  Radius += ((float) Line->Thickness + 1.) / 2.0;
-  if (Y + Radius < MIN (Line->Point1.Y, Line->Point2.Y) ||
-      Y - Radius > MAX (Line->Point1.Y, Line->Point2.Y))
-    return false;
-  dx = (float) (Line->Point2.X - Line->Point1.X);
-  dy = (float) (Line->Point2.Y - Line->Point1.Y);
-  dx1 = (float) (Line->Point1.X - X);
-  dy1 = (float) (Line->Point1.Y - Y);
-  d = dx * dy1 - dy * dx1;
-
-  /* check distance from PV to line */
-  Radius *= Radius;
-  if ((l = dx * dx + dy * dy) == 0.0)
-    {
-      l = SQUARE (Line->Point1.X - X) + SQUARE (Line->Point1.Y - Y);
-      return ((l <= Radius) ? true : false);
-    }
-  if (d * d > Radius * l)
-    return (false);
-
-  /* they intersect if Q is on line */
-  r = -(dx * dx1 + dy * dy1);
-  if (r >= 0 && r <= l)
-    return (true);
-
-  /* we have to check P1 or P2 depending on the sign of r */
-  if (r < 0.0)
-    return ((dx1 * dx1 + dy1 * dy1) <= Radius);
-  dx1 = Line->Point2.X - X;
-  dy1 = Line->Point2.Y - Y;
-  return ((dx1 * dx1 + dy1 * dy1) <= Radius);
+  double D1, D2, L;
+
+  /* Get length of segment */
+  L = Distance (Line->Point1.X, Line->Point1.Y, Line->Point2.X, Line->Point2.Y);
+  if (L < 0.1)
+    return Distance (X, Y, Line->Point1.X, Line->Point1.Y) < Radius + Line->Thickness / 2;
+
+  /* Get distance from (X1, Y1) to Q (on the line) */
+  D1 = ((double) (Y - Line->Point1.Y) * (Line->Point2.Y - Line->Point1.Y)
+        + (double) (X - Line->Point1.X) * (Line->Point2.X - Line->Point1.X)) / L;
+  /* Translate this into distance to Q from segment */
+  if (D1 < 0)       D1 = -D1;
+  else if (D1 > L)  D1 -= L;
+  else              D1 = 0;
+  /* Get distance from (X, Y) to Q */
+  D2 = ((double) (X - Line->Point1.X) * (Line->Point2.Y - Line->Point1.Y)
+        + (double) (Y - Line->Point1.Y) * (Line->Point2.X - Line->Point1.X)) / L;
+  /* Total distance is then the pythagorean sum of these */
+  return sqrt (D1*D1 + D2*D2) <= Radius + Line->Thickness / 2;
 }
 
 /* ---------------------------------------------------------------------------
  * checks if a line crosses a rectangle
  */
 bool
-IsLineInRectangle (LocationType X1, LocationType Y1,
-		   LocationType X2, LocationType Y2, LineTypePtr Line)
+IsLineInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, LineTypePtr Line)
 {
   LineType line;
 
@@ -795,31 +779,30 @@ IsLineInRectangle (LocationType X1, LocationType Y1,
 
   return (false);
 }
-static int 
-sign(float x){return x<0?-1:x>0?1:0;}
+
 static int /*checks if a point (of null radius) is in a slanted rectangle*/
-IsPointInQuadrangle(PointType p[4],PointTypePtr l)
+IsPointInQuadrangle(PointType p[4], PointTypePtr l)
 {
-  int dx,dy,x,y;
-  float prod0,prod1;
+  Coord dx, dy, x, y;
+  double prod0, prod1;
 
   dx = p[1].X - p[0].X;
   dy = p[1].Y - p[0].Y;
-  x=l->X - p[0].X;
-  y=l->Y - p[0].Y;
-  prod0 = (float)x * dx + (float)y * dy;
+  x = l->X - p[0].X;
+  y = l->Y - p[0].Y;
+  prod0 = (double) x * dx + (double) y * dy;
   x = l->X - p[1].X;
   y = l->Y - p[1].Y;
-  prod1 = (float)x * dx + (float)y * dy;
-  if (sign (prod0) * sign (prod1) <= 0)
+  prod1 = (double) x * dx + (double) y * dy;
+  if (prod0 * prod1 <= 0)
     {
       dx = p[1].X - p[2].X;
       dy = p[1].Y - p[2].Y;
-      prod0 = (float)x * dx + (float)y * dy;
+      prod0 = (double) x * dx + (double) y * dy;
       x = l->X - p[2].X;
       y = l->Y - p[2].Y;
-      prod1 = (float)x * dx + (float)y * dy;
-      if (sign (prod0) * sign (prod1) <= 0)
+      prod1 = (double) x * dx + (double) y * dy;
+      if (prod0 * prod1 <= 0)
 	return true;
     }
   return false;
@@ -870,8 +853,7 @@ IsLineInQuadrangle (PointType p[4], LineTypePtr Line)
  * checks if an arc crosses a square
  */
 bool
-IsArcInRectangle (LocationType X1, LocationType Y1,
-		  LocationType X2, LocationType Y2, ArcTypePtr Arc)
+IsArcInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, ArcTypePtr Arc)
 {
   LineType line;
 
@@ -915,12 +897,11 @@ IsArcInRectangle (LocationType X1, LocationType Y1,
  * Written to enable arbitrary pad directions; for rounded pads, too.
  */
 bool
-IsPointInPad (LocationType X, LocationType Y, BDimension Radius,
-	      PadTypePtr Pad)
+IsPointInPad (Coord X, Coord Y, Coord Radius, PadTypePtr Pad)
 {
   double r, Sin, Cos;
-  LocationType x; 
-  BDimension t2 = (Pad->Thickness + 1) / 2, range;
+  Coord x; 
+  Coord t2 = (Pad->Thickness + 1) / 2, range;
   PadType pad = *Pad;
 
   /* series of transforms saving range */
@@ -933,8 +914,7 @@ IsPointInPad (LocationType X, LocationType Y, BDimension Radius,
   /* so, pad.Point1.X = pad.Point1.Y = 0; */
 
   /* rotate round (0, 0) so that Point2 coordinates be (r, 0) */
-  r= sqrt ((double)pad.Point2.X * pad.Point2.X +
-	   (double)pad.Point2.Y * pad.Point2.Y);
+  r = Distance (0, 0, pad.Point2.X, pad.Point2.Y);
   if (r < .1)
     {
       Cos = 1;
@@ -963,15 +943,17 @@ IsPointInPad (LocationType X, LocationType Y, BDimension Radius,
     {
       if (X <= 0)
 	{
-	  if ( Y <= t2 ) range = -X; else
-	    return (Radius >= 0) && (Radius * (double)Radius > 
-		    (double)(t2 - Y) * (t2 - Y) + (double)X * X);
+	  if (Y <= t2)
+            range = -X;
+          else
+	    return Radius > Distance (0, t2, X, Y);
 	}
       else if (X >= r)
 	{
-	  if ( Y <= t2 ) range = X - r; else 
-	    return (Radius >= 0) && (Radius * (double)Radius > 
-		    (double)(t2 - Y) * (t2 - Y) + (double)(X - r) * (X - r));
+	  if (Y <= t2)
+            range = X - r;
+          else 
+	    return Radius > Distance (r, t2, X, Y);
 	}
       else
 	range = Y - t2;
@@ -979,11 +961,9 @@ IsPointInPad (LocationType X, LocationType Y, BDimension Radius,
   else/*Rounded pad: even more simple*/
     {
       if (X <= 0)
-	return (Radius + t2 >= 0) && ((Radius + t2) * (double)(Radius + t2) > 
-		(double)X * X + (double)Y * Y);
+	return (Radius + t2) > Distance (0, 0, X, Y);
       else if (X >= r) 
-	return (Radius + t2 >= 0) && ((Radius + t2) * (double)(Radius + t2) > 
-		(double)(X - r) * (X - r) + (double)Y * Y);
+	return (Radius + t2) > Distance (r, 0, X, Y);
       else
 	range = Y - t2;
     }
@@ -991,9 +971,9 @@ IsPointInPad (LocationType X, LocationType Y, BDimension Radius,
 }
 
 bool
-IsPointInBox (LocationType X, LocationType Y, BoxTypePtr box, BDimension Radius)
+IsPointInBox (Coord X, Coord Y, BoxTypePtr box, Coord Radius)
 {
-  BDimension width, height, range;
+  Coord width, height, range;
 
   /* NB: Assumes box has point1 with numerically lower X and Y coordinates */
 
@@ -1007,22 +987,18 @@ IsPointInBox (LocationType X, LocationType Y, BoxTypePtr box, BDimension Radius)
   if (X <= 0)
     {
       if (Y < 0)
-        return (Radius >= 0) && (Radius * (double)Radius >
-                (double)Y * Y + (double)X * X);
+        return Radius > Distance (0, 0, X, Y);
       else if (Y > height)
-        return (Radius >= 0) && (Radius * (double)Radius >
-                (double)(Y - height) * (Y - height) + (double)X * X);
+        return Radius > Distance (0, height, X, Y);
       else
         range = -X;
     }
   else if (X >= width)
     {
       if (Y < 0)
-        return (Radius >= 0) && (Radius * (double)Radius >
-                (double)Y * Y + (double)(X - width) * (X - width));
+        return Radius > Distance (width, 0, X, Y);
       else if (Y > height)
-        return (Radius >= 0) && (Radius * (double)Radius >
-                (double)(Y - height) * (Y - height) + (double)(X - width) * (X - width));
+        return Radius > Distance (width, height, X, Y);
       else
         range = X - width;
     }
@@ -1039,91 +1015,62 @@ IsPointInBox (LocationType X, LocationType Y, BoxTypePtr box, BDimension Radius)
   return range < Radius;
 }
 
+/* TODO: this code is BROKEN in the case of non-circular arcs,
+ *       and in the case that the arc thickness is greater than
+ *       the radius.
+ */
 bool
-IsPointOnArc (float X, float Y, float Radius, ArcTypePtr Arc)
+IsPointOnArc (Coord X, Coord Y, Coord Radius, ArcTypePtr Arc)
 {
-  double x, y, dx, dy, r1, r2, a, d, l;
-  double pdx, pdy;
-  double ang1, ang2, ang0, delta;
-  int startAngle, arcDelta;
-
-  pdx = X - Arc->X;
-  pdy = Y - Arc->Y;
-  l = pdx * pdx + pdy * pdy;
-  Radius += 0.5 * Arc->Thickness;
-  if (Radius < 0) /* thin arc: trivial condition */
-    return (false);
-  /* concentric arcs, simpler intersection conditions */
-  if (l < 0.5)
+  /* Calculate angle of point from arc center */
+  double p_dist = Distance (X, Y, Arc->X, Arc->Y);
+  double p_cos = (X - Arc->X) / p_dist;
+  Angle p_ang = acos (p_cos) * RAD_TO_DEG;
+  Angle ang1, ang2;
+
+  /* Convert StartAngle, Delta into bounding angles in [0, 720) */
+  if (Arc->Delta > 0)
     {
-      if (Arc->Width <= Radius)
-	return (true);
-      else
-	return (false);
+      ang1 = NormalizeAngle (Arc->StartAngle);
+      ang2 = NormalizeAngle (Arc->StartAngle + Arc->Delta);
     }
-  r1 = Arc->Width;
-  r2 = Radius;
-  if (sqrt (l) < r2 - r1) /* the arc merged in the circle */
-    return (true);
-  r1 *= r1;
-  r2 *= r2;
-  a = 0.5 * (r1 - r2 + l) / l;
-  r1 = r1 / l;
-  d = r1 - a * a;
-  /* the circles are too far apart to touch or probably just touch */
-  if (d < 0)
-    return (false);
-  /* project the points of intersection */
-  d = sqrt (d);
-  x = a * pdx;
-  y = a * pdy;
-  dy = -d * pdx;
-  dx = d * pdy;
-  /* arrgh! calculate the angles, and put them in a standard range */
-  startAngle = Arc->StartAngle;
-  arcDelta = Arc->Delta;
-  if (arcDelta < 0)
+  else
     {
-      startAngle += arcDelta;
-      arcDelta = -arcDelta;
+      ang1 = NormalizeAngle (Arc->StartAngle + Arc->Delta);
+      ang2 = NormalizeAngle (Arc->StartAngle);
     }
-  if (arcDelta > 360)
-    arcDelta = 360;
-  while (startAngle < 0)
-    startAngle += 360;
-  while (startAngle > 360)
-    startAngle -= 360;
-  ang1 = RAD_TO_DEG * atan2 ((y + dy), -(x + dx));
-  if (ang1 < 0)
-    ang1 += 360;
-  ang2 = RAD_TO_DEG * atan2 ((y - dy), -(x - dx));
-  if (ang2 < 0)
-    ang2 += 360;
   if (ang1 > ang2)
+    ang2 += 360;
+  /* Make sure full circles aren't treated as zero-length arcs */
+  if (Arc->Delta == 360 || Arc->Delta == -360)
+    ang2 = ang1 + 360;
+
+  if (Y > Arc->Y)
+    p_ang = -p_ang;
+  p_ang += 180;
+
+  /* Check point is outside arc range, check distance from endpoints */
+  if (ang1 >= p_ang || ang2 <= p_ang)
     {
-      ang0 = ang1;
-      ang1 = ang2;
-      ang2 = ang0;
-    }
-  delta = ang2 - ang1;
-  /* ang0 does not belong to intersection range */
-  ang0 = RAD_TO_DEG * atan2 (-pdy, pdx);
-  if (ang0 < 0)
-    ang0 += 360;
-  if (ang0 > ang1 && ang0 < ang2) /* we need the other part of circle */
-    {
-      ang1 = ang2;
-      delta = 360 - delta;
+      Coord ArcX, ArcY;
+
+      ArcX = Arc->X + Arc->Width *
+              cos ((Arc->StartAngle + 180) / RAD_TO_DEG);
+      ArcY = Arc->Y - Arc->Width *
+              sin ((Arc->StartAngle + 180) / RAD_TO_DEG);
+      if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2)
+        return true;
+
+      ArcX = Arc->X + Arc->Width *
+              cos ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG);
+      ArcY = Arc->Y - Arc->Width *
+              sin ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG);
+      if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2)
+        return true;
+      return false;
     }
-  if (ang1 >= startAngle && ang1 <= startAngle + arcDelta)
-    return (true);
-  if (startAngle >= ang1 && startAngle <= ang1 + delta)
-    return (true);
-  if (startAngle + arcDelta >= 360 && ang1 <= startAngle + arcDelta - 360)
-    return (true);
-  if (ang1 + delta >= 360 && startAngle <= ang1 + delta - 360)
-    return (true);
-  return (false);
+  /* If point is inside the arc range, just compare it to the arc */
+  return fabs (Distance (X, Y, Arc->X, Arc->Y) - Arc->Width) < Radius + Arc->Thickness / 2;
 }
 
 /* ---------------------------------------------------------------------------
@@ -1141,14 +1088,14 @@ IsPointOnArc (float X, float Y, float Radius, ArcTypePtr Arc)
  * locked items.  Otherwise, locked items are ignored.
  */
 int
-SearchObjectByLocation (int Type,
+SearchObjectByLocation (unsigned Type,
 			void **Result1, void **Result2, void **Result3,
-			LocationType X, LocationType Y, BDimension Radius)
+			Coord X, Coord Y, Coord Radius)
 {
   void *r1, *r2, *r3;
   void **pr1 = &r1, **pr2 = &r2, **pr3 = &r3;
   int i;
-  float HigherBound = 0;
+  double HigherBound = 0;
   int HigherAvail = NO_TYPE;
   int locked = Type & LOCKED_TYPE;
   /* setup variables used by local functions */
@@ -1216,7 +1163,7 @@ SearchObjectByLocation (int Type,
 				   false))
     {
       BoxTypePtr box = &((TextTypePtr) r2)->BoundingBox;
-      HigherBound = (float) (box->X2 - box->X1) * (float) (box->Y2 - box->Y1);
+      HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1);
       HigherAvail = ELEMENTNAME_TYPE;
     }
 
@@ -1227,7 +1174,7 @@ SearchObjectByLocation (int Type,
 			       (ElementTypePtr *) pr3, false))
     {
       BoxTypePtr box = &((ElementTypePtr) r1)->BoundingBox;
-      HigherBound = (float) (box->X2 - box->X1) * (float) (box->Y2 - box->Y1);
+      HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1);
       HigherAvail = ELEMENT_TYPE;
     }
 
@@ -1292,8 +1239,8 @@ SearchObjectByLocation (int Type,
 		{
 		  BoxTypePtr box =
 		    &(*(PolygonTypePtr *) Result2)->BoundingBox;
-		  float area =
-		    (float) (box->X2 - box->X1) * (float) (box->X2 - box->X1);
+		  double area =
+		    (double) (box->X2 - box->X1) * (double) (box->X2 - box->X1);
 		  if (HigherBound < area)
 		    break;
 		  else
@@ -1597,7 +1544,7 @@ SearchElementByName (DataTypePtr Base, char *Name)
  * searches the cursor position for the type 
  */
 int
-SearchScreen (LocationType X, LocationType Y, int Type, void **Result1,
+SearchScreen (Coord X, Coord Y, int Type, void **Result1,
 	      void **Result2, void **Result3)
 {
   int ans;
@@ -1611,7 +1558,7 @@ SearchScreen (LocationType X, LocationType Y, int Type, void **Result1,
  * searches the cursor position for the type
  */
 int
-SearchScreenGridSlop (LocationType X, LocationType Y, int Type, void **Result1,
+SearchScreenGridSlop (Coord X, Coord Y, int Type, void **Result1,
 	      void **Result2, void **Result3)
 {
   int ans;
diff --git a/src/search.h b/src/search.h
index b6ddaa2..b1a6196 100644
--- a/src/search.h
+++ b/src/search.h
@@ -71,21 +71,18 @@
 /* ---------------------------------------------------------------------------
  * prototypes
  */
-bool IsPointOnLine (float, float, float, LineTypePtr);
-bool IsPointOnPin (float, float, float, PinTypePtr);
-bool IsPointOnArc (float, float, float, ArcTypePtr);
-bool IsPointOnLineEnd (LocationType, LocationType, RatTypePtr);
-bool IsLineInRectangle (LocationType, LocationType, LocationType,
-			   LocationType, LineTypePtr);
+bool IsPointOnLine (Coord, Coord, Coord, LineTypePtr);
+bool IsPointOnPin (Coord, Coord, Coord, PinTypePtr);
+bool IsPointOnArc (Coord, Coord, Coord, ArcTypePtr);
+bool IsPointOnLineEnd (Coord, Coord, RatTypePtr);
+bool IsLineInRectangle (Coord, Coord, Coord, Coord, LineTypePtr);
 bool IsLineInQuadrangle (PointType p[4], LineTypePtr Line);
-bool IsArcInRectangle (LocationType, LocationType, LocationType,
-			  LocationType, ArcTypePtr);
-bool IsPointInPad (LocationType, LocationType, BDimension, PadTypePtr);
-bool IsPointInBox (LocationType, LocationType, BoxTypePtr, BDimension);
-int SearchObjectByLocation (int, void **, void **, void **, LocationType,
-			    LocationType, BDimension);
-int SearchScreen (LocationType, LocationType, int, void **, void **, void **);
-int SearchScreenGridSlop (LocationType, LocationType, int, void **, void **, void **);
+bool IsArcInRectangle (Coord, Coord, Coord, Coord, ArcTypePtr);
+bool IsPointInPad (Coord, Coord, Coord, PadTypePtr);
+bool IsPointInBox (Coord, Coord, BoxTypePtr, Coord);
+int SearchObjectByLocation (unsigned, void **, void **, void **, Coord, Coord, Coord);
+int SearchScreen (Coord, Coord, int, void **, void **, void **);
+int SearchScreenGridSlop (Coord, Coord, int, void **, void **, void **);
 int SearchObjectByID (DataTypePtr, void **, void **, void **, int, int);
 ElementTypePtr SearchElementByName (DataTypePtr, char *);
 

commit 08587e0e972d52df43944204b13fa242c8686da8
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Audit undo.[ch], thermal.c, set.[ch], rubberband.c, introduce Coord

diff --git a/src/rubberband.c b/src/rubberband.c
index 31ed1b7..4fe166c 100644
--- a/src/rubberband.c
+++ b/src/rubberband.c
@@ -78,8 +78,8 @@ static int rubber_callback (const BoxType * b, void *cl);
 
 struct rubber_info
 {
-  int radius;
-  LocationType X, Y;
+  Coord radius;
+  Coord X, Y;
   LineTypePtr line;
   BoxType box;
   LayerTypePtr layer;
@@ -90,8 +90,8 @@ rubber_callback (const BoxType * b, void *cl)
 {
   LineTypePtr line = (LineTypePtr) b;
   struct rubber_info *i = (struct rubber_info *) cl;
-  float x, y, rad, dist1, dist2;
-  BDimension t;
+  double x, y, rad, dist1, dist2;
+  Coord t;
   int touches = 0;
 
   t = line->Thickness / 2;
@@ -226,7 +226,7 @@ rubber_callback (const BoxType * b, void *cl)
 static void
 CheckPadForRubberbandConnection (PadTypePtr Pad)
 {
-  BDimension half = Pad->Thickness / 2;
+  Coord half = Pad->Thickness / 2;
   Cardinal i, group;
   struct rubber_info info;
 
@@ -369,7 +369,7 @@ CheckPinForRubberbandConnection (PinTypePtr Pin)
 {
   struct rubber_info info;
   Cardinal n;
-  BDimension t = Pin->Thickness / 2;
+  Coord t = Pin->Thickness / 2;
 
   info.box.X1 = Pin->X - t;
   info.box.X2 = Pin->X + t;
@@ -406,7 +406,7 @@ CheckLinePointForRubberbandConnection (LayerTypePtr Layer,
 {
   Cardinal group;
   struct rubber_info info;
-  BDimension t = Line->Thickness / 2;
+  Coord t = Line->Thickness / 2;
 
   /* lookup layergroup and check all visible lines in this group */
   info.radius = Exact ? -1 : MAX(Line->Thickness / 2, 1);
@@ -447,7 +447,7 @@ CheckPolygonForRubberbandConnection (LayerTypePtr Layer,
   {
     if (layer->On)
       {
-	BDimension thick;
+	Coord thick;
 
 	/* the following code just stupidly compares the endpoints
 	 * of the lines
diff --git a/src/set.c b/src/set.c
index 074a6ac..1f86adb 100644
--- a/src/set.c
+++ b/src/set.c
@@ -88,7 +88,7 @@ SetGrid (Coord Grid, bool align)
  * sets a new line thickness
  */
 void
-SetLineSize (BDimension Size)
+SetLineSize (Coord Size)
 {
   if (Size >= MIN_LINESIZE && Size <= MAX_LINESIZE)
     {
@@ -102,7 +102,7 @@ SetLineSize (BDimension Size)
  * sets a new via thickness
  */
 void
-SetViaSize (BDimension Size, bool Force)
+SetViaSize (Coord Size, bool Force)
 {
   if (Force || (Size <= MAX_PINORVIASIZE &&
 		Size >= MIN_PINORVIASIZE &&
@@ -116,7 +116,7 @@ SetViaSize (BDimension Size, bool Force)
  * sets a new via drilling hole
  */
 void
-SetViaDrillingHole (BDimension Size, bool Force)
+SetViaDrillingHole (Coord Size, bool Force)
 {
   if (Force || (Size <= MAX_PINORVIASIZE &&
 		Size >= MIN_PINORVIAHOLE &&
@@ -139,7 +139,7 @@ pcb_use_route_style (RouteStyleType * rst)
  * sets a keepaway width
  */
 void
-SetKeepawayWidth (BDimension Width)
+SetKeepawayWidth (Coord Width)
 {
   if (Width <= MAX_LINESIZE)
     {
@@ -151,7 +151,7 @@ SetKeepawayWidth (BDimension Width)
  * sets a text scaling
  */
 void
-SetTextScale (Dimension Scale)
+SetTextScale (int Scale)
 {
   if (Scale <= MAX_TEXTSCALE && Scale >= MIN_TEXTSCALE)
     {
@@ -333,7 +333,7 @@ SetRouteStyle (char *name)
 }
 
 void
-SetLocalRef (LocationType X, LocationType Y, bool Showing)
+SetLocalRef (Coord X, Coord Y, bool Showing)
 {
   static MarkType old;
   static int count = 0;
diff --git a/src/set.h b/src/set.h
index af6115a..4bfe6ec 100644
--- a/src/set.h
+++ b/src/set.h
@@ -33,20 +33,20 @@
 
 #include "global.h"
 
-void SetTextScale (Dimension);
+void SetTextScale (int);
 void SetGrid (Coord, bool);
-void SetZoom (float);
-void SetLineSize (BDimension);
-void SetViaSize (BDimension, bool);
-void SetViaDrillingHole (BDimension, bool);
-void SetKeepawayWidth (BDimension);
+void SetZoom (double);
+void SetLineSize (Coord);
+void SetViaSize (Coord, bool);
+void SetViaDrillingHole (Coord, bool);
+void SetKeepawayWidth (Coord);
 void SetChangedFlag (bool);
 void SetBufferNumber (int);
 void SetMode (int);
 void SetCrosshairRangeToBuffer (void);
 void SetRouteStyle (char *);
-void SetLocalRef (LocationType, LocationType, bool);
-void RedrawZoom (Position, Position);
+void SetLocalRef (Coord, Coord, bool);
+void RedrawZoom (Coord, Coord);
 void SaveMode (void);
 void RestoreMode (void);
 void pcb_use_route_style (RouteStyleType *);
diff --git a/src/thermal.c b/src/thermal.c
index d1df1fc..03fee24 100644
--- a/src/thermal.c
+++ b/src/thermal.c
@@ -81,19 +81,18 @@ static PCBTypePtr pcb;
 
 struct cent
 {
-  LocationType x, y;
-  BDimension s, c;
+  Coord x, y;
+  Coord s, c;
   char style;
   POLYAREA *p;
 };
 
 static POLYAREA *
-diag_line (LocationType X, LocationType Y, BDimension l, BDimension w,
-           bool rt)
+diag_line (Coord X, Coord Y, Coord l, Coord w, bool rt)
 {
   PLINE *c;
   Vector v;
-  BDimension x1, x2, y1, y2;
+  Coord x1, x2, y1, y2;
 
   if (rt)
     {
@@ -132,7 +131,7 @@ square_therm (PinTypePtr pin, Cardinal style)
   POLYAREA *p, *p2;
   PLINE *c;
   Vector v;
-  BDimension d, in, out;
+  Coord d, in, out;
 
   switch (style)
     {
@@ -364,8 +363,8 @@ static POLYAREA *
 oct_therm (PinTypePtr pin, Cardinal style)
 {
   POLYAREA *p, *p2, *m;
-  BDimension t = 0.5 * pcb->ThermScale * pin->Clearance;
-  BDimension w = pin->Thickness + pin->Clearance;
+  Coord t = 0.5 * pcb->ThermScale * pin->Clearance;
+  Coord w = pin->Thickness + pin->Clearance;
 
   p = OctagonPoly (pin->X, pin->Y, w);
   p2 = OctagonPoly (pin->X, pin->Y, pin->Thickness);
@@ -389,7 +388,7 @@ oct_therm (PinTypePtr pin, Cardinal style)
       /* fix me add thermal style 4 */
     case 5:
       {
-        BDimension t = pin->Thickness / 2;
+        Coord t = pin->Thickness / 2;
         POLYAREA *q;
         /* cheat by using the square therm's rounded parts */
         p = square_therm (pin, style);
@@ -427,8 +426,8 @@ ThermPoly (PCBTypePtr p, PinTypePtr pin, Cardinal laynum)
     case 2:
       {
         POLYAREA *m;
-        BDimension t = (pin->Thickness + pin->Clearance) / 2;
-        BDimension w = 0.5 * pcb->ThermScale * pin->Clearance;
+        Coord t = (pin->Thickness + pin->Clearance) / 2;
+        Coord w = 0.5 * pcb->ThermScale * pin->Clearance;
         pa = CirclePoly (pin->X, pin->Y, t);
         arc = CirclePoly (pin->X, pin->Y, pin->Thickness / 2);
         /* create a thin ring */
diff --git a/src/undo.c b/src/undo.c
index 971c771..576b9cb 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -87,14 +87,13 @@ ChangeNameType, *ChangeNameTypePtr;
 
 typedef struct			/* information about a move command */
 {
-  LocationType DX,		/* movement vector */
-    DY;
+  Coord DX, DY;		/* movement vector */
 }
 MoveType, *MoveTypePtr;
 
 typedef struct			/* information about removed polygon points */
 {
-  LocationType X, Y;		/* data */
+  Coord X, Y;			/* data */
   int ID;
   Cardinal Index;		/* index in a polygons array of points */
   bool last_in_contour;		/* Whether the point was the last in its contour */
@@ -103,9 +102,8 @@ RemovedPointType, *RemovedPointTypePtr;
 
 typedef struct			/* information about rotation */
 {
-  LocationType CenterX,		/* center of rotation */
-    CenterY;
-  BYTE Steps;			/* number of steps */
+  Coord CenterX, CenterY;	/* center of rotation */
+  Cardinal Steps;		/* number of steps */
 }
 RotateType, *RotateTypePtr;
 
@@ -150,7 +148,7 @@ typedef struct			/* holds information about an operation */
     RotateType Rotate;
     MoveToLayerType MoveToLayer;
     FlagType Flags;
-    BDimension Size;
+    Coord Size;
     LayerChangeType LayerChange;
     ClearPolyType ClearPoly;
     NetlistChangeType NetlistChange;
@@ -365,7 +363,7 @@ UndoChange2ndSize (UndoListTypePtr Entry)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
-  BDimension swap;
+  Coord swap;
 
   /* lookup entry by ID */
   type =
@@ -429,7 +427,7 @@ UndoChangeClearSize (UndoListTypePtr Entry)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
-  BDimension swap;
+  Coord swap;
 
   /* lookup entry by ID */
   type =
@@ -460,7 +458,7 @@ UndoChangeMaskSize (UndoListTypePtr Entry)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
-  BDimension swap;
+  Coord swap;
 
   /* lookup entry by ID */
   type =
@@ -495,7 +493,7 @@ UndoChangeSize (UndoListTypePtr Entry)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
-  BDimension swap;
+  Coord swap;
 
   /* lookup entry by ID */
   type =
@@ -1251,7 +1249,7 @@ AddObjectToClearPolyUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 void
 AddObjectToMirrorUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-			   LocationType yoff)
+			   Coord yoff)
 {
   UndoListTypePtr undo;
 
@@ -1267,7 +1265,7 @@ AddObjectToMirrorUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
  */
 void
 AddObjectToRotateUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-			   LocationType CenterX, LocationType CenterY,
+			   Coord CenterX, Coord CenterY,
 			   BYTE Steps)
 {
   UndoListTypePtr undo;
@@ -1397,7 +1395,7 @@ AddObjectToInsertContourUndoList (int Type,
  */
 void
 AddObjectToMoveUndoList (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
-			 LocationType DX, LocationType DY)
+			 Coord DX, Coord DY)
 {
   UndoListTypePtr undo;
 
diff --git a/src/undo.h b/src/undo.h
index 9b088ff..a6cd324 100644
--- a/src/undo.h
+++ b/src/undo.h
@@ -50,12 +50,12 @@ void AddObjectToInsertPointUndoList (int, void *, void *, void *);
 void AddObjectToRemoveContourUndoList (int, LayerType *, PolygonType *);
 void AddObjectToInsertContourUndoList (int, LayerType *, PolygonType *);
 void AddObjectToMoveUndoList (int, void *, void *, void *,
-			      LocationType, LocationType);
+			      Coord, Coord);
 void AddObjectToChangeNameUndoList (int, void *, void *, void *, char *);
 void AddObjectToRotateUndoList (int, void *, void *, void *,
-				LocationType, LocationType, BYTE);
+				Coord, Coord, BYTE);
 void AddObjectToCreateUndoList (int, void *, void *, void *);
-void AddObjectToMirrorUndoList (int, void *, void *, void *, LocationType);
+void AddObjectToMirrorUndoList (int, void *, void *, void *, Coord);
 void AddObjectToMoveToLayerUndoList (int, void *, void *, void *);
 void AddObjectToFlagUndoList (int, void *, void *, void *);
 void AddObjectToSizeUndoList (int, void *, void *, void *);

commit 5c08fc27cfc2f3b2f0f99ce45726eb7c5536d5a2
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Change get_coord and action signatures to use Coord

diff --git a/src/action.c b/src/action.c
index f1083f7..f33ca43 100644
--- a/src/action.c
+++ b/src/action.c
@@ -1818,7 +1818,7 @@ Does a Restore if there was nothing to undo, else does a Close.
 %end-doc */
 
 static int
-ActionAtomic (int argc, char **argv, int x, int y)
+ActionAtomic (int argc, char **argv, Coord x, Coord y)
 {
   if (argc != 1)
     AFAIL (atomic);
@@ -1858,7 +1858,7 @@ not the current style settings.
 %end-doc */
 
 static int
-ActionDRCheck (int argc, char **argv, int x, int y)
+ActionDRCheck (int argc, char **argv, Coord x, Coord y)
 {
   int count;
 
@@ -1900,7 +1900,7 @@ static const char dumplibrary_help[] =
 %end-doc */
 
 static int
-ActionDumpLibrary (int argc, char **argv, int x, int y)
+ActionDumpLibrary (int argc, char **argv, Coord x, Coord y)
 {
   int i, j;
 
@@ -1959,7 +1959,7 @@ other, not their absolute positions on the board.
 %end-doc */
 
 static int
-ActionFlip (int argc, char **argv, int x, int y)
+ActionFlip (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   ElementTypePtr element;
@@ -2011,7 +2011,7 @@ followed by a newline.
 %end-doc */
 
 static int
-ActionMessage (int argc, char **argv, int x, int y)
+ActionMessage (int argc, char **argv, Coord x, Coord y)
 {
   int i;
 
@@ -2061,7 +2061,7 @@ to connect with. However, they will have no effect without the polygon.
 %end-doc */
 
 static int
-ActionSetThermal (int argc, char **argv, int x, int y)
+ActionSetThermal (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *style = ARG (1);
@@ -2171,7 +2171,7 @@ Changes the size of new text.
 %end-doc */
 
 static int
-ActionSetValue (int argc, char **argv, int x, int y)
+ActionSetValue (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *val = ARG (1);
@@ -2251,7 +2251,7 @@ save) before quitting.
 %end-doc */
 
 static int
-ActionQuit (int argc, char **argv, int x, int y)
+ActionQuit (int argc, char **argv, Coord x, Coord y)
 {
   char *force = ARG (0);
   if (force && strcasecmp (force, "force") == 0)
@@ -2296,7 +2296,7 @@ All ``found'' objects are marked ``not found''.
 %end-doc */
 
 static int
-ActionConnection (int argc, char **argv, int x, int y)
+ActionConnection (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -2360,7 +2360,7 @@ from.
 #define GAP MIL_TO_COORD(100)
 
 static int
-ActionDisperseElements (int argc, char **argv, int x, int y)
+ActionDisperseElements (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   Coord minx = GAP,
@@ -2624,7 +2624,7 @@ CrosshairShapeIncrement (enum crosshair_shape shape)
 }
 
 static int
-ActionDisplay (int argc, char **argv, int childX, int childY)
+ActionDisplay (int argc, char **argv, Coord childX, Coord childY)
 {
   char *function, *str_dir;
   int id;
@@ -2828,7 +2828,7 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	  {
 	    ElementTypePtr element;
 	    void *ptrtmp;
-	    int x, y;
+	    Coord x, y;
 
 	    gui->get_coords (_("Click on an element"), &x, &y);
 	    if ((SearchScreen
@@ -3007,7 +3007,7 @@ Restores the tool to the last saved tool.
 %end-doc */
 
 static int
-ActionMode (int argc, char **argv, int x, int y)
+ActionMode (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
 
@@ -3229,7 +3229,7 @@ static const char removeselected_help[] = "Removes any selected objects.";
 %end-doc */
 
 static int
-ActionRemoveSelected (int argc, char **argv, int x, int y)
+ActionRemoveSelected (int argc, char **argv, Coord x, Coord y)
 {
   if (RemoveSelected ())
     SetChangedFlag (true);
@@ -3250,7 +3250,7 @@ static const char renumber_help[] =
 %end-doc */
 
 static int
-ActionRenumber (int argc, char **argv, int x, int y)
+ActionRenumber (int argc, char **argv, Coord x, Coord y)
 {
   bool changed = false;
   ElementTypePtr *element_list;
@@ -3619,7 +3619,7 @@ that this uses the highest numbered paste buffer.
 %end-doc */
 
 static int
-ActionRipUp (int argc, char **argv, int x, int y)
+ActionRipUp (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   bool changed = false;
@@ -3747,7 +3747,7 @@ Selects the shortest unselected rat on the board.
 %end-doc */
 
 static int
-ActionAddRats (int argc, char **argv, int x, int y)
+ActionAddRats (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   RatTypePtr shorty;
@@ -3812,7 +3812,7 @@ static const char delete_help[] = "Delete stuff.";
 %end-doc */
 
 static int
-ActionDelete (int argc, char **argv, int x, int y)
+ActionDelete (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   int id = GetFunctionID (function);
@@ -3862,7 +3862,7 @@ static const char deleterats_help[] = "Delete rat lines.";
 %end-doc */
 
 static int
-ActionDeleteRats (int argc, char **argv, int x, int y)
+ActionDeleteRats (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -3899,7 +3899,7 @@ connecting them are minimized.  Note that you cannot undo this.
 %end-doc */
 
 static int
-ActionAutoPlaceSelected (int argc, char **argv, int x, int y)
+ActionAutoPlaceSelected (int argc, char **argv, Coord x, Coord y)
 {
   hid_action("Busy");
   if (gui->confirm_dialog (_("Auto-placement can NOT be undone.\n"
@@ -3941,7 +3941,7 @@ responsive.
 %end-doc */
 
 static int
-ActionAutoRoute (int argc, char **argv, int x, int y)
+ActionAutoRoute (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   hid_action("Busy");
@@ -3986,7 +3986,7 @@ cursor location.
 %end-doc */
 
 static int
-ActionMarkCrosshair (int argc, char **argv, int x, int y)
+ActionMarkCrosshair (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (!function || !*function)
@@ -4040,7 +4040,7 @@ of the silk layer lines and arcs for this element.
 %end-doc */
 
 static int
-ActionChangeSize (int argc, char **argv, int x, int y)
+ActionChangeSize (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *delta = ARG (1);
@@ -4132,7 +4132,7 @@ static const char changedrillsize_help[] =
 %end-doc */
 
 static int
-ActionChange2ndSize (int argc, char **argv, int x, int y)
+ActionChange2ndSize (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *delta = ARG (1);
@@ -4199,7 +4199,7 @@ changes the polygon clearance.
 %end-doc */
 
 static int
-ActionChangeClearSize (int argc, char **argv, int x, int y)
+ActionChangeClearSize (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *delta = ARG (1);
@@ -4274,7 +4274,7 @@ the mask edge.
 %end-doc */
 
 static int
-ActionMinMaskGap (int argc, char **argv, int x, int y)
+ActionMinMaskGap (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *delta = ARG (1);
@@ -4358,7 +4358,7 @@ polygon edges.
 %end-doc */
 
 static int
-ActionMinClearGap (int argc, char **argv, int x, int y)
+ActionMinClearGap (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *delta = ARG (1);
@@ -4467,7 +4467,7 @@ ChangePinName(U3, 7, VCC)
 %end-doc */
 
 static int
-ActionChangePinName (int argc, char **argv, int x, int y)
+ActionChangePinName (int argc, char **argv, Coord x, Coord y)
 {
   int changed = 0;
   char *refdes, *pinnum, *pinname;
@@ -4565,7 +4565,7 @@ Changes the name of the currently active layer.
 %end-doc */
 
 int
-ActionChangeName (int argc, char **argv, int x, int y)
+ActionChangeName (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *name;
@@ -4656,7 +4656,7 @@ off are automatically deleted.
 %end-doc */
 
 static int
-ActionMorphPolygon (int argc, char **argv, int x, int y)
+ActionMorphPolygon (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -4710,7 +4710,7 @@ appear on the silk layer when you print the layout.
 %end-doc */
 
 static int
-ActionToggleHideName (int argc, char **argv, int x, int y)
+ActionToggleHideName (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function && PCB->ElementOn)
@@ -4785,7 +4785,7 @@ polygon, insulating them from each other.
 %end-doc */
 
 static int
-ActionChangeJoin (int argc, char **argv, int x, int y)
+ActionChangeJoin (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -4846,7 +4846,7 @@ Note that @code{Pins} means both pins and pads.
 %end-doc */
 
 static int
-ActionChangeSquare (int argc, char **argv, int x, int y)
+ActionChangeSquare (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -4904,7 +4904,7 @@ Note that @code{Pins} means pins and pads.
 %end-doc */
 
 static int
-ActionSetSquare (int argc, char **argv, int x, int y)
+ActionSetSquare (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function && *function)
@@ -4963,7 +4963,7 @@ Note that @code{Pins} means pins and pads.
 %end-doc */
 
 static int
-ActionClearSquare (int argc, char **argv, int x, int y)
+ActionClearSquare (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function && *function)
@@ -5021,7 +5021,7 @@ static const char changeoctagon_help[] =
 %end-doc */
 
 static int
-ActionChangeOctagon (int argc, char **argv, int x, int y)
+ActionChangeOctagon (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5082,7 +5082,7 @@ static const char setoctagon_help[] = "Sets the octagon-flag of objects.";
 %end-doc */
 
 static int
-ActionSetOctagon (int argc, char **argv, int x, int y)
+ActionSetOctagon (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5145,7 +5145,7 @@ static const char clearoctagon_help[] =
 %end-doc */
 
 static int
-ActionClearOctagon (int argc, char **argv, int x, int y)
+ActionClearOctagon (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5207,7 +5207,7 @@ plated-through hole (not set), or an unplated hole (set).
 %end-doc */
 
 static int
-ActionChangeHole (int argc, char **argv, int x, int y)
+ActionChangeHole (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5255,7 +5255,7 @@ The "no paste flag" of a pad determines whether the solderpaste
 %end-doc */
 
 static int
-ActionChangePaste (int argc, char **argv, int x, int y)
+ActionChangePaste (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5338,7 +5338,7 @@ numbered paste buffer.
 %end-doc */
 
 static int
-ActionSelect (int argc, char **argv, int x, int y)
+ActionSelect (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5445,7 +5445,7 @@ ActionSelect (int argc, char **argv, int x, int y)
 
 	case F_Convert:
 	  {
-	    int x, y;
+	    Coord x, y;
 	    Note.Buffer = Settings.BufferNumber;
 	    SetBufferNumber (MAX_BUFFER - 1);
 	    ClearBuffer (PASTEBUFFER);
@@ -5524,7 +5524,7 @@ type specified are unselected.
 %end-doc */
 
 static int
-ActionUnselect (int argc, char **argv, int x, int y)
+ActionUnselect (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -5667,7 +5667,7 @@ Save the content of the active Buffer to a file. This is the graphical way to cr
 %end-doc */
 
 static int
-ActionSaveTo (int argc, char **argv, int x, int y)
+ActionSaveTo (int argc, char **argv, Coord x, Coord y)
 {
   char *function;
   char *name;
@@ -5765,7 +5765,7 @@ saved in @code{./pcb.settings}.
 %end-doc */
 
 static int
-ActionSaveSettings (int argc, char **argv, int x, int y)
+ActionSaveSettings (int argc, char **argv, Coord x, Coord y)
 {
   int locally = argc > 0 ? (strncasecmp (argv[0], "local", 5) == 0) : 0;
   hid_save_settings (locally);
@@ -5811,7 +5811,7 @@ you may have made.
 %end-doc */
 
 static int
-ActionLoadFrom (int argc, char **argv, int x, int y)
+ActionLoadFrom (int argc, char **argv, Coord x, Coord y)
 {
   char *function;
   char *name;
@@ -5879,7 +5879,7 @@ If a name is not given, one is prompted for.
 %end-doc */
 
 static int
-ActionNew (int argc, char **argv, int x, int y)
+ActionNew (int argc, char **argv, Coord x, Coord y)
 {
   char *name = ARG (0);
 
@@ -5993,7 +5993,7 @@ Selects the given buffer to be the current paste buffer.
 %end-doc */
 
 static int
-ActionPasteBuffer (int argc, char **argv, int x, int y)
+ActionPasteBuffer (int argc, char **argv, Coord x, Coord y)
 {
   char *function = argc ? argv[0] : (char *)"";
   char *sbufnum = argc > 1 ? argv[1] : (char *)"";
@@ -6090,7 +6090,7 @@ ActionPasteBuffer (int argc, char **argv, int x, int y)
 	case F_ToLayout:
 	  {
 	    static int oldx = 0, oldy = 0;
-	    int x, y;
+	    Coord x, y;
 	    bool absolute;
 
 	    if (argc == 1)
@@ -6158,7 +6158,7 @@ same serial number will be undone (or redone) as a group.  See
 %end-doc */
 
 static int
-ActionUndo (int argc, char **argv, int x, int y)
+ActionUndo (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (!function || !*function)
@@ -6335,7 +6335,7 @@ three "undone" lines.
 %end-doc */
 
 static int
-ActionRedo (int argc, char **argv, int x, int y)
+ActionRedo (int argc, char **argv, Coord x, Coord y)
 {
   if (((Settings.Mode == POLYGON_MODE ||
         Settings.Mode == POLYGONHOLE_MODE) &&
@@ -6386,7 +6386,7 @@ will call Polygon(PreviousPoint) when appropriate to do so.
 %end-doc */
 
 static int
-ActionPolygon (int argc, char **argv, int x, int y)
+ActionPolygon (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function && Settings.Mode == POLYGON_MODE)
@@ -6421,7 +6421,7 @@ static const char routestyle_help[] =
 %end-doc */
 
 static int
-ActionRouteStyle (int argc, char **argv, int x, int y)
+ActionRouteStyle (int argc, char **argv, Coord x, Coord y)
 {
   char *str = ARG (0);
   RouteStyleType *rts;
@@ -6461,7 +6461,7 @@ units, currently 1/100 mil.
 %end-doc */
 
 static int
-ActionMoveObject (int argc, char **argv, int x, int y)
+ActionMoveObject (int argc, char **argv, Coord x, Coord y)
 {
   char *x_str = ARG (0);
   char *y_str = ARG (1);
@@ -6511,7 +6511,7 @@ or from solder to component, won't automatically flip it.  Use the
 %end-doc */
 
 static int
-ActionMoveToCurrentLayer (int argc, char **argv, int x, int y)
+ActionMoveToCurrentLayer (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   if (function)
@@ -6557,7 +6557,7 @@ sizes (thickness, keepaway, drill, etc) according to that item.
 %end-doc */
 
 static int
-ActionSetSame (int argc, char **argv, int x, int y)
+ActionSetSame (int argc, char **argv, Coord x, Coord y)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
@@ -6639,7 +6639,7 @@ SetFlag(SelectedPins,thermal)
 %end-doc */
 
 static int
-ActionSetFlag (int argc, char **argv, int x, int y)
+ActionSetFlag (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *flag = ARG (1);
@@ -6670,7 +6670,7 @@ ClrFlag(SelectedLines,join)
 %end-doc */
 
 static int
-ActionClrFlag (int argc, char **argv, int x, int y)
+ActionClrFlag (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *flag = ARG (1);
@@ -6700,7 +6700,7 @@ cleared.  If the value is 1, the flag is set.
 %end-doc */
 
 static int
-ActionChangeFlag (int argc, char **argv, int x, int y)
+ActionChangeFlag (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *flag = ARG (1);
@@ -6815,7 +6815,7 @@ Lines starting with @code{#} are ignored.
 %end-doc */
 
 static int
-ActionExecuteFile (int argc, char **argv, int x, int y)
+ActionExecuteFile (int argc, char **argv, Coord x, Coord y)
 {
   FILE *fp;
   char *fname;
@@ -6876,7 +6876,7 @@ ActionExecuteFile (int argc, char **argv, int x, int y)
 /* --------------------------------------------------------------------------- */
 
 static int
-ActionPSCalib (int argc, char **argv, int x, int y)
+ActionPSCalib (int argc, char **argv, Coord x, Coord y)
 {
   HID *ps = hid_find_exporter ("ps");
   ps->calibrate (0.0,0.0);
@@ -6979,7 +6979,7 @@ parse_layout_attribute_units (char *name, int def)
 }
 
 static int
-ActionElementList (int argc, char **argv, int x, int y)
+ActionElementList (int argc, char **argv, Coord x, Coord y)
 {
   ElementType *e = NULL;
   char *refdes, *value, *footprint, *old;
@@ -7153,7 +7153,7 @@ not specified, the given attribute is removed if present.
 %end-doc */
 
 static int
-ActionElementSetAttr (int argc, char **argv, int x, int y)
+ActionElementSetAttr (int argc, char **argv, Coord x, Coord y)
 {
   ElementType *e = NULL;
   char *refdes, *name, *value;
@@ -7215,7 +7215,7 @@ Runs the given command, which is a system executable.
 %end-doc */
 
 static int
-ActionExecCommand (int argc, char **argv, int x, int y)
+ActionExecCommand (int argc, char **argv, Coord x, Coord y)
 {
   char *command;
 
@@ -7547,7 +7547,7 @@ smallest board dimension.  Dispersion is saved in the
 %end-doc */
 
 static int
-ActionImport (int argc, char **argv, int x, int y)
+ActionImport (int argc, char **argv, Coord x, Coord y)
 {
   char *mode;
   char **sources = NULL;
@@ -7586,8 +7586,8 @@ ActionImport (int argc, char **argv, int x, int y)
   if (mode && strcasecmp (mode, "setnewpoint") == 0)
     {
       const char *xs, *ys, *units;
-      int x, y;
-      char buf[50];
+      Coord x, y;
+      gchar *buf;
 
       xs = ARG (1);
       ys = ARG (2);
@@ -7623,10 +7623,12 @@ ActionImport (int argc, char **argv, int x, int y)
 	  return 1;
 	}
 
-      sprintf (buf, "%d", x);
+      buf = pcb_g_strdup_printf ("%$ms", x);
       AttributePut (PCB, "import::newX", buf);
-      sprintf (buf, "%d", y);
+      g_free (buf);
+      buf = pcb_g_strdup_printf ("%$ms", y);
       AttributePut (PCB, "import::newY", buf);
+      g_free (buf);
       return 0;
     }
 
@@ -7855,7 +7857,7 @@ pcb, an element, or a layer.
 
 
 static int
-ActionAttributes (int argc, char **argv, int x, int y)
+ActionAttributes (int argc, char **argv, Coord x, Coord y)
 {
   char *function = ARG (0);
   char *layername = ARG (1);
diff --git a/src/buffer.c b/src/buffer.c
index 0943f1a..ac2aa54 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -815,7 +815,7 @@ into the footprint as well.  The footprint remains in the paste buffer.
 %end-doc */
 
 int
-LoadFootprint (int argc, char **argv, int x, int y)
+LoadFootprint (int argc, char **argv, Coord x, Coord y)
 {
   char *name = ARG(0);
   char *refdes = ARG(1);
@@ -1385,7 +1385,7 @@ angle is given, the user is prompted for one.
 %end-doc */
 
 int
-ActionFreeRotateBuffer(int argc, char **argv, int x, int y)
+ActionFreeRotateBuffer(int argc, char **argv, Coord x, Coord y)
 {
   char *angle_s;
 
diff --git a/src/buffer.h b/src/buffer.h
index 2ff9496..e589fd4 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -53,6 +53,6 @@ void *CopyObjectToBuffer (DataTypePtr, DataTypePtr, int,
 			  void *, void *, void *);
 
 /* This action is called from ActionElementAddIf() */
-int LoadFootprint (int argc, char **argv, int x, int y);
+int LoadFootprint (int argc, char **argv, Coord x, Coord y);
 
 #endif
diff --git a/src/command.c b/src/command.c
index 5c2b985..4c3a419 100644
--- a/src/command.c
+++ b/src/command.c
@@ -87,7 +87,7 @@ static const char h_help[] = "Print a help message for commands.";
 %end-doc */
 
 static int
-CommandHelp (int argc, char **argv, int x, int y)
+CommandHelp (int argc, char **argv, Coord x, Coord y)
 {
   Message ("following commands are supported:\n"
 	   "  Command()   execute an action command (too numerous to list)\n"
@@ -124,7 +124,7 @@ will popup.
 %end-doc */
 
 static int
-CommandLoadLayout (int argc, char **argv, int x, int y)
+CommandLoadLayout (int argc, char **argv, Coord x, Coord y)
 {
   char *filename, *name = NULL;
 
@@ -162,7 +162,7 @@ a file select box will popup.
 %end-doc */
 
 static int
-CommandLoadElementToBuffer (int argc, char **argv, int x, int y)
+CommandLoadElementToBuffer (int argc, char **argv, Coord x, Coord y)
 {
   char *filename;
 
@@ -198,7 +198,7 @@ If no filename is specified a file select box will popup.
 %end-doc */
 
 static int
-CommandLoadLayoutToBuffer (int argc, char **argv, int x, int y)
+CommandLoadLayoutToBuffer (int argc, char **argv, Coord x, Coord y)
 {
   char *filename;
 
@@ -233,7 +233,7 @@ save) before quitting.
 %end-doc */
 
 static int
-CommandQuit (int argc, char **argv, int x, int y)
+CommandQuit (int argc, char **argv, Coord x, Coord y)
 {
   if (!PCB->Changed || gui->close_confirm_dialog () == HID_CLOSE_CONFIRM_OK)
     QuitApplication ();
@@ -255,7 +255,7 @@ confirmation.
 %end-doc */
 
 static int
-CommandReallyQuit (int argc, char **argv, int x, int y)
+CommandReallyQuit (int argc, char **argv, Coord x, Coord y)
 {
   QuitApplication ();
   return 0;
@@ -282,7 +282,7 @@ for verifying the board layout (which is also accomplished by the
 %end-doc */
 
 static int
-CommandLoadNetlist (int argc, char **argv, int x, int y)
+CommandLoadNetlist (int argc, char **argv, Coord x, Coord y)
 {
   char *filename, *name = NULL;
 
@@ -334,7 +334,7 @@ and has the same functionality as @code{s}.
 %end-doc */
 
 static int
-CommandSaveLayout (int argc, char **argv, int x, int y)
+CommandSaveLayout (int argc, char **argv, Coord x, Coord y)
 {
   switch (argc)
     {
@@ -372,7 +372,7 @@ has the same functionality as @code{s} combined with @code{q}.
 %end-doc */
 
 static int
-CommandSaveLayoutAndQuit (int argc, char **argv, int x, int y)
+CommandSaveLayoutAndQuit (int argc, char **argv, Coord x, Coord y)
 {
   if (!CommandSaveLayout (argc, argv, x, y))
     return CommandQuit (0, 0, 0, 0);
diff --git a/src/djopt.c b/src/djopt.c
index 80fa3c1..1d8332d 100644
--- a/src/djopt.c
+++ b/src/djopt.c
@@ -140,7 +140,7 @@ optimize hand-routed traces also.
 %end-doc */
 
 int
-djopt_set_auto_only (int argc, char **argv, int x, int y)
+djopt_set_auto_only (int argc, char **argv, Coord x, Coord y)
 {
   autorouted_only = autorouted_only ? 0 : 1;
   return 0;
@@ -2916,7 +2916,7 @@ RF losses and trace length.
 %end-doc */
 
 static int
-ActionDJopt (int argc, char **argv, int x, int y)
+ActionDJopt (int argc, char **argv, Coord x, Coord y)
 {
   char *arg = argc > 0 ? argv[0] : 0;
   int layn, saved = 0;
diff --git a/src/djopt.h b/src/djopt.h
index 76ee3b6..bc337af 100644
--- a/src/djopt.h
+++ b/src/djopt.h
@@ -31,6 +31,6 @@
 
 #include "global.h"
 
-int ActionDJopt (int, char **, int, int);
-int djopt_set_auto_only (int, char **, int, int);
+int ActionDJopt (int, char **, Coord, Coord);
+int djopt_set_auto_only (int, char **, Coord, Coord);
 #endif
diff --git a/src/fontmode.c b/src/fontmode.c
index 04b230d..8130b59 100644
--- a/src/fontmode.c
+++ b/src/fontmode.c
@@ -75,7 +75,7 @@ static const char fontedit_help[] =
 %end-doc */
 
 static int
-FontEdit (int argc, char **argv, int Ux, int Uy)
+FontEdit (int argc, char **argv, Coord Ux, Coord Uy)
 {
   FontType *font;
   SymbolType *symbol;
@@ -168,7 +168,7 @@ static const char fontsave_help[] = "Convert the current PCB back to a font.";
 %end-doc */
 
 static int
-FontSave (int argc, char **argv, int Ux, int Uy)
+FontSave (int argc, char **argv, Coord Ux, Coord Uy)
 {
   FontTypePtr font;
   SymbolTypePtr symbol;
diff --git a/src/global.h b/src/global.h
index 477798b..5b7ac4c 100644
--- a/src/global.h
+++ b/src/global.h
@@ -64,6 +64,9 @@ typedef struct AttributeListType AttributeListType, *AttributeListTypePtr;
 typedef struct unit Unit;
 typedef struct increments Increments;
 
+typedef int Coord;		/* pcb base unit */
+typedef double Angle;		/* degrees */
+
 #include "hid.h"
 #include "polyarea.h"
 
@@ -86,10 +89,6 @@ typedef struct increments Increments;
 # define bindtextdomain(D, Dir) (D)
 #endif /* ENABLE_NLS */
 
-
-typedef int Coord;		/* pcb base unit */
-typedef double Angle;		/* degrees */
-
 #if 1
 typedef int LocationType;
 typedef int BDimension;		/* big dimension */
diff --git a/src/hid.h b/src/hid.h
index b2725ac..efa2dfd 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -79,7 +79,7 @@ extern "C"
     /* Called when the action is triggered.  If this function returns
        non-zero, no further actions will be invoked for this key/mouse
        event.  */
-    int (*trigger_cb) (int argc, char **argv, int x, int y);
+    int (*trigger_cb) (int argc, char **argv, Coord x, Coord y);
     /* Short description that sometimes accompanies the name.  */
     const char *description;
     /* Full allowed syntax; use \n to separate lines.  */
@@ -397,7 +397,7 @@ typedef enum
     int (*shift_is_pressed) (void);
     int (*control_is_pressed) (void);
 	int (*mod1_is_pressed) (void);
-    void (*get_coords) (const char *msg_, int *x_, int *y_);
+    void (*get_coords) (const char *msg_, Coord *x_, Coord *y_);
 
     /* Sets the crosshair, which may differ from the pointer depending
        on grid and pad snap.  Note that the HID is responsible for
diff --git a/src/hid/batch/batch.c b/src/hid/batch/batch.c
index 962c594..f486ef3 100644
--- a/src/hid/batch/batch.c
+++ b/src/hid/batch/batch.c
@@ -263,7 +263,7 @@ batch_mod1_is_pressed (void)
 }
 
 static void
-batch_get_coords (const char *msg, int *x, int *y)
+batch_get_coords (const char *msg, Coord *x, Coord *y)
 {
 }
 
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index 43c50f8..da3bbfd 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -213,7 +213,8 @@ hid_actionl (const char *name, ...)
 int
 hid_actionv (const char *name, int argc, char **argv)
 {
-  int x = 0, y = 0, i, ret;
+  Coord x = 0, y = 0;
+  int i, ret;
   HID_Action *a, *old_action;
 
   if (!name)
diff --git a/src/hid/common/hidnogui.c b/src/hid/common/hidnogui.c
index aef38b8..55e6dca 100644
--- a/src/hid/common/hidnogui.c
+++ b/src/hid/common/hidnogui.c
@@ -214,7 +214,7 @@ nogui_mod1_is_pressed (void)
 }
 
 static void
-nogui_get_coords (const char *msg, int *x, int *y)
+nogui_get_coords (const char *msg, Coord *x, Coord *y)
 {
   CRASH;
 }
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index a9c994e..68775c1 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -30,8 +30,8 @@
 RCSID ("$Id$");
 
 
-static void zoom_to (double factor, int x, int y);
-static void zoom_by (double factor, int x, int y);
+static void zoom_to (double factor, Coord x, Coord y);
+static void zoom_by (double factor, Coord x, Coord y);
 static void zoom_fit (void);
 
 int ghid_flip_x = 0, ghid_flip_y = 0;
@@ -114,7 +114,7 @@ Note that zoom factors of zero are silently ignored.
 %end-doc */
 
 static int
-Zoom (int argc, char **argv, int x, int y)
+Zoom (int argc, char **argv, Coord x, Coord y)
 {
   const char *vp;
   double v;
@@ -154,7 +154,7 @@ Zoom (int argc, char **argv, int x, int y)
 
 
 static void
-zoom_to (double new_zoom, int x, int y)
+zoom_to (double new_zoom, Coord x, Coord y)
 {
   double min_zoom, max_zoom;
   double xtmp, ytmp;
@@ -200,7 +200,7 @@ zoom_to (double new_zoom, int x, int y)
 }
 
 static void
-zoom_by (double factor, int x, int y)
+zoom_by (double factor, Coord x, Coord y)
 {
   zoom_to (gport->zoom * factor, x, y);
 }
@@ -1078,7 +1078,7 @@ This just pops up a dialog telling the user which version of
 
 
 static int
-About (int argc, char **argv, int x, int y)
+About (int argc, char **argv, Coord x, Coord y)
 {
   ghid_dialog_about ();
   return 0;
@@ -1098,14 +1098,14 @@ Prompts the user for a coordinate, if one is not already selected.
 %end-doc */
 
 static int
-GetXY (int argc, char **argv, int x, int y)
+GetXY (int argc, char **argv, Coord x, Coord y)
 {
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
-static int PointCursor (int argc, char **argv, int x, int y)
+static int PointCursor (int argc, char **argv, Coord x, Coord y)
 {
   if (!ghidgui)
     return 0;
@@ -1120,7 +1120,7 @@ static int PointCursor (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 static int
-RouteStylesChanged (int argc, char **argv, int x, int y)
+RouteStylesChanged (int argc, char **argv, Coord x, Coord y)
 {
   gint n;
 
@@ -1133,7 +1133,7 @@ RouteStylesChanged (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 int
-PCBChanged (int argc, char **argv, int x, int y)
+PCBChanged (int argc, char **argv, Coord x, Coord y)
 {
   if (!ghidgui)
     return 0;
@@ -1154,7 +1154,7 @@ PCBChanged (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 static int
-LayerGroupsChanged (int argc, char **argv, int x, int y)
+LayerGroupsChanged (int argc, char **argv, Coord x, Coord y)
 {
   printf (_("LayerGroupsChanged -- not implemented\n"));
   return 0;
@@ -1163,7 +1163,7 @@ LayerGroupsChanged (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 static int
-LibraryChanged (int argc, char **argv, int x, int y)
+LibraryChanged (int argc, char **argv, Coord x, Coord y)
 {
   /* No need to show the library window every time it changes...
    *  ghid_library_window_show (&ghid_port, FALSE);
@@ -1174,7 +1174,7 @@ LibraryChanged (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 static int
-Command (int argc, char **argv, int x, int y)
+Command (int argc, char **argv, Coord x, Coord y)
 {
   ghid_handle_user_command (TRUE);
   return 0;
@@ -1183,7 +1183,7 @@ Command (int argc, char **argv, int x, int y)
 /* ---------------------------------------------------------------------- */
 
 static int
-Load (int argc, char **argv, int x, int y)
+Load (int argc, char **argv, Coord x, Coord y)
 {
   char *function;
   char *name = NULL;
@@ -1257,7 +1257,7 @@ called with that filename.
 %end-doc */
 
 static int
-Save (int argc, char **argv, int x, int y)
+Save (int argc, char **argv, Coord x, Coord y)
 {
   char *function;
   char *name;
@@ -1356,7 +1356,7 @@ side'' of the board.
 
 
 static int
-SwapSides (int argc, char **argv, int x, int y)
+SwapSides (int argc, char **argv, Coord x, Coord y)
 {
   gint flipd;
   int do_flip_x = 0;
@@ -1454,7 +1454,7 @@ options, and print the layout.
 %end-doc */
 
 static int
-Print (int argc, char **argv, int x, int y)
+Print (int argc, char **argv, Coord x, Coord y)
 {
   HID **hids;
   int i;
@@ -1512,7 +1512,7 @@ the measurements in, so that future printouts will be more precise.
 %end-doc */
 
 static int
-PrintCalibrate (int argc, char **argv, int x, int y)
+PrintCalibrate (int argc, char **argv, Coord x, Coord y)
 {
   HID *printer = hid_find_printer ();
   printer->calibrate (0.0, 0.0);
@@ -1530,7 +1530,7 @@ PrintCalibrate (int argc, char **argv, int x, int y)
 /* ------------------------------------------------------------ */
 
 static int
-Export (int argc, char **argv, int x, int y)
+Export (int argc, char **argv, Coord x, Coord y)
 {
 
   /* check if layout is empty */
@@ -1547,7 +1547,7 @@ Export (int argc, char **argv, int x, int y)
 /* ------------------------------------------------------------ */
 
 static int
-Benchmark (int argc, char **argv, int x, int y)
+Benchmark (int argc, char **argv, Coord x, Coord y)
 {
   int i = 0;
   time_t start, end;
@@ -1587,7 +1587,7 @@ currently within the window already.
 %end-doc */
 
 static int
-Center(int argc, char **argv, int pcb_x, int pcb_y)
+Center(int argc, char **argv, Coord pcb_x, Coord pcb_y)
 {
   GdkDisplay *display;
   GdkScreen *screen;
@@ -1669,7 +1669,7 @@ The values are percentages of the board size.  Thus, a move of
 %end-doc */
 
 static int
-CursorAction(int argc, char **argv, int x, int y)
+CursorAction(int argc, char **argv, Coord x, Coord y)
 {
   UnitList extra_units_x = {
     { "grid",  PCB->Grid, 0 },
@@ -1751,7 +1751,7 @@ Open the DRC violations window.
 %end-doc */
 
 static int
-DoWindows (int argc, char **argv, int x, int y)
+DoWindows (int argc, char **argv, Coord x, Coord y)
 {
   char *a = argc == 1 ? argv[0] : (char *)"";
 
@@ -1808,7 +1808,7 @@ Sets the display units to millimeters.
 %end-doc */
 
 static int
-SetUnits (int argc, char **argv, int x, int y)
+SetUnits (int argc, char **argv, Coord x, Coord y)
 {
   const Unit *new_unit;
   if (argc == 0)
@@ -1853,7 +1853,7 @@ default is given, div=40.
 %end-doc */
 
 static int
-ScrollAction (int argc, char **argv, int x, int y)
+ScrollAction (int argc, char **argv, Coord x, Coord y)
 {
   gdouble dx = 0.0, dy = 0.0;
   int div = 40;
@@ -1904,7 +1904,7 @@ the same coordinates, the auto pan mode is toggled.
 %end-doc */
 
 static int
-PanAction (int argc, char **argv, int x, int y)
+PanAction (int argc, char **argv, Coord x, Coord y)
 {
   static int on_x, on_y;
   int mode;
@@ -1961,7 +1961,7 @@ button number must be specified as the second argument.
 
 
 static int
-Popup (int argc, char **argv, int x, int y)
+Popup (int argc, char **argv, Coord x, Coord y)
 {
   GtkWidget *menu;
   char *element;
@@ -2016,7 +2016,7 @@ Asks user which schematics to import into PCB.
 
 
 static int
-ImportGUI (int argc, char **argv, int x, int y)
+ImportGUI (int argc, char **argv, Coord x, Coord y)
 {
     char *name = NULL;
     static gchar *current_layout_dir = NULL;
@@ -2047,7 +2047,7 @@ ImportGUI (int argc, char **argv, int x, int y)
 
 /* ------------------------------------------------------------ */
 static int
-Busy (int argc, char **argv, int x, int y)
+Busy (int argc, char **argv, Coord x, Coord y)
 {
   ghid_watch_cursor ();
   return 0;
diff --git a/src/hid/gtk/gui-log-window.c b/src/hid/gtk/gui-log-window.c
index a91f346..e964b8e 100644
--- a/src/hid/gtk/gui-log-window.c
+++ b/src/hid/gtk/gui-log-window.c
@@ -206,7 +206,7 @@ to it.  If false, the log will still be updated, but the window won't \
 be shown.";
 
 static gint
-GhidLogShowOnAppend (int argc, char **argv, int x, int y)
+GhidLogShowOnAppend (int argc, char **argv, Coord x, Coord y)
 {
   char *a = argc == 1 ? argv[0] : (char *)"";
 
diff --git a/src/hid/gtk/gui-netlist-window.c b/src/hid/gtk/gui-netlist-window.c
index bc3fc69..28d0ff2 100644
--- a/src/hid/gtk/gui-netlist-window.c
+++ b/src/hid/gtk/gui-netlist-window.c
@@ -1011,7 +1011,7 @@ ghid_netlist_window_update (gboolean init_nodes)
 }
 
 static gint
-GhidNetlistChanged (int argc, char **argv, int x, int y)
+GhidNetlistChanged (int argc, char **argv, Coord x, Coord y)
 {
   loading_new_netlist = TRUE;
   ghid_netlist_window_update (TRUE);
@@ -1029,7 +1029,7 @@ static const char netlistshow_help[] =
 show the window if it isn't already shown.";
 
 static gint
-GhidNetlistShow (int argc, char **argv, int x, int y)
+GhidNetlistShow (int argc, char **argv, Coord x, Coord y)
 {
   ghid_netlist_window_create (gport);
   if (argc > 0)
@@ -1044,7 +1044,7 @@ static const char netlistpresent_help[] =
 "Presents the netlist window.";
 
 static gint
-GhidNetlistPresent (int argc, char **argv, int x, int y)
+GhidNetlistPresent (int argc, char **argv, Coord x, Coord y)
 {
   ghid_netlist_window_show (gport, TRUE);
   return 0;
diff --git a/src/hid/gtk/gui-output-events.c b/src/hid/gtk/gui-output-events.c
index bc47214..2bb3dd7 100644
--- a/src/hid/gtk/gui-output-events.c
+++ b/src/hid/gtk/gui-output-events.c
@@ -153,7 +153,7 @@ ghid_port_ranges_scale (gboolean emit_changed)
  */
 
 void
-ghid_get_coords (const char *msg, int *x, int *y)
+ghid_get_coords (const char *msg, Coord *x, Coord *y)
 {
   if (!ghid_port.has_entered && msg)
     ghid_get_user_xy (msg);
@@ -663,7 +663,7 @@ gint
 ghid_port_window_leave_cb (GtkWidget * widget, 
                            GdkEventCrossing * ev, GHidPort * out)
 {
-  gint x0, y0, x, y, dx, dy, w, h;
+  Coord x0, y0, x, y, dx, dy, w, h;
   
   /* printf("leave mode: %d detail: %d\n", ev->mode, ev->detail); */
 
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index 7b210f8..aaab38e 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -2442,7 +2442,7 @@ ghid_do_export (HID_Attr_Val * options)
 }
 
 gint
-LayersChanged (int argc, char **argv, int px, int py)
+LayersChanged (int argc, char **argv, Coord x, Coord y)
 {
   if (!ghidgui || !ghidgui->ui_manager)
     return 0;
@@ -2482,7 +2482,7 @@ the same as a special layer, the layer is chosen over the special layer.
 %end-doc */
 
 static int
-ToggleView (int argc, char **argv, int x, int y)
+ToggleView (int argc, char **argv, Coord x, Coord y)
 {
   int i, l;
   static gboolean in_toggle_view = 0;
@@ -2565,7 +2565,7 @@ visible if it is not already visible
 %end-doc */
 
 static int
-SelectLayer (int argc, char **argv, int x, int y)
+SelectLayer (int argc, char **argv, Coord x, Coord y)
 {
   int newl;
   if (argc == 0)
@@ -3557,7 +3557,7 @@ Opens the window which allows editing of the route styles.
 %end-doc */
 
 static int
-AdjustStyle(int argc, char **argv, int x, int y)
+AdjustStyle(int argc, char **argv, Coord x, Coord y)
 {
   RouteStyleType *rst = NULL;
   
@@ -3588,7 +3588,7 @@ resource compatibility with the lesstif HID.
 %end-doc */
 
 static int
-EditLayerGroups(int argc, char **argv, int x, int y)
+EditLayerGroups(int argc, char **argv, Coord x, Coord y)
 {
   
   if (argc != 0)
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index e8123d9..6cd85e5 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -497,8 +497,8 @@ void ghid_cancel_lead_user (void);
 
 /* gtkhid-main.c */
 void ghid_pan_fixup (void);
-void ghid_get_coords (const char *msg, int *x, int *y);
-gint PCBChanged (int argc, char **argv, int x, int y);
+void ghid_get_coords (const char *msg, Coord *x, Coord *y);
+gint PCBChanged (int argc, char **argv, Coord x, Coord y);
 
 
 
diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index 27d312c..5606e5b 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -110,7 +110,7 @@ called with that filename.
 %end-doc */
 
 static int
-Load (int argc, char **argv, int x, int y)
+Load (int argc, char **argv, Coord x, Coord y)
 {
   const char *function;
   char *name;
@@ -171,7 +171,7 @@ load that vendor file.
 %end-doc */
 
 static int
-LoadVendor (int argc, char **argv, int x, int y)
+LoadVendor (int argc, char **argv, Coord x, Coord y)
 {
   char *name;
   XmString xmname, pattern;
@@ -229,7 +229,7 @@ called with that filename.
 %end-doc */
 
 static int
-Save (int argc, char **argv, int x, int y)
+Save (int argc, char **argv, Coord x, Coord y)
 {
   const char *function;
   char *name;
@@ -482,7 +482,7 @@ lesstif_confirm_dialog (char *msg, ...)
 }
 
 static int
-ConfirmAction (int argc, char **argv, int x, int y)
+ConfirmAction (int argc, char **argv, Coord x, Coord y)
 {
   int rv = lesstif_confirm_dialog (argc > 0 ? argv[0] : 0,
 				   argc > 1 ? argv[1] : 0,
@@ -616,7 +616,7 @@ user's stdout.
 %end-doc */
 
 static int
-PromptFor (int argc, char **argv, int x, int y)
+PromptFor (int argc, char **argv, Coord x, Coord y)
 {
   char *rv = lesstif_prompt_for (argc > 0 ? argv[0] : 0,
 				 argc > 1 ? argv[1] : 0);
@@ -902,7 +902,7 @@ Open the netlist window.
 %end-doc */
 
 static int
-DoWindows (int argc, char **argv, int x, int y)
+DoWindows (int argc, char **argv, Coord x, Coord y)
 {
   const char *a = argc == 1 ? argv[0] : "";
   if (strcmp (a, "1") == 0 || strcasecmp (a, "Layout") == 0)
@@ -946,7 +946,7 @@ This just pops up a dialog telling the user which version of
 
 
 static int
-About (int argc, char **argv, int x, int y)
+About (int argc, char **argv, Coord x, Coord y)
 {
   static Widget about = 0;
   if (!about)
@@ -979,7 +979,7 @@ options, and print the layout.
 %end-doc */
 
 static int
-Print (int argc, char **argv, int x, int y)
+Print (int argc, char **argv, Coord x, Coord y)
 {
   HID_Attribute *opts;
   HID *printer;
@@ -1029,7 +1029,7 @@ the measurements in, so that future printouts will be more precise.
 %end-doc */
 
 static int
-PrintCalibrate (int argc, char **argv, int x, int y)
+PrintCalibrate (int argc, char **argv, Coord x, Coord y)
 {
   HID *printer = hid_find_printer ();
   printer->calibrate (0.0, 0.0);
@@ -1056,7 +1056,7 @@ that exporter's options, and exports the layout.
 %end-doc */
 
 static int
-Export (int argc, char **argv, int x, int y)
+Export (int argc, char **argv, Coord x, Coord y)
 {
   static Widget selector = 0;
   HID_Attribute *opts;
@@ -1247,7 +1247,7 @@ The units are determined by the default display units.
 %end-doc */
 
 static int
-AdjustSizes (int argc, char **argv, int x, int y)
+AdjustSizes (int argc, char **argv, Coord x, Coord y)
 {
   if (!sizes_dialog)
     {
@@ -1571,7 +1571,7 @@ See @ref{ChangeName Action}.
 %end-doc */
 
 static int
-EditLayerGroups (int argc, char **argv, int x, int y)
+EditLayerGroups (int argc, char **argv, Coord x, Coord y)
 {
   if (!layer_groups_form)
     {
@@ -2013,7 +2013,7 @@ future imports.
 %end-doc */
 
 static int
-ImportGUI (int argc, char **argv, int x, int y)
+ImportGUI (int argc, char **argv, Coord x, Coord y)
 {
   static int I_am_recursing = 0;
   static XmString xms_sch = 0, xms_import = 0;
diff --git a/src/hid/lesstif/lesstif.h b/src/hid/lesstif/lesstif.h
index c4a2df4..e81c3e4 100644
--- a/src/hid/lesstif/lesstif.h
+++ b/src/hid/lesstif/lesstif.h
@@ -37,7 +37,7 @@ extern int lesstif_pcbxy_to_winxy (int pcbx, int pcby, int *winx, int *winy);
 extern void lesstif_need_idle_proc (void);
 extern void lesstif_show_crosshair (int);
 extern void lesstif_invalidate_all (void);
-extern void lesstif_coords_to_pcb (int, int, int *, int *);
+extern void lesstif_coords_to_pcb (int, int, Coord *, Coord *);
 extern void lesstif_get_xy (const char *msg);
 extern void lesstif_update_widget_flags (void);
 extern int lesstif_call_action (const char *, int, char **);
diff --git a/src/hid/lesstif/library.c b/src/hid/lesstif/library.c
index 5ce77f7..029a023 100644
--- a/src/hid/lesstif/library.c
+++ b/src/hid/lesstif/library.c
@@ -123,7 +123,7 @@ build_library_dialog ()
 }
 
 static int
-LibraryChanged (int argc, char **argv, int x, int y)
+LibraryChanged (int argc, char **argv, Coord x, Coord y)
 {
   int i;
   if (!Library.MenuN)
@@ -155,7 +155,7 @@ static const char libraryshow_help[] =
 %end-doc */
 
 static int
-LibraryShow (int argc, char **argv, int x, int y)
+LibraryShow (int argc, char **argv, Coord x, Coord y)
 {
   if (build_library_dialog ())
     return 0;
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 1c4d8b9..ef0b164 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -318,7 +318,7 @@ cur_clip ()
 /* Called from the core when it's busy doing something and we need to
    indicate that to the user.  */
 static int
-Busy(int argc, char **argv, int x, int y)
+Busy(int argc, char **argv, Coord x, Coord y)
 {
   static Cursor busy_cursor = 0;
   if (busy_cursor == 0)
@@ -334,7 +334,7 @@ Busy(int argc, char **argv, int x, int y)
 /* Local actions.  */
 
 static int
-PointCursor (int argc, char **argv, int x, int y)
+PointCursor (int argc, char **argv, Coord x, Coord y)
 {
   if (argc > 0)
     over_point = 1;
@@ -345,7 +345,7 @@ PointCursor (int argc, char **argv, int x, int y)
 }
 
 static int
-PCBChanged (int argc, char **argv, int x, int y)
+PCBChanged (int argc, char **argv, Coord x, Coord y)
 {
   if (work_area == 0)
     return 0;
@@ -403,7 +403,7 @@ Sets the display units to millimeters.
 %end-doc */
 
 static int
-SetUnits (int argc, char **argv, int x, int y)
+SetUnits (int argc, char **argv, Coord x, Coord y)
 {
   const Unit *new_unit;
   if (argc == 0)
@@ -465,7 +465,7 @@ Note that zoom factors of zero are silently ignored.
 %end-doc */
 
 static int
-ZoomAction (int argc, char **argv, int x, int y)
+ZoomAction (int argc, char **argv, Coord x, Coord y)
 {
   const char *vp;
   double v;
@@ -514,7 +514,7 @@ ZoomAction (int argc, char **argv, int x, int y)
 static int pan_thumb_mode;
 
 static int
-PanAction (int argc, char **argv, int x, int y)
+PanAction (int argc, char **argv, Coord x, Coord y)
 {
   int mode;
 
@@ -591,7 +591,7 @@ group_showing (int g, int *c)
 }
 
 static int
-SwapSides (int argc, char **argv, int x, int y)
+SwapSides (int argc, char **argv, Coord x, Coord y)
 {
   int old_shown_side = Settings.ShowSolderSide;
   int comp_group = GetLayerGroupNumberByNumber (component_silk_layer);
@@ -759,7 +759,7 @@ before.
 %end-doc */
 
 static int
-Command (int argc, char **argv, int x, int y)
+Command (int argc, char **argv, Coord x, Coord y)
 {
   XtManageChild (m_cmd_label);
   XtManageChild (m_cmd);
@@ -782,7 +782,7 @@ It reports the amount of time needed to draw the screen once.
 %end-doc */
 
 static int
-Benchmark (int argc, char **argv, int x, int y)
+Benchmark (int argc, char **argv, Coord x, Coord y)
 {
   int i = 0;
   time_t start, end;
@@ -817,7 +817,7 @@ Benchmark (int argc, char **argv, int x, int y)
 }
 
 static int
-Center(int argc, char **argv, int x, int y)
+Center(int argc, char **argv, Coord x, Coord y)
 {
   x = GridFit (x, PCB->Grid, PCB->GridOffsetX);
   y = GridFit (y, PCB->Grid, PCB->GridOffsetY);
@@ -874,7 +874,7 @@ The values are percentages of the board size.  Thus, a move of
 %end-doc */
 
 static int
-CursorAction(int argc, char **argv, int x, int y)
+CursorAction(int argc, char **argv, Coord x, Coord y)
 {
   UnitList extra_units_x = {
     { "grid",  PCB->Grid, 0 },
@@ -3439,7 +3439,7 @@ lesstif_mod1_is_pressed (void)
   return alt_pressed;
 }
 
-extern void lesstif_get_coords (const char *msg, int *x, int *y);
+extern void lesstif_get_coords (const char *msg, Coord *x, Coord *y);
 
 static void
 lesstif_set_crosshair (int x, int y, int action)
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index fe45b32..8c71c61 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -60,7 +60,7 @@ Prompts the user for a coordinate, if one is not already selected.
 %end-doc */
 
 static int
-GetXY (int argc, char **argv, int x, int y)
+GetXY (int argc, char **argv, Coord x, Coord y)
 {
   return 0;
 }
@@ -93,7 +93,7 @@ on one.
 %end-doc */
 
 static int
-Debug (int argc, char **argv, BDimension x, BDimension y)
+Debug (int argc, char **argv, Coord x, Coord y)
 {
   int i;
   printf ("Debug:");
@@ -117,7 +117,7 @@ passed a 1, does nothing but pretends to fail.
 %end-doc */
 
 static int
-Return (int argc, char **argv, int x, int y)
+Return (int argc, char **argv, Coord x, Coord y)
 {
   return atoi (argv[0]);
 }
@@ -142,7 +142,7 @@ pcb --action-string DumpKeys
 
 static int do_dump_keys = 0;
 static int
-DumpKeys (int argc, char **argv, int x, int y)
+DumpKeys (int argc, char **argv, Coord x, Coord y)
 {
   do_dump_keys = 1;
   return 0;
@@ -174,7 +174,7 @@ static int bg_color;
 extern Widget lesstif_m_layer;
 
 static int
-LayersChanged (int argc, char **argv, int x, int y)
+LayersChanged (int argc, char **argv, Coord x, Coord y)
 {
   int l, i, set;
   char *name;
@@ -434,7 +434,7 @@ visible if it is not already visible
 %end-doc */
 
 static int
-SelectLayer (int argc, char **argv, int x, int y)
+SelectLayer (int argc, char **argv, Coord x, Coord y)
 {
   int newl;
   if (argc == 0)
@@ -471,7 +471,7 @@ the same as a special layer, the layer is chosen over the special layer.
 %end-doc */
 
 static int
-ToggleView (int argc, char **argv, int x, int y)
+ToggleView (int argc, char **argv, Coord x, Coord y)
 {
   int i, l;
 
@@ -801,7 +801,7 @@ lesstif_get_xy (const char *message)
 }
 
 void
-lesstif_get_coords (const char *msg, int *px, int *py)
+lesstif_get_coords (const char *msg, Coord *px, Coord *py)
 {
   if (!have_xy && msg)
     lesstif_get_xy (msg);
diff --git a/src/hid/lesstif/netlist.c b/src/hid/lesstif/netlist.c
index e5575d2..ce28539 100644
--- a/src/hid/lesstif/netlist.c
+++ b/src/hid/lesstif/netlist.c
@@ -45,7 +45,7 @@ static XmString *netnode_strings = 0;
 static int n_netnode_strings;
 static int last_pick = -1;
 
-static int LesstifNetlistChanged (int argc, char **argv, int x, int y);
+static int LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y);
 
 static void
 pick_net (int pick)
@@ -385,7 +385,7 @@ build_netlist_dialog ()
 }
 
 static int
-LesstifNetlistChanged (int argc, char **argv, int x, int y)
+LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y)
 {
   int i;
   if (!PCB->NetlistLib.MenuN)
@@ -419,7 +419,7 @@ static const char netlistshow_help[] =
 %end-doc */
 
 static int
-LesstifNetlistShow (int argc, char **argv, int x, int y)
+LesstifNetlistShow (int argc, char **argv, Coord x, Coord y)
 {
   if (build_netlist_dialog ())
     return 0;
diff --git a/src/hid/lesstif/styles.c b/src/hid/lesstif/styles.c
index 9442849..ee07273 100644
--- a/src/hid/lesstif/styles.c
+++ b/src/hid/lesstif/styles.c
@@ -93,7 +93,7 @@ static char *value_names[] = {
   "Thickness", "Diameter", "Hole", "Keepaway"
 };
 
-static int RouteStylesChanged (int argc, char **argv, int x, int y);
+static int RouteStylesChanged (int argc, char **argv, Coord x, Coord y);
 
 static void
 update_one_value (int i, Coord v)
@@ -348,7 +348,7 @@ static const char adjuststyle_help[] =
 %end-doc */
 
 static int
-AdjustStyle (int argc, char **argv, int x, int y)
+AdjustStyle (int argc, char **argv, Coord x, Coord y)
 {
   if (!mainwind)
     return 1;
@@ -411,7 +411,7 @@ AdjustStyle (int argc, char **argv, int x, int y)
 }
 
 static int
-RouteStylesChanged (int argc, char **argv, int x, int y)
+RouteStylesChanged (int argc, char **argv, Coord x, Coord y)
 {
   int i, j, h;
   if (!PCB || !PCB->RouteStyle[0].Name)
diff --git a/src/misc.c b/src/misc.c
index 8db434a..97937aa 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -2388,7 +2388,7 @@ ElementOrientation (ElementType *e)
 }
 
 int
-ActionListRotations(int argc, char **argv, int x, int y)
+ActionListRotations(int argc, char **argv, Coord x, Coord y)
 {
   ELEMENT_LOOP (PCB->Data);
   {
diff --git a/src/move.c b/src/move.c
index 49177e9..3477af1 100644
--- a/src/move.c
+++ b/src/move.c
@@ -1134,7 +1134,7 @@ Creates a new layer.
 %end-doc */
 
 int
-MoveLayerAction (int argc, char **argv, int x, int y)
+MoveLayerAction (int argc, char **argv, Coord x, Coord y)
 {
   int old_index, new_index;
   int new_top = -1;
diff --git a/src/netlist.c b/src/netlist.c
index 0c004f9..06f0e77 100644
--- a/src/netlist.c
+++ b/src/netlist.c
@@ -344,7 +344,7 @@ updates the GUI.
 #define ARG(n) (argc > (n) ? argv[n] : 0)
 
 static int
-Netlist (int argc, char **argv, int x, int y)
+Netlist (int argc, char **argv, Coord x, Coord y)
 {
   NFunc func;
   int i, j;
diff --git a/src/puller.c b/src/puller.c
index 2fd37bc..959ac54 100644
--- a/src/puller.c
+++ b/src/puller.c
@@ -425,7 +425,7 @@ arc-line intersection was moved to.
 %end-doc */
 
 static int
-Puller (int argc, char **argv, int Ux, int Uy)
+Puller (int argc, char **argv, Coord Ux, Coord Uy)
 {
   double arc_angle, base_angle;
 #if TRACE1
@@ -2561,7 +2561,7 @@ trace_print_lines_arcs (void)
 #endif
 
 static int
-GlobalPuller(int argc, char **argv, int x, int y)
+GlobalPuller(int argc, char **argv, Coord x, Coord y)
 {
   int select_flags = 0;
 
diff --git a/src/report.c b/src/report.c
index e0ae113..dbcf776 100644
--- a/src/report.c
+++ b/src/report.c
@@ -56,7 +56,7 @@
 #define USER_UNITMASK (Settings.grid_unit->allow)
 
 static int
-ReportDrills (int argc, char **argv, int x, int y)
+ReportDrills (int argc, char **argv, Coord x, Coord y)
 {
   DrillInfoTypePtr AllDrills;
   Cardinal n;
@@ -118,7 +118,7 @@ This is a shortcut for @code{Report(Object)}.
 %end-doc */
 
 static int
-ReportDialog (int argc, char **argv, int x, int y)
+ReportDialog (int argc, char **argv, Coord x, Coord y)
 {
   void *ptr1, *ptr2, *ptr3;
   int type;
@@ -493,7 +493,7 @@ ReportDialog (int argc, char **argv, int x, int y)
 }
 
 static int
-ReportFoundPins (int argc, char **argv, int x, int y)
+ReportFoundPins (int argc, char **argv, Coord x, Coord y)
 {
   static DynamicStringType list;
   char temp[64];
@@ -534,7 +534,7 @@ ReportFoundPins (int argc, char **argv, int x, int y)
 }
 
 static double
-XYtoNetLength (int x, int y, int *found)
+XYtoNetLength (Coord x, Coord y, int *found)
 {
   double length;
 
@@ -574,7 +574,7 @@ XYtoNetLength (int x, int y, int *found)
 }
 
 static int
-ReportAllNetLengths (int argc, char **argv, int x, int y)
+ReportAllNetLengths (int argc, char **argv, Coord x, Coord y)
 {
   int ni;
   int found;
@@ -650,7 +650,7 @@ ReportAllNetLengths (int argc, char **argv, int x, int y)
 }
 
 static int
-ReportNetLength (int argc, char **argv, int x, int y)
+ReportNetLength (int argc, char **argv, Coord x, Coord y)
 {
   BDimension length = 0;
   char *netname = 0;
@@ -776,7 +776,7 @@ units
 %end-doc */
 
 static int
-Report (int argc, char **argv, int x, int y)
+Report (int argc, char **argv, Coord x, Coord y)
 {
   if (argc < 1)
     AUSAGE (report);
diff --git a/src/toporouter.c b/src/toporouter.c
index 3b52f24..e5310b0 100644
--- a/src/toporouter.c
+++ b/src/toporouter.c
@@ -7925,7 +7925,7 @@ toporouter_set_pair(toporouter_t *r, toporouter_netlist_t *n1, toporouter_netlis
 }
 
 static int 
-toporouter (int argc, char **argv, int x, int y)
+toporouter (int argc, char **argv, Coord x, Coord y)
 {
   toporouter_t *r = toporouter_new();
   parse_arguments(r, argc, argv);
@@ -7965,7 +7965,7 @@ toporouter (int argc, char **argv, int x, int y)
 }
 
 static int 
-escape (int argc, char **argv, int x, int y)
+escape (int argc, char **argv, Coord x, Coord y)
 {
   guint dir, viax, viay;
   gdouble pitch, length, dx, dy;
diff --git a/src/vendor.c b/src/vendor.c
index aa766bb..2abcca0 100644
--- a/src/vendor.c
+++ b/src/vendor.c
@@ -120,7 +120,7 @@ sizes for your vendor.
 %end-doc */
 
 int
-ActionApplyVendor (int argc, char **argv, int x, int y)
+ActionApplyVendor (int argc, char **argv, Coord x, Coord y)
 {
   hid_action ("Busy");
   apply_vendor_map ();
@@ -149,7 +149,7 @@ loaded first.
 %end-doc */
 
 int
-ActionToggleVendor (int argc, char **argv, int x, int y)
+ActionToggleVendor (int argc, char **argv, Coord x, Coord y)
 {
   if (vendorMapEnable)
     vendorMapEnable = false;
@@ -180,7 +180,7 @@ loaded first.
 %end-doc */
 
 int
-ActionEnableVendor (int argc, char **argv, int x, int y)
+ActionEnableVendor (int argc, char **argv, Coord x, Coord y)
 {
   vendorMapEnable = true;
   return 0;
@@ -206,7 +206,7 @@ specified in the currently loaded vendor drill table.
 %end-doc */
 
 int
-ActionDisableVendor (int argc, char **argv, int x, int y)
+ActionDisableVendor (int argc, char **argv, Coord x, Coord y)
 {
   vendorMapEnable = false;
   return 0;
@@ -228,7 +228,7 @@ static const char unload_vendor_help[] =
 %end-doc */
 
 int
-ActionUnloadVendor (int argc, char **argv, int x, int y)
+ActionUnloadVendor (int argc, char **argv, Coord x, Coord y)
 {
   cached_drill = -1;
 
@@ -266,7 +266,7 @@ be prompted to enter one.
 %end-doc */
 
 int
-ActionLoadVendorFrom (int argc, char **argv, int x, int y)
+ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y)
 {
   int i;
   char *fname = NULL;

commit 71ee8544e95d216e80871e154bd4dd8a7deef553
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce PCB::grid::unit attribute
    
    This is PCB's first use of the Attribute() field in the
    file format. It is a unit suffix string denoting the unit
    setting used by pcb when loading the file.
    
    Note the namespacing: as Attributes are persistent across
    file-saves, other programs may use them in future for
    purposes unknown and irrelevant to pcb. Therefore we will
    put all pcb attributes under the PCB namespace.
    
    If this attribute is missing or invalid (i.e., the unit
    given is unsupported by pcb-printf), PCB will then use the
    --grid-units command-line option. Failing that, it will
    use the grid-units entry in ~/.pcb/preferences. Failing
    that, it will use mils.
    
    Fixes-bug: lp-811393

diff --git a/src/file.c b/src/file.c
index e5eb93f..8f9bee5 100644
--- a/src/file.c
+++ b/src/file.c
@@ -392,6 +392,7 @@ set_some_route_style ()
 int
 LoadPCB (char *Filename)
 {
+  const char *unit_suffix;
   PCBTypePtr newPCB = CreateNewPCB (false);
   PCBTypePtr oldPCB;
 #ifdef DEBUG
@@ -437,13 +438,16 @@ LoadPCB (char *Filename)
       PCB->Filename = strdup (Filename);
       /* just in case a bad file saved file is loaded */
 
-      /* Use imperial if the grid is a multiple of .5cmil, else metric */
-      if ((1000000 * COORD_TO_MM (PCB->Grid) / 127.0) !=
-            (Coord) (1000000 * COORD_TO_MM (PCB->Grid)) / 127)
-        Settings.grid_unit = get_unit_struct ("mm");
-      else
-        Settings.grid_unit = get_unit_struct ("mil");
-
+      /* Use attribute PCB::grid::unit as unit, if we can */
+      unit_suffix = AttributeGet (PCB, "PCB::grid::unit");
+      if (unit_suffix && *unit_suffix)
+        {
+          const Unit *new_unit = get_unit_struct (unit_suffix);
+          if (new_unit)
+            Settings.grid_unit = new_unit;
+        }
+      AttributePut (PCB, "PCB::grid::unit", Settings.grid_unit->suffix);
+ 
       sort_netlist ();
 
       set_some_route_style ();
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index 7699cf9..a9c994e 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -1819,6 +1819,7 @@ SetUnits (int argc, char **argv, int x, int y)
     {
       Settings.grid_unit = new_unit;
       Settings.increments = get_increments_struct (Settings.grid_unit->suffix);
+      AttributePut (PCB, "PCB::grid::unit", argv[0]);
     }
 
   ghid_config_handle_units_changed ();
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 9108f2c..1c4d8b9 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -413,6 +413,7 @@ SetUnits (int argc, char **argv, int x, int y)
     {
       Settings.grid_unit = new_unit;
       Settings.increments = get_increments_struct (Settings.grid_unit->suffix);
+      AttributePut (PCB, "PCB::grid::unit", argv[0]);
     }
   lesstif_sizes_reset ();
   lesstif_styles_update_values ();

commit dc150b8b6b45d6db26d33ec07fe639b78d4e3980
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Modify get_unit_struct()'s bad-unit forgiveness
    
    Suffixes passed to get_unit_struct() may now start or end
    with whitespace, without affecting the result. However,
    incomplete units will NOT be matched.
    
    This means that "mi" will no longer return the "mil" struct,
    for example.
    
    The reasons for this change are:
      1. The old behavior returned the first potential match,
         regardless of other matches: "c" is always "cm", never
         "cmil".
      2. Prevent surprises (due to point #1, or typos).
      3. Prevent user dependence on behavior that will change
         as units are added or removed.
    
    It still supports plural units, like "inches" or "mils".
    However, it will read "miles" as "mil" because of this. ;)

diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 0203e32..7baffbb 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -136,18 +136,28 @@ static Increments increments[] = {
 #define N_INCREMENTS (sizeof increments / sizeof increments[0])
 
 /* Obtain a unit object from its (non-international) suffix */
-const Unit *get_unit_struct (const char *suffix)
+const Unit *get_unit_struct (const char *const_suffix)
 {
   int i;
-  int s_len = strlen (suffix);
+  int s_len = 0;
+  /* Turn given suffix into something we can modify... */
+  char *m_suffix = g_strdup (const_suffix);
+  /* ...and store this in a pointer we can move. */
+  char *suffix = m_suffix;
+
+  /* Determine bounds */
+  while (isspace (*suffix))
+    ++suffix;
+  while (isalnum (suffix[s_len]))
+    ++s_len;
 
   /* Also understand plural suffixes: "inches", "mils" */
   if (s_len > 2)
     {
       if (suffix[s_len - 2] == 'e' && suffix[s_len - 1] == 's')
-        s_len -= 2;
+        suffix[s_len - 2] = 0;
       else if (suffix[s_len - 1] == 's')
-        s_len -= 1;
+        suffix[s_len - 1] = 0;
     }
 
   /* Do lookup */
@@ -155,7 +165,11 @@ const Unit *get_unit_struct (const char *suffix)
     for (i = 0; i < N_UNITS; ++i)
       if (strcmp (suffix, Units[i].suffix) == 0 ||
           strcmp (suffix, Units[i].alias[0]) == 0)
-        return &Units[i];
+        {
+          g_free (m_suffix);
+          return &Units[i];
+        }
+  g_free (m_suffix);
   return NULL;
 }
 

commit 59d0f4e4813b91dd0ff514a0e7897182f5b35ff9
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add alias support, get_unit_list() to pcb-printf
    
    Add pcb-printf support for unit aliases (just one per unit
    for now, we will fix this if the need arises). Map "inch"
    to "in" and "pcb" to "cmil" for backward compatibility.
    
    Move initialize_units() call to main.c to ensure it is called
    before any other unit-handling code.
    
    Also, add the functions
      get_unit_list ();
      get_n_units ();
    which do exactly what they look like. These will be used
    to build HID-export unit selectors.

diff --git a/src/main.c b/src/main.c
index d007f87..8d6509a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -908,6 +908,7 @@ main (int argc, char *argv[])
 
   srand ( time(NULL) ); /* Set seed for rand() */
 
+  initialize_units();
   polygon_init ();
   hid_init ();
 
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 82c9492..0203e32 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -43,40 +43,47 @@
 /* These should be kept in order of smallest scale_factor
  * to largest -- the code uses this ordering when finding
  * the best scale to use for a group of measures */
-static Unit *Units;
-static int n_units;
+static Unit Units[] = {
+  { 0, "km", NULL, 'k', 0.000001, METRIC, ALLOW_KM, 5,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+  { 0, "m",  NULL, 'f', 0.001,    METRIC, ALLOW_M,  5,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+  { 0, "cm", NULL, 'e', 0.1,      METRIC, ALLOW_CM, 5,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+  { 0, "mm", NULL, 'm', 1,        METRIC, ALLOW_MM, 4,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+  { 0, "um", NULL, 'u', 1000,     METRIC, ALLOW_UM, 2,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+  { 0, "nm", NULL, 'n', 1000000,  METRIC, ALLOW_NM, 0,
+             MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0),
+             { "" } },
+
+  { 0, "in",   NULL, 'i', 0.001, IMPERIAL, ALLOW_IN,   5,
+               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               { "inch" } },
+  { 0, "mil",  NULL, 'l', 1,     IMPERIAL, ALLOW_MIL,  2,
+               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               { "" } },
+  { 0, "cmil", NULL, 'c', 100,   IMPERIAL, ALLOW_CMIL, 0,
+               MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0),
+               { "pcb" } }
+};
+#define N_UNITS ((int) (sizeof Units / sizeof Units[0]))
 /* The function is needed to avoid "non-constant initializer"
  *  errors on the internationalized unit suffixes. */
 void initialize_units()
 {
   int i;
-  static Unit rv[] = {
-    { "km", NULL, 'k', 0.000001, METRIC, ALLOW_KM, 5,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-    { "m",  NULL, 'f', 0.001,    METRIC, ALLOW_M,  5,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-    { "cm", NULL, 'e', 0.1,      METRIC, ALLOW_CM, 5,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-    { "mm", NULL, 'm', 1,        METRIC, ALLOW_MM, 4,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-    { "um", NULL, 'u', 1000,     METRIC, ALLOW_UM, 2,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-    { "nm", NULL, 'n', 1000000,  METRIC, ALLOW_NM, 0,
-            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
-
-    { "in",   NULL, 'i', 0.001, IMPERIAL, ALLOW_IN,   5,
-              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
-    { "inch", NULL,  0 , 0.001, IMPERIAL, NO_PRINT,   0,
-              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
-    { "mil",  NULL, 'l', 1,     IMPERIAL, ALLOW_MIL,  2,
-              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
-    { "cmil", NULL, 'c', 100,   IMPERIAL, ALLOW_CMIL, 0,
-              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) }
-  };
-  n_units = (sizeof rv / sizeof rv[0]);
-  for (i = 0; i < n_units; ++i)
-    rv[i].in_suffix = _(rv[i].suffix);
-  Units = rv;
+  for (i = 0; i < N_UNITS; ++i)
+    {
+      Units[i].index = i;
+      Units[i].in_suffix = _(Units[i].suffix);
+    }
 }
 /* This list -must- contain all printable units from the above list */
 /* For now I have just copy/pasted the same values for all metric
@@ -134,8 +141,6 @@ const Unit *get_unit_struct (const char *suffix)
   int i;
   int s_len = strlen (suffix);
 
-  if (Units == NULL) initialize_units();
-
   /* Also understand plural suffixes: "inches", "mils" */
   if (s_len > 2)
     {
@@ -146,12 +151,24 @@ const Unit *get_unit_struct (const char *suffix)
     }
 
   /* Do lookup */
-  for (i = 0; i < n_units; ++i)
-    if (strncmp (suffix, Units[i].suffix, s_len) == 0)
-      return &Units[i];
+  if (*suffix)
+    for (i = 0; i < N_UNITS; ++i)
+      if (strcmp (suffix, Units[i].suffix) == 0 ||
+          strcmp (suffix, Units[i].alias[0]) == 0)
+        return &Units[i];
   return NULL;
 }
 
+/* ACCESSORS */
+const Unit *get_unit_list (void)
+{
+	return Units;
+}
+int get_n_units (void)
+{
+	return N_UNITS;
+}
+
 /* Obtain a increment object from its (non-international) suffix */
 Increments *get_increments_struct (const char *suffix)
 {
@@ -210,8 +227,6 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
   const char *suffix;
   int i, n;
 
-  if (Units == NULL) initialize_units();
-
   value = malloc (n_coords * sizeof *value);
   buff  = g_string_new ("");
 
@@ -257,7 +272,7 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
 
   /* Determine scale factor -- find smallest unit that brings
    * the whole group above unity */
-  for (n = 0; n < n_units; ++n)
+  for (n = 0; n < N_UNITS; ++n)
     {
       if ((Units[n].allow & allow) != 0 && (Units[n].family == family))
         {
@@ -271,7 +286,7 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
         }
     }
   /* If nothing worked, wind back to the smallest allowable unit */
-  if (n == n_units)
+  if (n == N_UNITS)
     {
       do {
         --n;
@@ -349,8 +364,6 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
   if (string == NULL || spec == NULL)
     return NULL;
 
-  if (Units == NULL) initialize_units();
-
   while(*fmt)
     {
       enum e_suffix suffix = NO_SUFFIX;
@@ -479,7 +492,7 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
                   unit_str = CoordsToString(value, 2, spec->str, ALLOW_MM | ALLOW_MIL, suffix);
                   break;
                 case '*':
-                  for (i = 0; i < n_units; ++i)
+                  for (i = 0; i < N_UNITS; ++i)
                     if (strcmp (ext_unit, Units[i].suffix) == 0)
                       unit_str = CoordsToString(value, 1, spec->str, Units[i].allow, suffix);
                   if (unit_str == NULL)
@@ -495,7 +508,7 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
                   mask = va_arg(args, enum e_allow);
                   break;
                 default:
-                  for (i = 0; i < n_units; ++i)
+                  for (i = 0; i < N_UNITS; ++i)
                     if (*fmt == Units[i].printf_code)
                       unit_str = CoordsToString(value, 1, spec->str, Units[i].allow, suffix);
                   if (unit_str == NULL)
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index 07cd80a..6534945 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -99,6 +99,7 @@ enum e_family { METRIC, IMPERIAL };
 enum e_suffix { NO_SUFFIX, SUFFIX, FILE_MODE };
 
 struct unit {
+  int index;			/* Index into Unit[] list */
   const char *suffix;
   const char *in_suffix;	/* internationalized suffix */
   char printf_code;
@@ -112,6 +113,8 @@ struct unit {
   Coord step_medium;
   Coord step_large;
   Coord step_huge;
+  /* aliases -- right now we only need 1 ("inch"->"in"), add as needed */
+  const char *alias[1];
 };
 
 struct increments {
@@ -134,7 +137,11 @@ struct increments {
   Coord clear_max;
 };
 
+void initialize_units();
+
 const Unit *get_unit_struct (const char *suffix);
+const Unit *get_unit_list (void);
+int get_n_units (void);
 double coord_to_unit (const Unit *, Coord);
 Coord  unit_to_coord (const Unit *, double);
 Increments *get_increments_struct (const char *suffix);

commit 9b95139e8eac7755349d05c36e7e3d3ca61d23d1
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Use suffixed units in gpcb-menu.res and pcb-menu.res

diff --git a/src/gpcb-menu.res.in b/src/gpcb-menu.res.in
index bb5b8bf..7449d50 100644
--- a/src/gpcb-menu.res.in
+++ b/src/gpcb-menu.res.in
@@ -121,22 +121,22 @@ MainMenu =
     {"mm"  checked=grid_units_mm SetUnits(mm)}
    }
    {"Grid size"
-    {"No Grid" checked=gridsize,1 SetValue(Grid,1)}
+    {"No Grid" checked=grid,0 SetValue(Grid,1)}
     -
-    {  "0.1 mil" checked=gridsize,10 SetUnits(mil) SetValue(Grid,10)}
-    {  "1 mil"   checked=gridsize,100 SetUnits(mil) SetValue(Grid,100)}
-    {  "5 mil"   checked=gridsize,500 SetUnits(mil) SetValue(Grid,500)}
-    { "10 mil"   checked=gridsize,1000 SetUnits(mil) SetValue(Grid,1000)}
-    { "25 mil"   checked=gridsize,2500 SetUnits(mil) SetValue(Grid,2500)}
-    { "50 mil"   checked=gridsize,5000 SetUnits(mil) SetValue(Grid,5000)}
-    {"100 mil"   checked=gridsize,10000 SetUnits(mil) SetValue(Grid,10000)}
+    {  "0.1 mil" checked=gridsize,0.1mil SetUnits(mil) SetValue(Grid,0.1mil)}
+    {  "1 mil"   checked=gridsize,1mil SetUnits(mil) SetValue(Grid,1mil)}
+    {  "5 mil"   checked=gridsize,5mil SetUnits(mil) SetValue(Grid,5mil)}
+    { "10 mil"   checked=gridsize,10mil SetUnits(mil) SetValue(Grid,10mil)}
+    { "25 mil"   checked=gridsize,25mil SetUnits(mil) SetValue(Grid,25mil)}
+    { "50 mil"   checked=gridsize,50mil SetUnits(mil) SetValue(Grid,50mil)}
+    {"100 mil"   checked=gridsize,100mil SetUnits(mil) SetValue(Grid,100mil)}
     -
-    {"0.01 mm" checked=gridsize,39 SetUnits(mm) SetValue(Grid,0.01mm)}
-    {"0.05 mm" checked=gridsize,197 SetUnits(mm) SetValue(Grid,0.05mm)}
-    {"0.1 mm"  checked=gridsize,394 SetUnits(mm) SetValue(Grid,0.1mm)}
-    {"0.25 mm" checked=gridsize,984 SetUnits(mm) SetValue(Grid,0.25mm)}
-    {"0.5 mm"  checked=gridsize,1969 SetUnits(mm) SetValue(Grid,0.5mm)}
-    {"1 mm"    checked=gridsize,3937 SetUnits(mm) SetValue(Grid,1mm)}
+    {"0.01 mm" checked=gridsize,0.01mm SetUnits(mm) SetValue(Grid,0.01mm)}
+    {"0.05 mm" checked=gridsize,0.05mm SetUnits(mm) SetValue(Grid,0.05mm)}
+    {"0.1 mm"  checked=gridsize,0.10mm SetUnits(mm) SetValue(Grid,0.1mm)}
+    {"0.25 mm" checked=gridsize,0.25mm SetUnits(mm) SetValue(Grid,0.25mm)}
+    {"0.5 mm"  checked=gridsize,0.50mm SetUnits(mm) SetValue(Grid,0.5mm)}
+    {"1 mm"    checked=gridsize,1mm SetUnits(mm) SetValue(Grid,1mm)}
     -
     {"Grid -5mil" SetValue(Grid,-5,mil) a={"Shift-G" "Shift<Key>g"}}
     {"Grid +5mil" SetValue(Grid,+5,mil) a={"G" "<Key>g"}}
@@ -159,13 +159,13 @@ MainMenu =
     {"Zoom Max" Zoom() m=M a={"V" "<Key>v"}}
     {"Zoom In 2X" Zoom(-2)}
     {"Zoom Out 2X" Zoom(+2)}
-    {"Zoom to 0.1mil/px" Zoom(=10)}
-    {"Zoom to 0.01mm/px" Zoom(=39.37)}
-    {"Zoom to 1mil/px" Zoom(=100)}
-    {"Zoom to 0.05mm/px" Zoom(=196.8504)}
-    {"Zoom to 2.5mil/px" Zoom(=250)}
-    {"Zoom to 0.1mm/px" Zoom(=393.7)}
-    {"Zoom to 10mil/px" Zoom(=1000)}
+    {"Zoom to 0.1mil/px" Zoom(=0.1mil)}
+    {"Zoom to 0.01mm/px" Zoom(=0.01mm)}
+    {"Zoom to 1mil/px" Zoom(=1mil)}
+    {"Zoom to 0.05mm/px" Zoom(=0.05mm)}
+    {"Zoom to 2.5mil/px" Zoom(=2.5mil)}
+    {"Zoom to 0.1mm/px" Zoom(=0.1mm)}
+    {"Zoom to 10mil/px" Zoom(=10mil)}
     {"Zoom In 20% and center" Zoom(-1.2) Center() m=Z }
     {"Zoom Out 20% and center" Zoom(+1.2) Center() m=O }
     {"Flip up/down" checked=flip_y SwapSides(V) a={"Tab" "<Key>Tab"}}
diff --git a/src/pcb-menu.res.in b/src/pcb-menu.res.in
index 22847e9..fc3008a 100644
--- a/src/pcb-menu.res.in
+++ b/src/pcb-menu.res.in
@@ -81,35 +81,35 @@ MainMenu =
     {"Zoom Max" Zoom() m=M a={"V" "<Key>v"}}
     {"Zoom Toggle" Zoom(Toggle) a={"`" "<Key>`"}}
     -
-    {"Zoom to 0.1mil/px" Zoom(=10)}
-    {"Zoom to 0.01mm/px" Zoom(=39.37)}
-    {"Zoom to 1mil/px" Zoom(=100)}
-    {"Zoom to 0.05mm/px" Zoom(=196.8504)}
-    {"Zoom to 2.5mil/px" Zoom(=250)}
-    {"Zoom to 0.1mm/px" Zoom(=393.7)}
-    {"Zoom to 10mil/px" Zoom(=1000)}
+    {"Zoom to 0.1mil/px" Zoom(=0.1mil)}
+    {"Zoom to 0.01mm/px" Zoom(=0.01mil)}
+    {"Zoom to 1mil/px" Zoom(=1mil)}
+    {"Zoom to 0.05mm/px" Zoom(=0.05mm)}
+    {"Zoom to 2.5mil/px" Zoom(=2.5mil)}
+    {"Zoom to 0.1mm/px" Zoom(=0.1mm)}
+    {"Zoom to 10mil/px" Zoom(=10mil)}
    }
    {Grid
     {"mil" checked=grid_units_mil SetUnits(mil)}
     {"mm"  checked=grid_units_mm SetUnits(mm)}
     {"Display grid" checked=drawgrid Display(Grid)}
     {"Realign grid" GetXY(Click to set the grid origin) Display(ToggleGrid)}
-    {"No Grid" checked=gridsize,1 SetValue(Grid,1)}
+    {"No Grid" checked=grid,0 SetValue(Grid,1)}
     -
-    {  "0.1 mil" checked=gridsize,10 SetUnits(mil) SetValue(Grid,10)}
-    {  "1 mil"   checked=gridsize,100 SetUnits(mil) SetValue(Grid,100)}
-    {  "5 mil"   checked=gridsize,500 SetUnits(mil) SetValue(Grid,500)}
-    { "10 mil"   checked=gridsize,1000 SetUnits(mil) SetValue(Grid,1000)}
-    { "25 mil"   checked=gridsize,2500 SetUnits(mil) SetValue(Grid,2500)}
-    { "50 mil"   checked=gridsize,5000 SetUnits(mil) SetValue(Grid,5000)}
-    {"100 mil"   checked=gridsize,10000 SetUnits(mil) SetValue(Grid,10000)}
+    {  "0.1 mil" checked=gridsize,0.1mil SetUnits(mil) SetValue(Grid,0.1mil)}
+    {  "1 mil"   checked=gridsize,1mil SetUnits(mil) SetValue(Grid,1mil)}
+    {  "5 mil"   checked=gridsize,5mil SetUnits(mil) SetValue(Grid,5mil)}
+    { "10 mil"   checked=gridsize,10mil SetUnits(mil) SetValue(Grid,10mil)}
+    { "25 mil"   checked=gridsize,25mil SetUnits(mil) SetValue(Grid,25mil)}
+    { "50 mil"   checked=gridsize,50mil SetUnits(mil) SetValue(Grid,50mil)}
+    {"100 mil"   checked=gridsize,100mil SetUnits(mil) SetValue(Grid,100mil)}
     -
-    {"0.01 mm" checked=gridsize,39 SetUnits(mm) SetValue(Grid,0.01mm)}
-    {"0.05 mm" checked=gridsize,197 SetUnits(mm) SetValue(Grid,0.05mm)}
-    {"0.1 mm"  checked=gridsize,394 SetUnits(mm) SetValue(Grid,0.1mm)}
-    {"0.25 mm" checked=gridsize,984 SetUnits(mm) SetValue(Grid,0.25mm)}
-    {"0.5 mm"  checked=gridsize,1969 SetUnits(mm) SetValue(Grid,0.5mm)}
-    {"1 mm"    checked=gridsize,3937 SetUnits(mm) SetValue(Grid,1mm)}
+    {"0.01 mm" checked=gridsize,0.01mm SetUnits(mm) SetValue(Grid,0.01mm)}
+    {"0.05 mm" checked=gridsize,0.05mm SetUnits(mm) SetValue(Grid,0.05mm)}
+    {"0.1 mm"  checked=gridsize,0.10mm SetUnits(mm) SetValue(Grid,0.1mm)}
+    {"0.25 mm" checked=gridsize,0.25mm SetUnits(mm) SetValue(Grid,0.25mm)}
+    {"0.5 mm"  checked=gridsize,0.50mm SetUnits(mm) SetValue(Grid,0.5mm)}
+    {"1 mm"    checked=gridsize,1mm SetUnits(mm) SetValue(Grid,1mm)}
     -
     {"Grid -5mil" SetValue(Grid,-5,mil) a={"Shift-G" "Shift<Key>g"}}
     {"Grid +5mil" SetValue(Grid,+5,mil) a={"G" "<Key>g"}}

commit b0951b40055c914c8717322b20478f3f68e99814
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Make file.c use %mr pcb-printf spec
    
    I have changed the %mr spec to always output cmils,
    no suffix, and changed file.c to use this. The reason
    is that the %mc spec (cmils, no suffix) is locale-
    dependent, while %mr is not.
    
    When we change the actual file format, file.c can be
    left alone and the relevant changes should be done to
    the %mr spec in pcb-printf.

diff --git a/src/buffer.c b/src/buffer.c
index 6ff6132..0943f1a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -458,8 +458,7 @@ ClearBuffer (BufferTypePtr Buffer)
  * returns true if any objects have been removed
  */
 void
-AddSelectedToBuffer (BufferTypePtr Buffer, LocationType X, LocationType Y,
-		     bool LeaveSelected)
+AddSelectedToBuffer (BufferTypePtr Buffer, Coord X, Coord Y, bool LeaveSelected)
 {
   /* switch crosshair off because adding objects to the pastebuffer
    * may change the 'valid' area for the cursor
@@ -1071,7 +1070,7 @@ ConvertBufferToElement (BufferTypePtr Buffer)
 	END_LOOP;
 	POLYGON_LOOP (layer);
 	{
-	  int x1, y1, x2, y2, w, h, t;
+	  Coord x1, y1, x2, y2, w, h, t;
 
 	  if (! polygon_is_rectangle (polygon))
 	    {
@@ -1234,11 +1233,11 @@ RotateBuffer (BufferTypePtr Buffer, BYTE Number)
 }
 
 static void
-free_rotate (int *x, int *y, int cx, int cy, double cosa, double sina)
+free_rotate (Coord *x, Coord *y, Coord cx, Coord cy, double cosa, double sina)
 {
   double nx, ny;
-  int px = *x - cx;
-  int py = *y - cy;
+  Coord px = *x - cx;
+  Coord py = *y - cy;
 
   nx = px * cosa + py * sina;
   ny = py * cosa - px * sina;
@@ -1249,8 +1248,8 @@ free_rotate (int *x, int *y, int cx, int cy, double cosa, double sina)
 
 void
 FreeRotateElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
-			   LocationType X, LocationType Y,
-			   double cosa, double sina, double Angle)
+			   Coord X, Coord Y,
+			   double cosa, double sina, Angle angle)
 {
   /* solder side objects need a different orientation */
 
@@ -1297,8 +1296,7 @@ FreeRotateElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
   ARC_LOOP (Element);
   {
     free_rotate (&arc->X, &arc->Y, X, Y, cosa, sina);
-    arc->StartAngle += Angle;
-    arc->StartAngle %= 360;
+    arc->StartAngle = NormalizeAngle (arc->StartAngle + angle);
   }
   END_LOOP;
 
@@ -1308,12 +1306,12 @@ FreeRotateElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
 }
 
 void
-FreeRotateBuffer (BufferTypePtr Buffer, double Angle)
+FreeRotateBuffer (BufferTypePtr Buffer, Angle angle)
 {
   double cosa, sina;
 
-  cosa = cos(Angle * M_PI/180.0);
-  sina = sin(Angle * M_PI/180.0);
+  cosa = cos(angle * M_PI/180.0);
+  sina = sin(angle * M_PI/180.0);
 
   /* rotate vias */
   VIA_LOOP (Buffer->Data);
@@ -1329,7 +1327,7 @@ FreeRotateBuffer (BufferTypePtr Buffer, double Angle)
   ELEMENT_LOOP (Buffer->Data);
   {
     FreeRotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y,
-			       cosa, sina, Angle);
+			       cosa, sina, angle);
   }
   END_LOOP;
 
@@ -1347,8 +1345,7 @@ FreeRotateBuffer (BufferTypePtr Buffer, double Angle)
   {
     r_delete_entry (layer->arc_tree, (BoxType *)arc);
     free_rotate (&arc->X, &arc->Y, Buffer->X, Buffer->Y, cosa, sina);
-    arc->StartAngle += Angle;
-    arc->StartAngle %= 360;
+    arc->StartAngle = NormalizeAngle (arc->StartAngle + angle);
     r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
   }
   ENDALL_LOOP;
diff --git a/src/buffer.h b/src/buffer.h
index 7182a9d..2ff9496 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -38,7 +38,7 @@
  */
 void SetBufferBoundingBox (BufferTypePtr);
 void ClearBuffer (BufferTypePtr);
-void AddSelectedToBuffer (BufferTypePtr, LocationType, LocationType, bool);
+void AddSelectedToBuffer (BufferTypePtr, Coord, Coord, bool);
 bool LoadElementToBuffer (BufferTypePtr, char *, bool);
 bool ConvertBufferToElement (BufferTypePtr);
 bool SmashBufferElement (BufferTypePtr);
diff --git a/src/create.c b/src/create.c
index cd31935..b5081fa 100644
--- a/src/create.c
+++ b/src/create.c
@@ -533,7 +533,7 @@ CreateNewArcOnLayer (LayerTypePtr Layer,
   ARC_LOOP (Layer);
   {
     if (arc->X == X1 && arc->Y == Y1 && arc->Width == width &&
-	(arc->StartAngle + 360) % 360 == (sa + 360) % 360 &&
+	NormalizeAngle (arc->StartAngle) == NormalizeAngle (sa) &&
 	arc->Delta == dir)
       return (NULL);		/* prevent stacked arcs */
   }
diff --git a/src/file.c b/src/file.c
index b7349bb..e5eb93f 100644
--- a/src/file.c
+++ b/src/file.c
@@ -575,26 +575,24 @@ WritePCBDataHeader (FILE * FP)
 
   fputs ("\nPCB[", FP);
   PrintQuotedString (FP, (char *)EMPTY (PCB->Name));
-  pcb_fprintf (FP, " %mc %mc]\n\n", PCB->MaxWidth, PCB->MaxHeight);
-  pcb_fprintf (FP, "Grid[%s %mc %mc %d]\n",
-	       c_dtostr (COORD_TO_MIL(PCB->Grid) * 100), PCB->GridOffsetX,
-	       PCB->GridOffsetY, Settings.DrawGrid);
-  pcb_fprintf (FP, "Cursor[%mc %mc %s]\n",
+  pcb_fprintf (FP, " %mr %mr]\n\n", PCB->MaxWidth, PCB->MaxHeight);
+  pcb_fprintf (FP, "Grid[%.1mr %mr %mr %d]\n", PCB->Grid, PCB->GridOffsetX, PCB->GridOffsetY, Settings.DrawGrid);
+  pcb_fprintf (FP, "Cursor[%mr %mr %s]\n",
                Crosshair.X, Crosshair.Y, c_dtostr (PCB->Zoom));
   /* PolyArea should be output in square cmils, no suffix */
   fprintf (FP, "PolyArea[%s]\n", c_dtostr (COORD_TO_MIL (COORD_TO_MIL (PCB->IsleArea) * 100) * 100));
   pcb_fprintf (FP, "Thermal[%s]\n", c_dtostr (PCB->ThermScale));
-  pcb_fprintf (FP, "DRC[%mc %mc %mc %mc %mc %mc]\n", PCB->Bloat, PCB->Shrink,
+  pcb_fprintf (FP, "DRC[%mr %mr %mr %mr %mr %mr]\n", PCB->Bloat, PCB->Shrink,
 	       PCB->minWid, PCB->minSlk, PCB->minDrill, PCB->minRing);
   fprintf (FP, "Flags(%s)\n", pcbflags_to_string(PCB->Flags));
   fprintf (FP, "Groups(\"%s\")\n", LayerGroupsToString (&PCB->LayerGroups));
   fputs ("Styles[\"", FP);
   for (group = 0; group < NUM_STYLES - 1; group++)
-    pcb_fprintf (FP, "%s,%mc,%mc,%mc,%mc:", PCB->RouteStyle[group].Name,
+    pcb_fprintf (FP, "%s,%mr,%mr,%mr,%mr:", PCB->RouteStyle[group].Name,
 	         PCB->RouteStyle[group].Thick,
 	         PCB->RouteStyle[group].Diameter,
 	         PCB->RouteStyle[group].Hole, PCB->RouteStyle[group].Keepaway);
-  pcb_fprintf (FP, "%s,%mc,%mc,%mc,%mc\"]\n\n", PCB->RouteStyle[group].Name,
+  pcb_fprintf (FP, "%s,%mr,%mr,%mr,%mr\"]\n\n", PCB->RouteStyle[group].Name,
 	       PCB->RouteStyle[group].Thick,
 	       PCB->RouteStyle[group].Diameter,
 	       PCB->RouteStyle[group].Hole, PCB->RouteStyle[group].Keepaway);
@@ -616,13 +614,13 @@ WritePCBFontData (FILE * FP)
 	continue;
 
       if (isprint (i))
-	pcb_fprintf (FP, "Symbol['%c' %mc]\n(\n", i, font->Symbol[i].Delta);
+	pcb_fprintf (FP, "Symbol['%c' %mr]\n(\n", i, font->Symbol[i].Delta);
       else
-	pcb_fprintf (FP, "Symbol[%i %mc]\n(\n", i, font->Symbol[i].Delta);
+	pcb_fprintf (FP, "Symbol[%i %mr]\n(\n", i, font->Symbol[i].Delta);
 
       line = font->Symbol[i].Line;
       for (j = font->Symbol[i].LineN; j; j--, line++)
-        pcb_fprintf (FP, "\tSymbolLine[%mc %mc %mc %mc %mc]\n",
+        pcb_fprintf (FP, "\tSymbolLine[%mr %mr %mr %mr %mr]\n",
                      line->Point1.X, line->Point1.Y,
                      line->Point2.X, line->Point2.Y, line->Thickness);
       fputs (")\n", FP);
@@ -640,7 +638,7 @@ WriteViaData (FILE * FP, DataTypePtr Data)
   for (iter = Data->Via; iter != NULL; iter = g_list_next (iter))
     {
       PinType *via = iter->data;
-      pcb_fprintf (FP, "Via[%mc %mc %mc %mc %mc %mc ", via->X, via->Y,
+      pcb_fprintf (FP, "Via[%mr %mr %mr %mr %mr %mr ", via->X, via->Y,
                    via->Thickness, via->Clearance, via->Mask, via->DrillingHole);
       PrintQuotedString (FP, (char *)EMPTY (via->Name));
       fprintf (FP, " %s]\n", F2S (via, VIA_TYPE));
@@ -658,7 +656,7 @@ WritePCBRatData (FILE * FP)
   for (iter = PCB->Data->Rat; iter != NULL; iter = g_list_next (iter))
     {
       RatType *line = iter->data;
-      pcb_fprintf (FP, "Rat[%mc %mc %d %mc %mc %d ",
+      pcb_fprintf (FP, "Rat[%mr %mr %d %mr %mr %d ",
                    line->Point1.X, line->Point1.Y, line->group1,
                    line->Point2.X, line->Point2.Y, line->group2);
       fprintf (FP, " %s]\n", F2S (line, RATLINE_TYPE));
@@ -722,7 +720,7 @@ WriteElementData (FILE * FP, DataTypePtr Data)
       PrintQuotedString (FP, (char *)EMPTY (NAMEONPCB_NAME (element)));
       fputc (' ', FP);
       PrintQuotedString (FP, (char *)EMPTY (VALUE_NAME (element)));
-      pcb_fprintf (FP, " %mc %mc %mc %mc %d %d %s]\n(\n",
+      pcb_fprintf (FP, " %mr %mr %mr %mr %d %d %s]\n(\n",
                    element->MarkX, element->MarkY,
                    DESCRIPTION_TEXT (element).X - element->MarkX,
                    DESCRIPTION_TEXT (element).Y - element->MarkY,
@@ -733,7 +731,7 @@ WriteElementData (FILE * FP, DataTypePtr Data)
       for (p = element->Pin; p != NULL; p = g_list_next (p))
 	{
 	  PinType *pin = p->data;
-          pcb_fprintf (FP, "\tPin[%mc %mc %mc %mc %mc %mc ",
+          pcb_fprintf (FP, "\tPin[%mr %mr %mr %mr %mr %mr ",
                        pin->X - element->MarkX,
                        pin->Y - element->MarkY,
                        pin->Thickness, pin->Clearance,
@@ -746,7 +744,7 @@ WriteElementData (FILE * FP, DataTypePtr Data)
       for (p = element->Pad; p != NULL; p = g_list_next (p))
 	{
 	  PadType *pad = p->data;
-          pcb_fprintf (FP, "\tPad[%mc %mc %mc %mc %mc %mc %mc ",
+          pcb_fprintf (FP, "\tPad[%mr %mr %mr %mr %mr %mr %mr ",
                        pad->Point1.X - element->MarkX,
                        pad->Point1.Y - element->MarkY,
                        pad->Point2.X - element->MarkX,
@@ -760,7 +758,7 @@ WriteElementData (FILE * FP, DataTypePtr Data)
       for (p = element->Line; p != NULL; p = g_list_next (p))
 	{
 	  LineType *line = p->data;
-          pcb_fprintf (FP, "\tElementLine [%mc %mc %mc %mc %mc]\n",
+          pcb_fprintf (FP, "\tElementLine [%mr %mr %mr %mr %mr]\n",
                        line->Point1.X - element->MarkX,
                        line->Point1.Y - element->MarkY,
                        line->Point2.X - element->MarkX,
@@ -770,7 +768,7 @@ WriteElementData (FILE * FP, DataTypePtr Data)
       for (p = element->Arc; p != NULL; p = g_list_next (p))
 	{
 	  ArcType *arc = p->data;
-          pcb_fprintf (FP, "\tElementArc [%mc %mc %mc %mc %ma %ma %mc]\n",
+          pcb_fprintf (FP, "\tElementArc [%mr %mr %mr %mr %ma %ma %mr]\n",
                        arc->X - element->MarkX,
                        arc->Y - element->MarkY,
                        arc->Width, arc->Height,
@@ -800,7 +798,7 @@ WriteLayerData (FILE * FP, Cardinal Number, LayerTypePtr layer)
       for (n = layer->Line; n != NULL; n = g_list_next (n))
 	{
 	  LineType *line = n->data;
-          pcb_fprintf (FP, "\tLine[%mc %mc %mc %mc %mc %mc %s]\n",
+          pcb_fprintf (FP, "\tLine[%mr %mr %mr %mr %mr %mr %s]\n",
                        line->Point1.X, line->Point1.Y,
                        line->Point2.X, line->Point2.Y,
                        line->Thickness, line->Clearance,
@@ -809,7 +807,7 @@ WriteLayerData (FILE * FP, Cardinal Number, LayerTypePtr layer)
       for (n = layer->Arc; n != NULL; n = g_list_next (n))
 	{
 	  ArcType *arc = n->data;
-          pcb_fprintf (FP, "\tArc[%mc %mc %mc %mc %mc %mc %ma %ma %s]\n",
+          pcb_fprintf (FP, "\tArc[%mr %mr %mr %mr %mr %mr %ma %ma %s]\n",
                        arc->X, arc->Y, arc->Width,
                        arc->Height, arc->Thickness,
                        arc->Clearance, arc->StartAngle,
@@ -818,7 +816,7 @@ WriteLayerData (FILE * FP, Cardinal Number, LayerTypePtr layer)
       for (n = layer->Text; n != NULL; n = g_list_next (n))
 	{
 	  TextType *text = n->data;
-          pcb_fprintf (FP, "\tText[%mc %mc %d %d ",
+          pcb_fprintf (FP, "\tText[%mr %mr %d %d ",
                        text->X, text->Y,
                        text->Direction, text->Scale);
 	  PrintQuotedString (FP, (char *)EMPTY (text->TextString));
@@ -850,7 +848,7 @@ WriteLayerData (FILE * FP, Cardinal Number, LayerTypePtr layer)
 		  if (hole)
 		    fputs ("\t", FP);
 		}
-              pcb_fprintf (FP, "[%mc %mc] ", point->X, point->Y);
+              pcb_fprintf (FP, "[%mr %mr] ", point->X, point->Y);
 	    }
 	  if (hole > 0)
 	    fputs ("\n\t\t)", FP);
diff --git a/src/global.h b/src/global.h
index ec388a9..477798b 100644
--- a/src/global.h
+++ b/src/global.h
@@ -88,7 +88,7 @@ typedef struct increments Increments;
 
 
 typedef int Coord;		/* pcb base unit */
-typedef int Angle;		/* degrees */
+typedef double Angle;		/* degrees */
 
 #if 1
 typedef int LocationType;
diff --git a/src/misc.c b/src/misc.c
index 83e2bb7..8db434a 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -116,6 +116,17 @@ Distance (double x1, double y1, double x2, double y2)
   return sqrt(delta_x * delta_x + delta_y * delta_y);
 }
 
+/* Bring an angle into [0, 360) range */
+Angle
+NormalizeAngle (Angle a)
+{
+  while (a < 0)
+    a += 360.0;
+  while (a >= 360.0)
+    a -= 360.0;
+  return a;
+}
+
 /* Get Value returns a numeric value passed from the string and sets the
  * bool variable absolute to false if it leads with a +/- character
  */
diff --git a/src/misc.h b/src/misc.h
index 2f2ccec..21fec7e 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -44,6 +44,7 @@ typedef struct {
 } UnitList[];
 
 double Distance (double x1, double y1, double x2, double y2);
+Angle  NormalizeAngle (Angle a);
 
 void r_delete_element (DataTypePtr, ElementTypePtr);
 void SetLineBoundingBox (LineTypePtr);
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 895ae12..82c9492 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -456,7 +456,11 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
                 case 'S': unit_str = CoordsToString(value, 1, spec->str, mask & ALLOW_ALL, suffix); break;
                 case 'M': unit_str = CoordsToString(value, 1, spec->str, mask & ALLOW_METRIC, suffix); break;
                 case 'L': unit_str = CoordsToString(value, 1, spec->str, mask & ALLOW_IMPERIAL, suffix); break;
+#if 0
                 case 'r': unit_str = CoordsToString(value, 1, spec->str, ALLOW_READABLE, FILE_MODE); break;
+#else
+                case 'r': unit_str = CoordsToString(value, 1, spec->str, ALLOW_READABLE, NO_SUFFIX); break;
+#endif
                 /* All these fallthroughs are deliberate */
                 case '9': value[count++] = va_arg(args, Coord);
                 case '8': value[count++] = va_arg(args, Coord);
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index 65c9e5a..07cd80a 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -52,6 +52,7 @@
  *          units
  *   %mr    output a measure in a unit readable by parse_l.l
  *          (this will always append a unit suffix)
+ *   %ma    output an angle in degrees (expects degrees)
  *
  * These accept the usual printf modifiers for %f, as well as
  *     $    output a unit suffix after the measure
@@ -83,9 +84,13 @@ enum e_allow {
                    ALLOW_CM | ALLOW_M  | ALLOW_KM,
   ALLOW_IMPERIAL = ALLOW_CMIL | ALLOW_MIL | ALLOW_IN,
   /* This is all units allowed in parse_l.l */
+#if 0
   ALLOW_READABLE = ALLOW_NM | ALLOW_UM | ALLOW_MM |
                    ALLOW_M  | ALLOW_KM | ALLOW_CMIL |
                    ALLOW_MIL | ALLOW_IN,
+#else
+  ALLOW_READABLE = ALLOW_CMIL,
+#endif
 
   ALLOW_ALL = ~0
 };
diff --git a/src/rotate.c b/src/rotate.c
index 017eb0c..1667985 100644
--- a/src/rotate.c
+++ b/src/rotate.c
@@ -198,8 +198,8 @@ RotateArcLowLevel (ArcTypePtr Arc, LocationType X, LocationType Y,
 {
   BDimension save;
 
-  /* add Number*90 degrees to the startangle and check for overflow */
-  Arc->StartAngle = (Arc->StartAngle + Number * 90) % 360;
+  /* add Number*90 degrees (i.e., Number quarter-turns) */
+  Arc->StartAngle = NormalizeAngle (Arc->StartAngle + Number * 90);
   ROTATE (Arc->X, Arc->Y, X, Y, Number);
 
   /* now change width and height */

commit e671936b613d47e2c52da5ac599e832b00abbc2d
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Update hid/gtk/gui-config.c with new grid preferences

diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 9443a0f..083ce25 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -124,7 +124,7 @@ static ConfigAttribute config_attributes[] = {
   {"gui-title-window", CONFIG_Boolean, &_ghidgui.ghid_title_window},
   {"use-command-window", CONFIG_Boolean, &_ghidgui.use_command_window},
   {"save-in-tmp", CONFIG_Unused, NULL},
-  {"grid-units-mm", CONFIG_Unused, NULL},
+  {"grid-units", CONFIG_Unused, NULL},
 
   {"history-size", CONFIG_Integer, &_ghidgui.history_size},
   {"auto-pan-speed", CONFIG_Integer, &_ghidgui.auto_pan_speed},
@@ -154,15 +154,6 @@ static ConfigAttribute config_attributes[] = {
   {"default-PCB-width", CONFIG_Unused, NULL},
   {"default-PCB-height", CONFIG_Unused, NULL},
 
-  {"grid-increment-mil", CONFIG_Unused, NULL},
-  {"grid-increment-mm", CONFIG_Unused, NULL},
-  {"size-increment-mil", CONFIG_Unused, NULL},
-  {"size-increment-mm", CONFIG_Unused, NULL},
-  {"line-increment-mil", CONFIG_Unused, NULL},
-  {"line-increment-mm", CONFIG_Unused, NULL},
-  {"clear-increment-mil", CONFIG_Unused, NULL},
-  {"clear-increment-mm", CONFIG_Unused, NULL},
-
   {"groups", CONFIG_Unused, NULL},
   {"route-styles", CONFIG_Unused, NULL},
   {"library-newlib", CONFIG_String, &lib_newlib_config},

commit 83cf329e2bb26514f6c0c53d3fc20498a9805218
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Remove mm/mil dichotomy, support arbitrary user units
    
    Currently, pcb assumes the user's display units are either mm
    or mil, and uses the Settings.grid_unit_mm boolean (and flag
    "grid_unit_mm") to determine which is which.
    
    This patch removes the boolean and replaces it with the new
    Settings.grid_unit, which can be set to any unit supported by
    pcb-printf. The user-visible interface has not changed (there
    is still a mm/mil toggle in Gtk and the menus only contain mm
    and mil units), but new units can be accessed though the
    :SetUnits command.
    
    The flag is still there and can be used in pcb-menu.res as
    usual. However, the new flag "grid_unit_mil" should be checked
    to see if mils are selected, since this is no longer implied
    by grid_unit_mm == 0.
    
    There will be some user-visible changes to the precision of
    displayed values, since I have removed a lot of special-case
    code for this sort of this thing and use the default_prec
    of applicable units instead.
    
    Because of the new flexibility, some idioms have been changed:
    
      Settings.grid_unit_mm ? COORD_TO_MM (x) : COORD_TO_MIL (x)
    becomes
      coord_to_unit (Settings.grid_unit, x)
    
      Settings.grid_unit_mm ? "mm" : "mil"
    becomes
      Settings.grid_unit->suffix
    
      Settings.grid_unit_mm = 1;
    becomes
      Settings.grid_unit = get_unit_struct ("mm");
    
    For GUI use, the Unit structure returned by get_unit_struct
    exposes certain members:
    
      suffix       : "mm"/"mil"/etc
      in_suffix    : i18n version of the above
      default_prec : precision used for spinboxes, labels, etc
    
      step_tiny    :
      step_small   :
      step_medium  : step sizes for various spinboxes
      step_large   :
      step_huge    :
    
    Additionally, the *_increment_mm and *_increment_mil variables
    have their own structure containing default, min and max values.
    These can no longer be set on the command line.

diff --git a/src/file.c b/src/file.c
index ef37641..b7349bb 100644
--- a/src/file.c
+++ b/src/file.c
@@ -438,8 +438,11 @@ LoadPCB (char *Filename)
       /* just in case a bad file saved file is loaded */
 
       /* Use imperial if the grid is a multiple of .5cmil, else metric */
-      Settings.grid_units_mm = (1000000 * COORD_TO_MM (PCB->Grid) / 127.0) !=
-                                 (Coord) (1000000 * COORD_TO_MM (PCB->Grid)) / 127;
+      if ((1000000 * COORD_TO_MM (PCB->Grid) / 127.0) !=
+            (Coord) (1000000 * COORD_TO_MM (PCB->Grid)) / 127)
+        Settings.grid_unit = get_unit_struct ("mm");
+      else
+        Settings.grid_unit = get_unit_struct ("mil");
 
       sort_netlist ();
 
diff --git a/src/find.c b/src/find.c
index 43dee33..5b30e93 100644
--- a/src/find.c
+++ b/src/find.c
@@ -90,6 +90,7 @@
 #include "misc.h"
 #include "rtree.h"
 #include "polygon.h"
+#include "pcb-printf.h"
 #include "search.h"
 #include "set.h"
 #include "undo.h"
@@ -157,9 +158,9 @@ RCSID ("$Id$");
 #define	IS_PV_ON_PAD(PV,Pad) \
 	( IsPointInPad((PV)->X, (PV)->Y, MAX((PV)->Thickness/2 +Bloat,0), (Pad)))
 
-#define LENGTH_TO_HUMAN(value) (Settings.grid_units_mm ? COORD_TO_MM(value) : COORD_TO_MIL(value))
-#define LENGTH_DIGITS (Settings.grid_units_mm ? 4 : 2)
-#define LENGTH_UNITS_STRING (Settings.grid_units_mm ? "mm" : "mils")
+#define LENGTH_TO_HUMAN(value) coord_to_unit (Settings.grid_unit, value)
+#define LENGTH_DIGITS (Settings.grid_unit->default_prec)
+#define LENGTH_UNITS_STRING (Settings.grid_unit->suffix)
 
 
 static DrcViolationType
diff --git a/src/flags.c b/src/flags.c
index a167663..a4e5fe5 100644
--- a/src/flags.c
+++ b/src/flags.c
@@ -36,6 +36,7 @@
 
 #include "global.h"
 #include "data.h"
+#include "pcb-printf.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -71,6 +72,18 @@ FlagGridSize (int dummy)
 }
 
 static int
+FlagUnitsMm (int dummy)
+{
+  return (Settings.grid_unit == get_unit_struct ("mm"));
+}
+
+static int
+FlagUnitsMil (int dummy)
+{
+  return (Settings.grid_unit == get_unit_struct ("mil"));
+}
+
+static int
 FlagBuffer (int dummy)
 {
   return (int) (Settings.BufferNumber + 1);
@@ -230,7 +243,8 @@ HID_Flag flags_flag_list[] = {
   {"hidenames", FlagTESTFLAG, HIDENAMESFLAG},
 
   {"fullpoly", FlagSETTINGS, OffsetOf (SettingType, FullPoly)},
-  {"grid_units_mm", FlagSETTINGS, OffsetOf (SettingType, grid_units_mm)},
+  {"grid_units_mm", FlagUnitsMm, -1},
+  {"grid_units_mil", FlagUnitsMil, -1},
   {"clearline", FlagSETTINGS, OffsetOf (SettingType, ClearLine)},
   {"uniquenames", FlagSETTINGS, OffsetOf (SettingType, UniqueNames)},
   {"showsolderside", FlagSETTINGS, OffsetOf (SettingType, ShowSolderSide)},
diff --git a/src/global.h b/src/global.h
index 9341940..ec388a9 100644
--- a/src/global.h
+++ b/src/global.h
@@ -61,6 +61,9 @@ typedef struct drc_violation_st DrcViolationType, *DrcViolationTypePtr;
 typedef struct rtree rtree_t;
 typedef struct AttributeListType AttributeListType, *AttributeListTypePtr;
 
+typedef struct unit Unit;
+typedef struct increments Increments;
+
 #include "hid.h"
 #include "polyarea.h"
 
@@ -608,7 +611,8 @@ typedef struct
  */
 typedef struct			/* some resources... */
 {
-  bool grid_units_mm;
+  const Unit *grid_unit;
+  Increments *increments;
 
   int verbose;
 
@@ -637,12 +641,7 @@ typedef struct			/* some resources... */
     AlignmentDistance, Bloat,	/* default drc sizes */
     Shrink, minWid, minSlk, minDrill, minRing;
   int TextScale;		/* text scaling in % */
-  Coord Grid,			/* grid in pcb-units */
-    grid_increment_mm,		/* key g and <shift>g value for mil units */
-    grid_increment_mil,		/* key g and <shift>g value for mil units */
-    size_increment_mm,		/* key s and <shift>s value for mil units */
-    size_increment_mil,		/* key s and <shift>s value for mil units */
-    line_increment_mm, line_increment_mil, clear_increment_mm, clear_increment_mil;	/* number of shift operations for zooming */
+  Coord Grid;			/* grid in pcb-units */
   double Zoom,
     IsleArea,    		/* polygon min area */
     PinoutZoom;			/* same for pinout windows */
@@ -650,8 +649,7 @@ typedef struct			/* some resources... */
     Volume,			/* the speakers volume -100..100 */
     CharPerLine,		/* width of an output line in characters */
     Mode,			/* currently active mode */
-    BufferNumber,		/* number of the current buffer */
-    GridFactor;			/* factor used for grid-drawing */
+    BufferNumber;		/* number of the current buffer */
   int BackupInterval;		/* time between two backups in seconds */
   char *DefaultLayerName[MAX_LAYER], *FontCommand,	/* commands for file loading... */
    *FileCommand, *ElementCommand, *PrintFile, *LibraryCommandDir, *LibraryCommand, *LibraryContentsCommand, *LibraryTree,	/* path to library tree */
diff --git a/src/gpcb-menu.res.in b/src/gpcb-menu.res.in
index dc594c4..bb5b8bf 100644
--- a/src/gpcb-menu.res.in
+++ b/src/gpcb-menu.res.in
@@ -117,8 +117,8 @@ MainMenu =
   {"View"
    {"Enable visible grid" checked=drawgrid Display(Grid)}
    {"Grid units"
-    {"mil" checked=grid_units_mm,0 SetUnits(mil)}
-    {"mm"  checked=grid_units_mm,1 SetUnits(mm)}
+    {"mil" checked=grid_units_mil SetUnits(mil)}
+    {"mm"  checked=grid_units_mm SetUnits(mm)}
    }
    {"Grid size"
     {"No Grid" checked=gridsize,1 SetValue(Grid,1)}
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index a4cd443..7699cf9 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -20,6 +20,7 @@
 #include "gui.h"
 #include "hid/common/hidnogui.h"
 #include "hid/common/draw_helpers.h"
+#include "pcb-printf.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
@@ -1809,12 +1810,16 @@ Sets the display units to millimeters.
 static int
 SetUnits (int argc, char **argv, int x, int y)
 {
+  const Unit *new_unit;
   if (argc == 0)
     return 0;
-  if (strcmp (argv[0], "mil") == 0)
-    Settings.grid_units_mm = 0;
-  if (strcmp (argv[0], "mm") == 0)
-    Settings.grid_units_mm = 1;
+
+  new_unit = get_unit_struct (argv[0]);
+  if (new_unit != NULL && new_unit->allow != NO_PRINT)
+    {
+      Settings.grid_unit = new_unit;
+      Settings.increments = get_increments_struct (Settings.grid_unit->suffix);
+    }
 
   ghid_config_handle_units_changed ();
 
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 685e4b2..9443a0f 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -46,6 +46,7 @@
 #include "error.h"
 #include "draw.h"
 #include "misc.h" /* MKDIR() */
+#include "pcb-printf.h"
 #include "set.h"
 
 #if 0
@@ -935,11 +936,11 @@ config_general_apply (void)
 
   /* -------------- The Sizes config page ----------------
    */
-#define	STEP0_SMALL_SIZE	(Settings.grid_units_mm ? 0.005 : 0.1)
-#define	STEP1_SMALL_SIZE	(Settings.grid_units_mm ? 0.05 : 1.0)
-#define	STEP0_SIZE			(Settings.grid_units_mm ? 5.0 : 100)
-#define	STEP1_SIZE			(Settings.grid_units_mm ? 25.0 : 1000)
-#define	SPIN_DIGITS			(Settings.grid_units_mm ? 3 : 1)
+#define	STEP0_SMALL_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_tiny)
+#define	STEP1_SMALL_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_small)
+#define	STEP0_SIZE		FROM_PCB_UNITS (Settings.grid_unit->step_large)
+#define	STEP1_SIZE		FROM_PCB_UNITS (Settings.grid_unit->step_huge)
+#define	SPIN_DIGITS		(Settings.grid_unit->default_prec)
 
 static GtkWidget *config_sizes_vbox,
   *config_sizes_tab_vbox, *config_text_spin_button;
@@ -1020,7 +1021,7 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
     }
 
   str = g_strdup_printf (_("<b>%s</b> grid units are selected"),
-			 Settings.grid_units_mm ? _("mm") : _("mil"));
+                         Settings.grid_unit->in_suffix);
   label = gtk_label_new ("");
   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
   gtk_label_set_markup (GTK_LABEL (label), str);
@@ -1056,8 +1057,7 @@ config_sizes_tab_create (GtkWidget * tab_vbox)
 			  &new_board_height, FALSE, _("Height"));
   ghid_check_button_connected (vbox, &use_board_size_default_button, FALSE,
 			       TRUE, FALSE, FALSE, 0, NULL, NULL,
-			       _
-			       ("Use this board size as the default for new layouts"));
+			       _("Use this board size as the default for new layouts"));
 
   /* ---- Text Scale ---- */
   vbox = ghid_category_vbox (config_sizes_vbox, _("Text Scale"),
@@ -1181,10 +1181,8 @@ config_increments_tab_create (GtkWidget * tab_vbox)
       config_increments_tab_vbox = tab_vbox;
     }
 
-  str =
-    g_strdup_printf (_
-		     ("Increment/Decrement values to use in <b>%s</b> units mode.\n"),
-		     Settings.grid_units_mm ? _("mm") : _("mil"));
+  str = g_strdup_printf (_("Increment/Decrement values to use for <b>%s</b>"),
+                         Settings.grid_unit->in_suffix);
   label = gtk_label_new ("");
   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
   gtk_label_set_markup (GTK_LABEL (label), str);
@@ -1197,20 +1195,14 @@ config_increments_tab_create (GtkWidget * tab_vbox)
   vbox = ghid_category_vbox (config_increments_vbox,
 			     _("Grid Increment/Decrement"), 4, 2, TRUE, TRUE);
 
-  /* Grid increment spin button ('g' and '<shift>g').  For mil
-     |  units, range from 1.0 to 25.0.  For mm, range from 0.01 to 1.0
-     |  Step sizes of 5 mil or .05 mm, and .01 mm precision or 1 mil precision.
-   */
-  target = Settings.grid_units_mm ?
-    &Settings.grid_increment_mm : &Settings.grid_increment_mil;
+  target = &Settings.increments->grid;
   ghid_spin_button (vbox, NULL,
-		    GRID_UNITS_VALUE (Settings.grid_increment_mm,
-				      Settings.grid_increment_mil),
-		    GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (1.0,
-								    25.0),
-		    GRID_UNITS_VALUE (0.05, 5.0), GRID_UNITS_VALUE (0.05,
-								    5.0),
-		    GRID_UNITS_VALUE (2, 0), 0, increment_spin_button_cb,
+                    FROM_PCB_UNITS (Settings.increments->grid),
+                    FROM_PCB_UNITS (Settings.increments->grid_min),
+                    FROM_PCB_UNITS (Settings.increments->grid_max),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_medium),
+		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 'g' and '<shift>g' grid change actions"));
 
@@ -1223,16 +1215,14 @@ config_increments_tab_create (GtkWidget * tab_vbox)
      |  units, range from 1.0 to 10.0.  For mm, range from 0.01 to 0.5
      |  Step sizes of 1 mil or .01 mm, and .01 mm precision or 1 mil precision.
    */
-  target = Settings.grid_units_mm ?
-    &Settings.size_increment_mm : &Settings.size_increment_mil;
+  target = &Settings.increments->size;
   ghid_spin_button (vbox, NULL,
-		    GRID_UNITS_VALUE (Settings.size_increment_mm,
-				      Settings.size_increment_mil),
-		    GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (0.5,
-								    10.0),
-		    GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (0.05,
-								    5.0),
-		    GRID_UNITS_VALUE (2, 0), 0, increment_spin_button_cb,
+                    FROM_PCB_UNITS (Settings.increments->size),
+                    FROM_PCB_UNITS (Settings.increments->size_min),
+                    FROM_PCB_UNITS (Settings.increments->size_max),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
+		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
 		    target, FALSE,
 		    _("For 's' and '<shift>s' size change actions on lines,\n"
 		      "pads, pins and text.\n"
@@ -1247,19 +1237,16 @@ config_increments_tab_create (GtkWidget * tab_vbox)
      |  Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
      |  precision.
    */
-  target = Settings.grid_units_mm ?
-    &Settings.line_increment_mm : &Settings.line_increment_mil;
+  target = &Settings.increments->line;
   ghid_spin_button (vbox, NULL,
-		    GRID_UNITS_VALUE (Settings.line_increment_mm,
-				      Settings.line_increment_mil),
-		    GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.5,
-								     10.0),
-		    GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.05,
-								     5.0),
-		    GRID_UNITS_VALUE (3, 1), 0, increment_spin_button_cb,
+                    FROM_PCB_UNITS (Settings.increments->line),
+                    FROM_PCB_UNITS (Settings.increments->line_min),
+                    FROM_PCB_UNITS (Settings.increments->line_max),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
+		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
 		    target, FALSE,
-		    _
-		    ("For 'l' and '<shift>l' routing line width change actions"));
+		    _("For 'l' and '<shift>l' routing line width change actions"));
 
   /* ---- Clear Increment/Decrement ---- */
   vbox = ghid_category_vbox (config_increments_vbox,
@@ -1271,19 +1258,16 @@ config_increments_tab_create (GtkWidget * tab_vbox)
      |  Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
      |  precision.
    */
-  target = Settings.grid_units_mm ?
-    &Settings.clear_increment_mm : &Settings.clear_increment_mil;
+  target = &Settings.increments->clear;
   ghid_spin_button (vbox, NULL,
-		    GRID_UNITS_VALUE (Settings.clear_increment_mm,
-				      Settings.clear_increment_mil),
-		    GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.5,
-								     10.0),
-		    GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.05,
-								     5.0),
-		    GRID_UNITS_VALUE (3, 1), 0, increment_spin_button_cb,
+                    FROM_PCB_UNITS (Settings.increments->clear),
+                    FROM_PCB_UNITS (Settings.increments->clear_min),
+                    FROM_PCB_UNITS (Settings.increments->clear_max),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_tiny),
+                    FROM_PCB_UNITS (Settings.grid_unit->step_small),
+		    Settings.grid_unit->default_prec, 0, increment_spin_button_cb,
 		    target, FALSE,
-		    _
-		    ("For 'k' and '<shift>k' line clearance inside polygon size\n"
+		    _("For 'k' and '<shift>k' line clearance inside polygon size\n"
 		     "change actions"));
 
 
@@ -2086,10 +2070,12 @@ config_page_create (GtkTreeStore * tree, GtkTreeIter * iter,
 void
 ghid_config_handle_units_changed (void)
 {
+  gchar *text = pcb_g_strdup_printf ("<b>%s</b>",
+                                     Settings.grid_unit->in_suffix);
   ghid_set_cursor_position_labels ();
-  gtk_label_set_markup (GTK_LABEL (ghidgui->grid_units_label),
-			Settings.grid_units_mm ?
-			_("<b>mm</b> ") : _("<b>mil</b> "));
+  gtk_label_set_markup (GTK_LABEL (ghidgui->grid_units_label), text);
+  g_free (text);
+
   if (config_sizes_vbox)
     {
       gtk_widget_destroy (config_sizes_vbox);
diff --git a/src/hid/gtk/gui-dialog-size.c b/src/hid/gtk/gui-dialog-size.c
index 0c0f8ef..1cc59ad 100644
--- a/src/hid/gtk/gui-dialog-size.c
+++ b/src/hid/gtk/gui-dialog-size.c
@@ -53,9 +53,9 @@
 
 RCSID ("$Id$");
 
-#define STEP0_SIZE          (Settings.grid_units_mm ? 0.05 : 1.0)
-#define STEP1_SIZE          (Settings.grid_units_mm ? 0.25 : 5.0)
-#define SPIN_DIGITS			(Settings.grid_units_mm ? 3 : 1)
+#define STEP0_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_small)
+#define STEP1_SIZE	FROM_PCB_UNITS (Settings.grid_unit->step_medium)
+#define SPIN_DIGITS	(Settings.grid_unit->default_prec)
 
 typedef struct
 {
@@ -64,7 +64,6 @@ typedef struct
     *via_hole_spin_button,
     *via_size_spin_button,
     *clearance_spin_button, *set_temp1_button, *set_temp2_button;
-  gboolean units_mm;		/* at time of dialog creation */
 }
 SizesDialog;
 
@@ -219,8 +218,8 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
 
-  s = g_strdup_printf (_("<b>%s</b> grid units are selected"),
-		       Settings.grid_units_mm ? _("mm") : _("mil"));
+  s = g_strdup_printf (_("<b>%s</b> grid units are selected"), 
+                       Settings.grid_unit->in_suffix);
   label = gtk_label_new ("");
   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
   gtk_label_set_markup (GTK_LABEL (label), s);
@@ -234,14 +233,11 @@ ghid_route_style_dialog (gint index, RouteStyleType * temp_rst)
   sd->name_entry = gtk_entry_new ();
   gtk_box_pack_start (GTK_BOX (hbox), sd->name_entry, FALSE, FALSE, 0);
 
-  sd->units_mm = Settings.grid_units_mm;	/* XXX not used yet */
-
   vbox1 = ghid_category_vbox (vbox, _("Sizes"), 4, 2, TRUE, TRUE);
   table = gtk_table_new (4, 2, FALSE);
   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
 
-  /* XXX Scale these based on units_mm?? */
   ghid_table_spin_button (table, 0, 0,
 			  &sd->line_width_spin_button,
 			  FROM_PCB_UNITS (rst->Thick),
diff --git a/src/hid/gtk/gui-misc.c b/src/hid/gtk/gui-misc.c
index 00791e3..396abe1 100644
--- a/src/hid/gtk/gui-misc.c
+++ b/src/hid/gtk/gui-misc.c
@@ -402,26 +402,17 @@ ghid_set_status_line_label (void)
                       ? "45_/"
                       : "45\\_"));
   gchar *text = pcb_g_strdup_printf (
-      Settings.grid_units_mm
-        ? _("<b>view</b>=%s  "
-            "<b>grid</b>=%5.3mm:%i  "
-            "%s%s  "
-            "<b>line</b>=%5.3mm  "
-            "<b>via</b>=%5.3mm(%5.3mm)  %s"
-            "<b>clearance</b>=%5.3mm  "
-            "<b>text</b>=%i%%  "
-            "<b>buffer</b>=#%i")
-        : _("<b>view</b>=%s  "
-            "<b>grid</b>=%.1ml:%i  "
-            "%s%s  "
-            "<b>line</b>=%.1ml  "
-            "<b>via</b>=%.1ml(%.1ml)  %s"
-            "<b>clearance</b>=%.1ml  "
-            "<b>text</b>=%i%%  "
-            "<b>buffer</b>=#%i"),
+        _("%m+<b>view</b>=%s  "
+          "<b>grid</b>=%$mS  "
+          "%s%s  "
+          "<b>line</b>=%mS  "
+          "<b>via</b>=%mS (%mS)  %s"
+          "<b>clearance</b>=%mS  "
+          "<b>text</b>=%i%%  "
+          "<b>buffer</b>=#%i"),
+      Settings.grid_unit->allow,
       Settings.ShowSolderSide ? _("solder") : _("component"),
       PCB->Grid,
-      (int) Settings.GridFactor,
       flag, TEST_FLAG (RUBBERBANDFLAG, PCB) ? ",R  " : "  ",
       Settings.LineThickness,
       Settings.ViaThickness,
@@ -450,7 +441,7 @@ ghid_set_cursor_position_labels (void)
       double a      = atan2 (dy, dx) * RAD_TO_DEG;
 
       text = pcb_g_strdup_printf ("%m+r %-mS; phi %-.1f; %-mS %-mS",
-                                  Settings.grid_units_mm ? ALLOW_MM : ALLOW_MIL,
+                                  Settings.grid_unit->allow,
                                   r, a, dx, dy);
       ghid_cursor_position_relative_label_set_text (text);
       g_free (text);
@@ -460,7 +451,7 @@ ghid_set_cursor_position_labels (void)
 
 
   text = pcb_g_strdup_printf ("%m+%-mS %-mS",
-                              Settings.grid_units_mm ? ALLOW_MM : ALLOW_MIL,
+                              Settings.grid_unit->allow,
                               Crosshair.X, Crosshair.Y);
   ghid_cursor_position_label_set_text (text);
   g_free (text);
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index e9c2669..7b210f8 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -948,7 +948,8 @@ ghid_window_set_name_label (gchar * name)
 static void
 grid_units_button_cb (GtkWidget * widget, gpointer data)
 {
-  if (Settings.grid_units_mm)
+  /* Button only toggles between mm and mil */
+  if (Settings.grid_unit == get_unit_struct ("mm"))
     hid_actionl ("SetUnits", "mil", NULL);
   else
     hid_actionl ("SetUnits", "mm", NULL);
@@ -993,8 +994,7 @@ make_cursor_position_labels (GtkWidget * hbox, GHidPort * port)
   button = gtk_button_new ();
   label = gtk_label_new ("");
   gtk_label_set_markup (GTK_LABEL (label),
-			Settings.grid_units_mm ?
-			"<b>mm</b> " : "<b>mil</b> ");
+			Settings.grid_unit->in_suffix);
   ghidgui->grid_units_label = label;
   gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
   gtk_container_add (GTK_CONTAINER (button), label);
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index bc15628..e8123d9 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -58,8 +58,8 @@
      |  PCB keeps values internally higher precision, but gui
      |  widgets (spin buttons, labels, etc) need mils or millimeters.
    */
-#define	FROM_PCB_UNITS(v)	(Settings.grid_units_mm ? COORD_TO_MM(v) : COORD_TO_MIL(v))
-#define	TO_PCB_UNITS(v)		(Settings.grid_units_mm ? MM_TO_COORD(v) : MIL_TO_COORD(v))
+#define	FROM_PCB_UNITS(v)	coord_to_unit (Settings.grid_unit, v)
+#define	TO_PCB_UNITS(v)		unit_to_coord (Settings.grid_unit, v)
 
 extern int ghid_flip_x, ghid_flip_y;
 #define SIDE_X(x)   ((ghid_flip_x ? PCB->MaxWidth - (x) : (x)))
@@ -90,16 +90,11 @@ extern int ghid_flip_x, ghid_flip_y;
 #define GHID_KEY_LEFT     0x04
 #define GHID_KEY_RIGHT    0x05
 
-  /* Pick one of two values depending on current grid units setting.
-   */
-#define GRID_UNITS_VALUE(mm, mil)   (Settings.grid_units_mm ? (mm) : (mil))
-
-
 typedef struct
 {
   GtkUIManager *ui_manager;
   GtkActionGroup *main_actions,
-    *grid_actions, *change_selected_actions, *displayed_name_actions;
+    *change_selected_actions, *displayed_name_actions;
 
   GtkWidget *name_label,
     *status_line_label,
@@ -224,7 +219,6 @@ void ghid_set_menu_toggle_button (GtkActionGroup * ag,
 void ghid_pcb_saved_toggle_states_set (void);
 void ghid_sync_with_new_layout (void);
 
-void ghid_grid_setting_update_menu_actions (void);
 void ghid_change_selected_update_menu_actions (void);
 
 void ghid_config_window_show ();
diff --git a/src/hid/lesstif/dialogs.c b/src/hid/lesstif/dialogs.c
index 2f956a9..27d312c 100644
--- a/src/hid/lesstif/dialogs.c
+++ b/src/hid/lesstif/dialogs.c
@@ -1132,18 +1132,15 @@ static Widget sz_text;
 static Widget sz_set, sz_reset, sz_units;
 
 static int
-sz_str2val (Widget w, int pcbu)
+sz_str2val (Widget w, bool pcbu)
 {
   double d;
   char *buf;
   buf = XmTextGetString (w);
   if (!pcbu)
-    return atoi (buf);
+    return strtol (buf, NULL, 0);
   sscanf (buf, "%lf", &d);
-  if (Settings.grid_units_mm)
-    return MM_TO_COORD (d);
-  else
-    return MIL_TO_COORD (d);
+  return unit_to_coord (Settings.grid_unit, d);
 }
 
 static void
@@ -1151,12 +1148,7 @@ sz_val2str (Widget w, BDimension u, int pcbu)
 {
   static char buf[40];
   if (pcbu)
-    {
-      if (Settings.grid_units_mm)
-        pcb_sprintf (buf, "%.2mm", u);
-      else
-        pcb_sprintf (buf, "%.2ml", u);
-    }
+    pcb_sprintf (buf, "%m+%.2mm", Settings.grid_unit->allow, u);
   else
     pcb_sprintf (buf, "%#mS %%", u);
   XmTextSetString (w, buf);
@@ -1202,13 +1194,11 @@ lesstif_sizes_reset ()
   sz_val2str (sz_drc_ring, PCB->minRing, 1);
   sz_val2str (sz_text, Settings.TextScale, 0);
 
-  if (Settings.grid_units_mm)
-    ls = "Units are MMs";
-  else
-    ls = "Units are Mils";
+  ls = g_strdup_printf (_("Units are %s."), Settings.grid_unit->in_suffix);
   n = 0;
   stdarg (XmNlabelString, XmStringCreatePCB (ls));
   XtSetValues (sz_units, args, n);
+  g_free (ls);
 }
 
 static Widget
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index d275af0..9108f2c 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -48,7 +48,7 @@ RCSID ("$Id$");
 
 /* How big the viewport can be relative to the pcb size.  */
 #define MAX_ZOOM_SCALE	10
-#define UUNIT	(Settings.grid_units_mm ? ALLOW_MM : ALLOW_MIL)
+#define UUNIT	Settings.grid_unit->allow
 
 typedef struct hid_gc_struct
 {
@@ -139,9 +139,9 @@ static int view_left_x = 0, view_top_y = 0;
 /* Denotes PCB units per screen pixel.  Larger numbers mean zooming
    out - the largest value means you are looking at the whole
    board.  */
-static double view_zoom = 1000, prev_view_zoom = 1000;
-static int flip_x = 0, flip_y = 0;
-static int autofade = 0;
+static double view_zoom = MIL_TO_COORD (10), prev_view_zoom = MIL_TO_COORD (10);
+static bool flip_x = 0, flip_y = 0;
+static bool autofade = 0;
 static bool crosshair_on = true;
 
 static void
@@ -226,7 +226,7 @@ static void Pan (int mode, int x, int y);
 /* Px converts view->pcb, Vx converts pcb->view */
 
 static inline int
-Vx (int x)
+Vx (Coord x)
 {
   int rv = (x - view_left_x) / view_zoom + 0.5;
   if (flip_x)
@@ -235,7 +235,7 @@ Vx (int x)
 }
 
 static inline int
-Vy (int y)
+Vy (Coord y)
 {
   int rv = (y - view_top_y) / view_zoom + 0.5;
   if (flip_y)
@@ -244,12 +244,12 @@ Vy (int y)
 }
 
 static inline int
-Vz (int z)
+Vz (Coord z)
 {
   return z / view_zoom + 0.5;
 }
 
-static inline int
+static inline Coord
 Px (int x)
 {
   if (flip_x)
@@ -257,7 +257,7 @@ Px (int x)
   return x * view_zoom + view_left_x;
 }
 
-static inline int
+static inline Coord
 Py (int y)
 {
   if (flip_y)
@@ -265,14 +265,14 @@ Py (int y)
   return y * view_zoom + view_top_y;
 }
 
-static inline int
+static inline Coord
 Pz (int z)
 {
   return z * view_zoom;
 }
 
 void
-lesstif_coords_to_pcb (int vx, int vy, int *px, int *py)
+lesstif_coords_to_pcb (int vx, int vy, Coord *px, Coord *py)
 {
   *px = Px (vx);
   *py = Py (vy);
@@ -405,12 +405,15 @@ Sets the display units to millimeters.
 static int
 SetUnits (int argc, char **argv, int x, int y)
 {
+  const Unit *new_unit;
   if (argc == 0)
     return 0;
-  if (strcmp (argv[0], "mil") == 0)
-    Settings.grid_units_mm = 0;
-  if (strcmp (argv[0], "mm") == 0)
-    Settings.grid_units_mm = 1;
+  new_unit = get_unit_struct (argv[0]);
+  if (new_unit != NULL && new_unit->allow != NO_PRINT)
+    {
+      Settings.grid_unit = new_unit;
+      Settings.increments = get_increments_struct (Settings.grid_unit->suffix);
+    }
   lesstif_sizes_reset ();
   lesstif_styles_update_values ();
   return 0;
@@ -2311,17 +2314,15 @@ static void
 mark_delta_to_widget (BDimension dx, BDimension dy, Widget w)
 {
   char *buf;
-  double g = Settings.grid_units_mm ? COORD_TO_MM (PCB->Grid) : COORD_TO_MIL (PCB->Grid);
+  double g = coord_to_unit (Settings.grid_unit, PCB->Grid);
   int prec;
   XmString ms;
 
   /* Integer-sized grid? */
   if (((int) (g * 10000 + 0.5) % 10000) == 0)
     prec = 0;
-  else if (Settings.grid_units_mm && g <= 0.005)
-    prec = 3;
   else
-    prec = 2;
+    prec = Settings.grid_unit->default_prec;
 
   if (dx == 0 && dy == 0)
     buf = pcb_g_strdup_printf ("%m+%+.*mS, %+.*mS", UUNIT, prec, dx, prec, dy);
@@ -2346,7 +2347,7 @@ cursor_pos_to_widget (BDimension x, BDimension y, Widget w, int prev_state)
 {
   int this_state = prev_state;
   static char *buf;
-  double g = Settings.grid_units_mm ? COORD_TO_MM (PCB->Grid) : COORD_TO_MIL (PCB->Grid);
+  double g = coord_to_unit (Settings.grid_unit, PCB->Grid);
   XmString ms;
   int prec;
 
@@ -2355,17 +2356,12 @@ cursor_pos_to_widget (BDimension x, BDimension y, Widget w, int prev_state)
   if (((int) (g * 10000 + 0.5) % 10000) == 0)
     {
       prec = 0;
-      this_state = 2 + Settings.grid_units_mm;
-    }
-  else if (Settings.grid_units_mm && g <= 0.005)
-    {
-      prec = 3;
-      this_state = 4 + Settings.grid_units_mm;
+      this_state = Settings.grid_unit->allow;
     }
   else
     {
-      prec = 2;
-      this_state = 4 + Settings.grid_units_mm;
+      prec = Settings.grid_unit->default_prec;
+      this_state = -Settings.grid_unit->allow;
     }
 
   if (x < 0)
@@ -2613,17 +2609,18 @@ idle_proc (XtPointer dummy)
 
   {
     static Coord old_grid = -1;
-    static Coord old_gx, old_gy, old_mm;
+    static Coord old_gx, old_gy;
+    static const Unit *old_unit;
     XmString ms;
     if (PCB->Grid != old_grid
 	|| PCB->GridOffsetX != old_gx
-	|| PCB->GridOffsetY != old_gy || Settings.grid_units_mm != old_mm)
+	|| PCB->GridOffsetY != old_gy || Settings.grid_unit != old_unit)
       {
 	static char buf[100];
 	old_grid = PCB->Grid;
+	old_unit = Settings.grid_unit;
 	old_gx = PCB->GridOffsetX;
 	old_gy = PCB->GridOffsetY;
-	old_mm = Settings.grid_units_mm;
 	if (old_grid == 1)
 	  {
 	    strcpy (buf, "No Grid");
@@ -2644,35 +2641,21 @@ idle_proc (XtPointer dummy)
 
   {
     static double old_zoom = -1;
-    static int old_zoom_units = -1;
-    if (view_zoom != old_zoom || Settings.grid_units_mm != old_zoom_units)
+    static const Unit *old_grid_unit = NULL;
+    if (view_zoom != old_zoom || Settings.grid_unit != old_grid_unit)
       {
-	static char buf[100];
-	double g;
-	const char *units;
+	gchar *buf = pcb_g_strdup_printf ("%m+%$mS/pix",
+                                          Settings.grid_unit->allow, (Coord) view_zoom);
 	XmString ms;
 
 	old_zoom = view_zoom;
-	old_zoom_units = Settings.grid_units_mm;
+	old_grid_unit = Settings.grid_unit;
 
-	if (Settings.grid_units_mm)
-	  {
-	    g = COORD_TO_MM (view_zoom);
-	    units = "mm";
-	  }
-	else
-	  {
-	    g = COORD_TO_MIL (view_zoom);
-	    units = "mil";
-	  }
-	if ((int) (g * 100 + 0.5) == (int) (g + 0.005) * 100)
-	  sprintf (buf, "%d %s/pix", (int) (g + 0.005), units);
-	else
-	  sprintf (buf, "%.2f %s/pix", g, units);
 	ms = XmStringCreatePCB (buf);
 	n = 0;
 	stdarg (XmNlabelString, ms);
 	XtSetValues (m_zoom, args, n);
+        g_free (buf);
       }
   }
 
diff --git a/src/hid/lesstif/styles.c b/src/hid/lesstif/styles.c
index 91e8c79..9442849 100644
--- a/src/hid/lesstif/styles.c
+++ b/src/hid/lesstif/styles.c
@@ -16,6 +16,7 @@
 #include "data.h"
 #include "set.h"
 #include "mymem.h"
+#include "pcb-printf.h"
 
 #include "hid.h"
 #include "../hidint.h"
@@ -64,9 +65,8 @@ static Widget value_form, value_labels, value_texts, units_form;
 static int local_update = 0;
 XmString xms_mm, xms_mil;
 
-static int use_mm = 0;
-
-#define USTR (use_mm ? xms_mm : xms_mil)
+static const Unit *unit = 0;
+static XmString ustr;
 
 static int
 hash (char *cp)
@@ -96,19 +96,14 @@ static char *value_names[] = {
 static int RouteStylesChanged (int argc, char **argv, int x, int y);
 
 static void
-update_one_value (int i, int v)
+update_one_value (int i, Coord v)
 {
   char buf[100];
-  double d;
-  if (use_mm)
-    d = COORD_TO_MM (v);
-  else
-    d = COORD_TO_MIL (v);
 
-  sprintf (buf, "%.2f", d);
+  pcb_sprintf (buf, "%m+%.2mS", unit->allow, v);
   XmTextSetString (style_values[i], buf);
   n = 0;
-  stdarg (XmNlabelString, USTR);
+  stdarg (XmNlabelString, ustr);
   XtSetValues (units_pb[i], args, n);
 }
 
@@ -132,7 +127,8 @@ lesstif_styles_update_values ()
       lesstif_update_status_line ();
       return;
     }
-  use_mm = Settings.grid_units_mm;
+  unit = Settings.grid_unit;
+  ustr = XmStringCreateLocalized ((char *)Settings.grid_unit->suffix);
   update_values ();
 }
 
@@ -164,17 +160,14 @@ static void
 style_value_cb (Widget w, int i, void *cbs)
 {
   double d;
-  int n;
+  Coord n;
   char *s;
 
   if (local_update)
     return;
   s = XmTextGetString (w);
   sscanf (s, "%lf", &d);
-  if (use_mm)
-    n = MM_TO_COORD (d);
-  else
-    n = MIL_TO_COORD (d);
+  n = unit_to_coord (unit, d);
   switch (i)
     {
     case SSthick:
@@ -196,7 +189,10 @@ style_value_cb (Widget w, int i, void *cbs)
 static void
 units_cb ()
 {
-  use_mm = !use_mm;
+  if (unit == get_unit_struct ("mm"))
+    unit = get_unit_struct ("mil");
+  else
+    unit = get_unit_struct ("mm");
   update_values ();
 }
 
@@ -235,7 +231,7 @@ style_value (int i)
   stdarg (XmNbottomPosition, i + 1);
   stdarg (XmNleftAttachment, XmATTACH_FORM);
   stdarg (XmNrightAttachment, XmATTACH_FORM);
-  stdarg (XmNlabelString, USTR);
+  stdarg (XmNlabelString, ustr);
   units_pb[i] = XmCreatePushButton (units_form, value_names[i], args, n);
   XtAddCallback (units_pb[i], XmNactivateCallback,
 		 (XtCallbackProc) units_cb, (XtPointer) (size_t) i);
@@ -360,9 +356,6 @@ AdjustStyle (int argc, char **argv, int x, int y)
     {
       int i;
 
-      xms_mm = XmStringCreatePCB ("mm");
-      xms_mil = XmStringCreatePCB ("mil");
-
       n = 0;
       stdarg (XmNautoUnmanage, False);
       stdarg (XmNtitle, "Route Styles");
diff --git a/src/pcb-menu.res.in b/src/pcb-menu.res.in
index 1e88e52..22847e9 100644
--- a/src/pcb-menu.res.in
+++ b/src/pcb-menu.res.in
@@ -90,8 +90,8 @@ MainMenu =
     {"Zoom to 10mil/px" Zoom(=1000)}
    }
    {Grid
-    {"mil" checked=grid_units_mm,0 SetUnits(mil)}
-    {"mm"  checked=grid_units_mm,1 SetUnits(mm)}
+    {"mil" checked=grid_units_mil SetUnits(mil)}
+    {"mm"  checked=grid_units_mm SetUnits(mm)}
     {"Display grid" checked=drawgrid Display(Grid)}
     {"Realign grid" GetXY(Click to set the grid origin) Display(ToggleGrid)}
     {"No Grid" checked=gridsize,1 SetValue(Grid,1)}
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index b941c4d..65c9e5a 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -93,7 +93,7 @@ enum e_allow {
 enum e_family { METRIC, IMPERIAL };
 enum e_suffix { NO_SUFFIX, SUFFIX, FILE_MODE };
 
-typedef struct unit {
+struct unit {
   const char *suffix;
   const char *in_suffix;	/* internationalized suffix */
   char printf_code;
@@ -107,9 +107,9 @@ typedef struct unit {
   Coord step_medium;
   Coord step_large;
   Coord step_huge;
-} Unit;
+};
 
-typedef struct increments {
+struct increments {
   const char *suffix;
   /* key g and <shift>g value  */
   Coord grid;
@@ -127,7 +127,7 @@ typedef struct increments {
   Coord clear;
   Coord clear_min;
   Coord clear_max;
-} Increments;
+};
 
 const Unit *get_unit_struct (const char *suffix);
 double coord_to_unit (const Unit *, Coord);
diff --git a/src/report.c b/src/report.c
index 53b8b41..e0ae113 100644
--- a/src/report.c
+++ b/src/report.c
@@ -53,8 +53,7 @@
 #include <dmalloc.h>
 #endif
 
-/* These should perhaps be ALLOW_METRIC and ALLOW_IMPERIAL to allow scaling */
-#define USER_UNITMASK (Settings.grid_units_mm ? ALLOW_MM : ALLOW_MIL)
+#define USER_UNITMASK (Settings.grid_unit->allow)
 
 static int
 ReportDrills (int argc, char **argv, int x, int y)
@@ -82,7 +81,7 @@ ReportDrills (int argc, char **argv, int x, int y)
   sprintf (stringlist,
 	   "There are %d different drill sizes used in this layout, %d holes total\n\n"
 	   "Drill Diam. (%s)\t# of Pins\t# of Vias\t# of Elements\t# Unplated\n",
-	   AllDrills->DrillN, total_drills, Settings.grid_units_mm ? "mm" : "mil");
+	   AllDrills->DrillN, total_drills, Settings.grid_unit->suffix);
   thestring = stringlist;
   while (*thestring != '\0')
     thestring++;
@@ -90,7 +89,7 @@ ReportDrills (int argc, char **argv, int x, int y)
     {
       pcb_sprintf (thestring,
 	       "\t%$m*\t\t%d\t\t%d\t\t%d\t\t%d\n",
-	       (Settings.grid_units_mm ? "mm" : "mil"),
+	       Settings.grid_unit->suffix,
 	       AllDrills->Drill[n].DrillSize,
 	       AllDrills->Drill[n].PinCount, AllDrills->Drill[n].ViaCount,
 	       AllDrills->Drill[n].ElementN,
@@ -634,7 +633,7 @@ ReportAllNetLengths (int argc, char **argv, int x, int y)
           BDimension length;
 
           if (argc < 1)
-            units_name = (Settings.grid_units_mm ? "mm" : "mil");
+            units_name = Settings.grid_unit->suffix;
 
           if (ResetConnections (true))
             Draw ();
@@ -730,7 +729,7 @@ ReportNetLength (int argc, char **argv, int x, int y)
 
   {
     char buf[50];
-    pcb_sprintf(buf, "%$m*", (Settings.grid_units_mm ? "mm" : "mil"), length);
+    pcb_sprintf(buf, "%$m*", Settings.grid_unit->suffix, length);
     if (netname)
       gui->log ("Net \"%s\" length: %s\n", netname, buf);
     else

commit 461825d9a84dc5abe78618b83662afea3fbd44f5
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Cleanup default values in main.c

diff --git a/src/main.c b/src/main.c
index 2754864..d007f87 100644
--- a/src/main.c
+++ b/src/main.c
@@ -56,6 +56,7 @@
 #include "lrealpath.h"
 #include "free_atexit.h"
 #include "polygon.h"
+#include "pcb-printf.h"
 
 #include "hid/common/actions.h"
 
@@ -401,6 +402,7 @@ static int show_copyright = 0;
 static int show_defaults = 0;
 static int show_actions = 0;
 static int do_dump_actions = 0;
+static char *grid_units;
 
 HID_Attribute main_attribute_list[] = {
   {"help", "Show Help", HID_Boolean, 0, 0, {0, 0, 0}, 0, &show_help},
@@ -417,7 +419,7 @@ HID_Attribute main_attribute_list[] = {
    {0, 0, 0}, 0,
    &do_dump_actions},
 
-  BSET (grid_units_mm, 0, "grid-units-mm", 0),
+  {"grid-units", "Default grid units (mm|mil)", HID_String, 0, 0, {0, "mil", 0}, 0, &grid_units},
 
   COLOR (BlackColor, "#000000", "black-color", "color for black"),
   COLOR (WhiteColor, "#ffffff", "white-color", "color for white"),
@@ -490,8 +492,8 @@ HID_Attribute main_attribute_list[] = {
 	"Initial thickness of new lines."),
   ISET (RatThickness, MIL_TO_COORD(10), "rat-thickness", 0),
   ISET (Keepaway, MIL_TO_COORD(10), "keepaway", 0),
-  ISET (MaxWidth, MIL_TO_COORD(MIL_TO_COORD(60)), "default-PCB-width", 0),
-  ISET (MaxHeight, MIL_TO_COORD(MIL_TO_COORD(50)), "default-PCB-height", 0),
+  ISET (MaxWidth, MIL_TO_COORD(6000), "default-PCB-width", 0),
+  ISET (MaxHeight, MIL_TO_COORD(5000), "default-PCB-height", 0),
   ISET (TextScale, 100, "text-scale", 0),
   ISET (AlignmentDistance, MIL_TO_COORD(2), "alignment-distance", 0),
   ISET (Bloat, MIL_TO_COORD(10), "bloat", 0),
@@ -502,15 +504,7 @@ HID_Attribute main_attribute_list[] = {
   ISET (minRing, MIL_TO_COORD(10), "min-ring", "DRC minimum annular ring"),
 
   ISET (Grid, MIL_TO_COORD(10), "grid", 0),
-  ISET (grid_increment_mm, MM_TO_COORD (0.1), "grid-increment-mm", 0),
-  ISET (grid_increment_mil, MIL_TO_COORD (5.0), "grid-increment-mil", 0),
-  ISET (size_increment_mm, MM_TO_COORD (0.2), "size-increment-mm", 0),
-  ISET (size_increment_mil, MIL_TO_COORD (10.0), "size-increment-mil", 0),
-  ISET (line_increment_mm, MM_TO_COORD (0.1), "line-increment-mm", 0),
-  ISET (line_increment_mil, MIL_TO_COORD (5.0), "line-increment-mil", 0),
-  ISET (clear_increment_mm, MM_TO_COORD (0.05), "clear-increment-mm", 0),
-  ISET (clear_increment_mil, MIL_TO_COORD (2.0), "clear-increment-mil", 0),
-  RSET (IsleArea, MIL_TO_COORD(1400) * MIL_TO_COORD(1400), "minimum polygon area", 0),
+  RSET (IsleArea, MIL_TO_COORD(100) * MIL_TO_COORD(100), "minimum polygon area", 0),
 
   ISET (BackupInterval, 60, "backup-interval", 0),
 
@@ -645,7 +639,12 @@ REGISTER_ATTRIBUTES (main_attribute_list)
     Settings.GnetlistProgram = strdup ("gnetlist");
   }
 
+  if (grid_units)
+    Settings.grid_unit = get_unit_struct (grid_units);
+  if (!grid_units || Settings.grid_unit == NULL)
+    Settings.grid_unit = get_unit_struct ("mil");
 
+  Settings.increments = get_increments_struct (Settings.grid_unit->suffix);
 }
 
 /* ---------------------------------------------------------------------- 

commit 84f6074fbfd11392f93ad53318a735355bae2864
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Introduce new structures (unit, increment) to pcb-printf
    
    Constants for gui spinbox steps are now in pcb-printf.h:
      Unit.step_tiny
      Unit.step_small
      Unit.step_medium
      Unit.step_large
      Unit.step_huge
    
    Additionally, the default/max/min values for the preferences
    Increments tab are in their own structure in pcb-printf.h.
    
    These changes are needed to bring all unit-specific constants
    into one place. The spinbox values can be shared by gtk and
    lesstif.

diff --git a/src/misc.c b/src/misc.c
index a0aa5e3..83e2bb7 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -163,10 +163,10 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
   if (units && *units)
     {
       int i;
-      double sf = unit_to_coord (units);
-      if (sf != -1)
+      const Unit *unit = get_unit_struct (units);
+      if (unit != NULL)
         {
-          value *= sf;
+          value  = unit_to_coord (unit, value);
           scaled = 1;
         }
       if (extra_units)
@@ -187,7 +187,7 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
   if (!scaled && default_unit && *default_unit)
     {
       int i;
-      double sf = unit_to_coord (default_unit);
+      const Unit *unit = get_unit_struct (default_unit);
       if (extra_units)
         for (i = 0; *extra_units[i].suffix; ++i)
           if (strcmp (extra_units[i].suffix, default_unit) == 0)
@@ -197,8 +197,8 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
                 value /= 100.0;
               scaled = 1;
             }
-      if (!scaled && sf != -1)
-        value *= sf;
+      if (!scaled && unit != NULL)
+        value = unit_to_coord (unit, value);
     }
 
   return value;
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 8b086a1..895ae12 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -32,42 +32,110 @@
 
 #include "pcb-printf.h"
 
-enum e_family { METRIC, IMPERIAL };
-enum e_suffix { NO_SUFFIX, SUFFIX, FILE_MODE };
-
-struct unit {
-  const char *suffix;
-  char printf_code;
-  double scale_factor;
-  enum e_family family;
-  enum e_allow  allow;
-  int default_prec;
-};
+/* Helper macros for tables */
+#define MM_TO_COORD3(a,b,c)		MM_TO_COORD (a), MM_TO_COORD (b), MM_TO_COORD (c)
+#define MIL_TO_COORD3(a,b,c)		MIL_TO_COORD (a), MIL_TO_COORD (b), MIL_TO_COORD (c)
+#define MM_TO_COORD5(a,b,c,d,e)		MM_TO_COORD (a), MM_TO_COORD (b), MM_TO_COORD (c),	\
+                              		MM_TO_COORD (d), MM_TO_COORD (e)
+#define MIL_TO_COORD5(a,b,c,d,e)	MIL_TO_COORD (a), MIL_TO_COORD (b), MIL_TO_COORD (c),	\
+                               		MIL_TO_COORD (d), MIL_TO_COORD (e)
 
 /* These should be kept in order of smallest scale_factor
  * to largest -- the code uses this ordering when finding
  * the best scale to use for a group of measures */
-static struct unit Units[] = {
-  { "km", 'k', 0.000001, METRIC, ALLOW_KM, 5 },
-  { "m",  'f', 0.001,    METRIC, ALLOW_M,  5 },
-  { "cm", 'e', 0.1,      METRIC, ALLOW_CM, 5 },
-  { "mm", 'm', 1,        METRIC, ALLOW_MM, 4 },
-  { "um", 'u', 1000,     METRIC, ALLOW_UM, 2 },
-  { "nm", 'n', 1000000,  METRIC, ALLOW_NM, 0 },
-
-  { "in",   'i', 0.001, IMPERIAL, ALLOW_IN,   5 },
-  { "inch",  0 , 0.001, IMPERIAL, NO_PRINT,   0 },
-  { "mil",  'l', 1,     IMPERIAL, ALLOW_MIL,  2 },
-  { "cmil", 'c', 100,   IMPERIAL, ALLOW_CMIL, 0 }
+static Unit *Units;
+static int n_units;
+/* The function is needed to avoid "non-constant initializer"
+ *  errors on the internationalized unit suffixes. */
+void initialize_units()
+{
+  int i;
+  static Unit rv[] = {
+    { "km", NULL, 'k', 0.000001, METRIC, ALLOW_KM, 5,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+    { "m",  NULL, 'f', 0.001,    METRIC, ALLOW_M,  5,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+    { "cm", NULL, 'e', 0.1,      METRIC, ALLOW_CM, 5,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+    { "mm", NULL, 'm', 1,        METRIC, ALLOW_MM, 4,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+    { "um", NULL, 'u', 1000,     METRIC, ALLOW_UM, 2,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+    { "nm", NULL, 'n', 1000000,  METRIC, ALLOW_NM, 0,
+            MM_TO_COORD5 (0.005, 0.05, 0.25, 5.0, 25.0) },
+
+    { "in",   NULL, 'i', 0.001, IMPERIAL, ALLOW_IN,   5,
+              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
+    { "inch", NULL,  0 , 0.001, IMPERIAL, NO_PRINT,   0,
+              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
+    { "mil",  NULL, 'l', 1,     IMPERIAL, ALLOW_MIL,  2,
+              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) },
+    { "cmil", NULL, 'c', 100,   IMPERIAL, ALLOW_CMIL, 0,
+              MIL_TO_COORD5 (0.1, 1.0, 5.0, 100.0, 1000.0) }
+  };
+  n_units = (sizeof rv / sizeof rv[0]);
+  for (i = 0; i < n_units; ++i)
+    rv[i].in_suffix = _(rv[i].suffix);
+  Units = rv;
+}
+/* This list -must- contain all printable units from the above list */
+/* For now I have just copy/pasted the same values for all metric
+ * units and the same values for all imperial ones */
+static Increments increments[] = {
+  /* TABLE FORMAT   |  default  |  min  |  max
+   *          grid  |           |       |
+   *          size  |           |       |
+   *          line  |           |       |
+   *         clear  |           |       |
+   */
+  { "km", MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+  { "m",  MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+  { "cm", MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+  { "mm", MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+  { "um", MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+  { "nm", MM_TO_COORD3 (0.1,  0.01,  1.0),
+          MM_TO_COORD3 (0.2,  0.01,  0.5),
+          MM_TO_COORD3 (0.1,  0.005, 0.5),
+          MM_TO_COORD3 (0.05, 0.005, 0.5) },
+
+  { "cmil", MIL_TO_COORD3 (5,  1,   25),
+            MIL_TO_COORD3 (10, 1,   10),
+            MIL_TO_COORD3 (5,  0.5, 10),
+            MIL_TO_COORD3 (2,  0.5, 10) },
+  { "mil",  MIL_TO_COORD3 (5,  1,   25),
+            MIL_TO_COORD3 (10, 1,   10),
+            MIL_TO_COORD3 (5,  0.5, 10),
+            MIL_TO_COORD3 (2,  0.5, 10) },
+  { "in",   MIL_TO_COORD3 (5,  1,   25),
+            MIL_TO_COORD3 (10, 1,   10),
+            MIL_TO_COORD3 (5,  0.5, 10),
+            MIL_TO_COORD3 (2,  0.5, 10) },
 };
-#define N_UNITS ((int) (sizeof Units / sizeof Units[0]))
+#define N_INCREMENTS (sizeof increments / sizeof increments[0])
 
-/* Scale factor lookup functions for Unit[] table */
-double coord_to_unit (const char *suffix)
+/* Obtain a unit object from its (non-international) suffix */
+const Unit *get_unit_struct (const char *suffix)
 {
   int i;
   int s_len = strlen (suffix);
 
+  if (Units == NULL) initialize_units();
+
   /* Also understand plural suffixes: "inches", "mils" */
   if (s_len > 2)
     {
@@ -78,23 +146,38 @@ double coord_to_unit (const char *suffix)
     }
 
   /* Do lookup */
-  for (i = 0; i < N_UNITS; ++i)
-    {
-      if (strncmp (suffix, Units[i].suffix, s_len) == 0)
-        {
-          double base = Units[i].family == METRIC
-                          ? COORD_TO_MM (1)
-                          : COORD_TO_MIL (1);
-          return Units[i].scale_factor * base;
-        }
-    }
-  /* Signal failure */
-  return -1;
+  for (i = 0; i < n_units; ++i)
+    if (strncmp (suffix, Units[i].suffix, s_len) == 0)
+      return &Units[i];
+  return NULL;
+}
+
+/* Obtain a increment object from its (non-international) suffix */
+Increments *get_increments_struct (const char *suffix)
+{
+  int i;
+  /* Do lookup */
+  for (i = 0; i < N_INCREMENTS; ++i)
+    if (strcmp (suffix, increments[i].suffix) == 0)
+      return &increments[i];
+  return NULL;
 }
 
-double unit_to_coord (const char *suffix)
+/* Scale factor lookup functions for Unit[] table */
+double coord_to_unit (const Unit *unit, Coord x)
+{
+  double base;
+  if (unit == NULL)
+    return -1;
+  base = unit->family == METRIC
+           ? COORD_TO_MM (1)
+           : COORD_TO_MIL (1);
+  return x * unit->scale_factor * base;
+}
+
+Coord unit_to_coord (const Unit *unit, double x)
 {
-  return 1.0 / coord_to_unit (suffix);
+  return x / coord_to_unit (unit, 1);
 }
 
 static int min_sig_figs(double d)
@@ -127,6 +210,8 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
   const char *suffix;
   int i, n;
 
+  if (Units == NULL) initialize_units();
+
   value = malloc (n_coords * sizeof *value);
   buff  = g_string_new ("");
 
@@ -172,7 +257,7 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
 
   /* Determine scale factor -- find smallest unit that brings
    * the whole group above unity */
-  for (n = 0; n < N_UNITS; ++n)
+  for (n = 0; n < n_units; ++n)
     {
       if ((Units[n].allow & allow) != 0 && (Units[n].family == family))
         {
@@ -186,7 +271,7 @@ static gchar *CoordsToString(Coord coord[], int n_coords, const char *printf_spe
         }
     }
   /* If nothing worked, wind back to the smallest allowable unit */
-  if (n == N_UNITS)
+  if (n == n_units)
     {
       do {
         --n;
@@ -264,6 +349,8 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
   if (string == NULL || spec == NULL)
     return NULL;
 
+  if (Units == NULL) initialize_units();
+
   while(*fmt)
     {
       enum e_suffix suffix = NO_SUFFIX;
@@ -388,7 +475,7 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
                   unit_str = CoordsToString(value, 2, spec->str, ALLOW_MM | ALLOW_MIL, suffix);
                   break;
                 case '*':
-                  for (i = 0; i < N_UNITS; ++i)
+                  for (i = 0; i < n_units; ++i)
                     if (strcmp (ext_unit, Units[i].suffix) == 0)
                       unit_str = CoordsToString(value, 1, spec->str, Units[i].allow, suffix);
                   if (unit_str == NULL)
@@ -404,7 +491,7 @@ static gchar *pcb_vprintf(const char *fmt, va_list args)
                   mask = va_arg(args, enum e_allow);
                   break;
                 default:
-                  for (i = 0; i < N_UNITS; ++i)
+                  for (i = 0; i < n_units; ++i)
                     if (*fmt == Units[i].printf_code)
                       unit_str = CoordsToString(value, 1, spec->str, Units[i].allow, suffix);
                   if (unit_str == NULL)
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index c41fe7b..b941c4d 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -90,8 +90,49 @@ enum e_allow {
   ALLOW_ALL = ~0
 };
 
-double coord_to_unit (const char *suffix);
-double unit_to_coord (const char *suffix);
+enum e_family { METRIC, IMPERIAL };
+enum e_suffix { NO_SUFFIX, SUFFIX, FILE_MODE };
+
+typedef struct unit {
+  const char *suffix;
+  const char *in_suffix;	/* internationalized suffix */
+  char printf_code;
+  double scale_factor;
+  enum e_family family;
+  enum e_allow  allow;
+  int default_prec;
+  /* used for gui spinboxes */
+  Coord step_tiny;
+  Coord step_small;
+  Coord step_medium;
+  Coord step_large;
+  Coord step_huge;
+} Unit;
+
+typedef struct increments {
+  const char *suffix;
+  /* key g and <shift>g value  */
+  Coord grid;
+  Coord grid_min;
+  Coord grid_max;
+  /* key s and <shift>s value  */
+  Coord size;
+  Coord size_min;
+  Coord size_max;
+  /* key l and <shift>l value  */
+  Coord line;
+  Coord line_min;
+  Coord line_max;
+  /* key k and <shift>k value  */
+  Coord clear;
+  Coord clear_min;
+  Coord clear_max;
+} Increments;
+
+const Unit *get_unit_struct (const char *suffix);
+double coord_to_unit (const Unit *, Coord);
+Coord  unit_to_coord (const Unit *, double);
+Increments *get_increments_struct (const char *suffix);
 
 int pcb_fprintf(FILE *f, const char *fmt, ...);
 int pcb_sprintf(char *string, const char *fmt, ...);

commit 0a3182d50e4960531c26f306e76434eefea1c099
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Add scale factor lookups to pcb_printf.c, tell GetValue to use them
    
    GetValue and pcb-printf have their own lookup tables to determine
    scale factors. To unify them, this patch adds two functions to pcb-
    printf, coord_to_unit and unit_to_coord.
    
    These a const char *suffix and return an appropriate scale factor.
    
    I have also added a NO_PRINT entry to the allow_mask array for
    suffixes like "inch" that we can read but never output.
    
    The definitive unit lookup table should now be in pcb_printf.c. Any
    other tables used in the code should be merged into this.

diff --git a/src/misc.c b/src/misc.c
index e1dff74..a0aa5e3 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -65,6 +65,7 @@
 #include "mymem.h"
 #include "misc.h"
 #include "move.h"
+#include "pcb-printf.h"
 #include "polygon.h"
 #include "remove.h"
 #include "rtree.h"
@@ -127,15 +128,6 @@ GetValue (const char *val, const char *units, bool * absolute)
 double
 GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_units, const char *default_unit)
 {
-  static UnitList default_units = {
-    { "mm",   MM_TO_COORD(1), 0 },
-    { "um",   MM_TO_COORD(0.001), 0 },
-    { "nm",   MM_TO_COORD(0.000001), 0 },
-    { "mil",  MIL_TO_COORD(1), 0 },
-    { "cmil", MIL_TO_COORD(0.01), 0 },
-    { "in",   MIL_TO_COORD(1000), 0 },
-    { "", 1, 0 }
-  };
   double value;
   int n = -1;
   bool scaled = 0;
@@ -171,15 +163,11 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
   if (units && *units)
     {
       int i;
-      for (i = 0; *default_units[i].suffix; ++i)
+      double sf = unit_to_coord (units);
+      if (sf != -1)
         {
-          if (strncmp (units, default_units[i].suffix, strlen(default_units[i].suffix)) == 0)
-            {
-              value *= default_units[i].scale;
-              if (default_units[i].flags & UNIT_PERCENT)
-                value /= 100.0;
-              scaled = 1;
-            }
+          value *= sf;
+          scaled = 1;
         }
       if (extra_units)
         {
@@ -199,13 +187,7 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
   if (!scaled && default_unit && *default_unit)
     {
       int i;
-      for (i = 0; *default_units[i].suffix; ++i)
-        if (strcmp (default_units[i].suffix, default_unit) == 0)
-          {
-            value *= default_units[i].scale;
-            if (default_units[i].flags & UNIT_PERCENT)
-              value /= 100.0;
-          }
+      double sf = unit_to_coord (default_unit);
       if (extra_units)
         for (i = 0; *extra_units[i].suffix; ++i)
           if (strcmp (extra_units[i].suffix, default_unit) == 0)
@@ -213,7 +195,10 @@ GetValueEx (const char *val, const char *units, bool * absolute, UnitList extra_
               value *= extra_units[i].scale;
               if (extra_units[i].flags & UNIT_PERCENT)
                 value /= 100.0;
+              scaled = 1;
             }
+      if (!scaled && sf != -1)
+        value *= sf;
     }
 
   return value;
diff --git a/src/pcb-printf.c b/src/pcb-printf.c
index 4410691..8b086a1 100644
--- a/src/pcb-printf.c
+++ b/src/pcb-printf.c
@@ -56,11 +56,47 @@ static struct unit Units[] = {
   { "nm", 'n', 1000000,  METRIC, ALLOW_NM, 0 },
 
   { "in",   'i', 0.001, IMPERIAL, ALLOW_IN,   5 },
+  { "inch",  0 , 0.001, IMPERIAL, NO_PRINT,   0 },
   { "mil",  'l', 1,     IMPERIAL, ALLOW_MIL,  2 },
   { "cmil", 'c', 100,   IMPERIAL, ALLOW_CMIL, 0 }
 };
 #define N_UNITS ((int) (sizeof Units / sizeof Units[0]))
 
+/* Scale factor lookup functions for Unit[] table */
+double coord_to_unit (const char *suffix)
+{
+  int i;
+  int s_len = strlen (suffix);
+
+  /* Also understand plural suffixes: "inches", "mils" */
+  if (s_len > 2)
+    {
+      if (suffix[s_len - 2] == 'e' && suffix[s_len - 1] == 's')
+        s_len -= 2;
+      else if (suffix[s_len - 1] == 's')
+        s_len -= 1;
+    }
+
+  /* Do lookup */
+  for (i = 0; i < N_UNITS; ++i)
+    {
+      if (strncmp (suffix, Units[i].suffix, s_len) == 0)
+        {
+          double base = Units[i].family == METRIC
+                          ? COORD_TO_MM (1)
+                          : COORD_TO_MIL (1);
+          return Units[i].scale_factor * base;
+        }
+    }
+  /* Signal failure */
+  return -1;
+}
+
+double unit_to_coord (const char *suffix)
+{
+  return 1.0 / coord_to_unit (suffix);
+}
+
 static int min_sig_figs(double d)
 {
   char buf[50];
diff --git a/src/pcb-printf.h b/src/pcb-printf.h
index 31346f4..c41fe7b 100644
--- a/src/pcb-printf.h
+++ b/src/pcb-printf.h
@@ -67,6 +67,7 @@
 #define	PCB_PCB_PRINTF_H
 
 enum e_allow {
+  NO_PRINT = 0,		/* suffixes we can read but not print (i.e., "inch") */
   ALLOW_NM = 1,
   ALLOW_UM = 2,
   ALLOW_MM = 4,
@@ -89,6 +90,9 @@ enum e_allow {
   ALLOW_ALL = ~0
 };
 
+double coord_to_unit (const char *suffix);
+double unit_to_coord (const char *suffix);
+
 int pcb_fprintf(FILE *f, const char *fmt, ...);
 int pcb_sprintf(char *string, const char *fmt, ...);
 int pcb_printf(const char *fmt, ...);

commit b605120493b2d8fab063ef11bf74d40bf80dd018
Author: Andrew Poelstra <asp11@xxxxxx>
Commit: Andrew Poelstra <asp11@xxxxxx>

    Convert grid/increments from double to Coord
    
    Since Coord is an integer unit, there will be (often
    severe) precision errors until we convert the base unit
    to nm.

diff --git a/src/action.c b/src/action.c
index 30d9745..f1083f7 100644
--- a/src/action.c
+++ b/src/action.c
@@ -2193,30 +2193,19 @@ ActionSetValue (int argc, char **argv, int x, int y)
 	  break;
 
 	case F_Grid:
-	  if (!absolute)
+	  if (absolute)
+	    SetGrid (value, false);
+	  else
 	    {
-	      if ((value == (int) value && PCB->Grid == (int) PCB->Grid)
-		  || (value != (int) value && PCB->Grid != (int) PCB->Grid)
-                  || PCB->Grid ==1)
-                {
-                  /* 
-		   * On the way down short against the minimum 
-		   * PCB drawing unit 
-		   */
-                  if ((value + PCB->Grid) < 1)
-                     SetGrid (1, false);
-                  else if (PCB->Grid == 1)
-                    SetGrid ( value, false);
-                  else
-                    SetGrid (value + PCB->Grid, false);
-                }
-
-	      else
-		Message (_
-			 ("Don't combine metric/English grids like that!\n"));
+              /* On the way down, short against the minimum 
+               * PCB drawing unit */
+              if ((value + PCB->Grid) < 1)
+                SetGrid (1, false);
+              else if (PCB->Grid == 1)
+                SetGrid (value, false);
+              else
+                SetGrid (value + PCB->Grid, false);
 	    }
-	  else
-	    SetGrid (value, false);
 	  break;
 
 	case F_LineSize:
@@ -2374,13 +2363,12 @@ static int
 ActionDisperseElements (int argc, char **argv, int x, int y)
 {
   char *function = ARG (0);
-  long minx, miny, maxy, dx, dy;
+  Coord minx = GAP,
+    miny = GAP,
+    maxy = GAP,
+    dx, dy;
   int all = 0, bad = 0;
 
-  minx = GAP;
-  miny = GAP;
-  maxy = GAP;
-
   if (!function || !*function)
     {
       bad = 1;
@@ -2424,13 +2412,13 @@ ActionDisperseElements (int argc, char **argv, int x, int y)
 	dx = minx - element->BoundingBox.X1;
 
 	/* snap to the grid */
-	dx -= (element->MarkX + dx) % (long) (PCB->Grid);
+	dx -= (element->MarkX + dx) % PCB->Grid;
 
 	/* 
 	 * and add one grid size so we make sure we always space by GAP or
 	 * more
 	 */
-	dx += (long) (PCB->Grid);
+	dx += PCB->Grid;
 
 	/* Figure out if this row has room.  If not, start a new row */
 	if (GAP + element->BoundingBox.X2 + dx > PCB->MaxWidth)
@@ -2444,10 +2432,10 @@ ActionDisperseElements (int argc, char **argv, int x, int y)
 	dy = miny - element->BoundingBox.Y1;
 
 	/* snap to the grid */
-	dx -= (element->MarkX + dx) % (long) (PCB->Grid);
-	dx += (long) (PCB->Grid);
-	dy -= (element->MarkY + dy) % (long) (PCB->Grid);
-	dy += (long) (PCB->Grid);
+	dx -= (element->MarkX + dx) % PCB->Grid;
+	dx += PCB->Grid;
+	dy -= (element->MarkY + dy) % PCB->Grid;
+	dy += PCB->Grid;
 
 	/* move the element */
 	MoveElementLowLevel (PCB->Data, element, dx, dy);
@@ -2596,8 +2584,7 @@ instead of only the biggest one.
 @item ToggleGrid
 Resets the origin of the current grid to be wherever the mouse pointer
 is (not where the crosshair currently is).  If you provide two numbers
-after this, the origin is set to that coordinate.  The numbers are in
-PCB internal units, currently 1/100 mil.
+after this, the origin is set to that coordinate.
 
 @item Grid
 Toggles whether the grid is displayed or not.
@@ -2821,10 +2808,9 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	  /* shift grid alignment */
 	case F_ToggleGrid:
 	  {
-	    float oldGrid;
+	    Coord oldGrid = PCB->Grid;
 
-	    oldGrid = PCB->Grid;
-	    PCB->Grid = 1.0;
+	    PCB->Grid = 1;
 	    if (MoveCrosshairAbsolute (Crosshair.X, Crosshair.Y))
 	      notify_crosshair_change (true);	/* first notify was in MoveCrosshairAbs */
 	    SetGrid (oldGrid, true);
@@ -2939,9 +2925,8 @@ ActionDisplay (int argc, char **argv, int childX, int childY)
 	case F_ToggleGrid:
 	  if (argc > 2)
 	    {
-	      /* FIXME: units */
-	      PCB->GridOffsetX = atoi (argv[1]);
-	      PCB->GridOffsetY = atoi (argv[2]);
+	      PCB->GridOffsetX = GetValue (argv[1], NULL, NULL);
+	      PCB->GridOffsetY = GetValue (argv[2], NULL, NULL);
 	      if (Settings.DrawGrid)
 		Redraw ();
 	    }
@@ -5465,8 +5450,8 @@ ActionSelect (int argc, char **argv, int x, int y)
 	    SetBufferNumber (MAX_BUFFER - 1);
 	    ClearBuffer (PASTEBUFFER);
 	    gui->get_coords (_("Select the Element's Mark Location"), &x, &y);
-	    x = GRIDFIT_X (x, PCB->Grid);
-	    y = GRIDFIT_Y (y, PCB->Grid);
+	    x = GridFit (x, PCB->Grid, PCB->GridOffsetX);
+	    y = GridFit (y, PCB->Grid, PCB->GridOffsetY);
 	    AddSelectedToBuffer (PASTEBUFFER, x, y, true);
 	    SaveUndoSerialNumber ();
 	    RemoveSelected ();
diff --git a/src/autoplace.c b/src/autoplace.c
index 65eef92..991cf9e 100644
--- a/src/autoplace.c
+++ b/src/autoplace.c
@@ -102,8 +102,8 @@ const struct
   float gamma;			/* annealing schedule constant */
   int good_ratio;		/* ratio of moves to good moves for halting */
   bool fast;			/* ignore SMD/pin conflicts */
-  int large_grid_size;		/*snap perturbations to this grid when T is high */
-  int small_grid_size;		/* snap to this grid when T is small. */
+  Coord large_grid_size;	/* snap perturbations to this grid when T is high */
+  Coord small_grid_size;	/* snap to this grid when T is small. */
 }
 /* wire cost is manhattan distance (in mils), thus 1 inch = 1000 */
 CostParameter =
@@ -121,8 +121,8 @@ CostParameter =
     0.75,			/* annealing schedule constant: 0.85 */
     40,				/* halt when there are 60 times as many moves as good moves */
     false,			/* don't ignore SMD/pin conflicts */
-    100,			/* coarse grid is 100 mils */
-    10,				/* fine grid is 10 mils */
+    MIL_TO_COORD (100),		/* coarse grid is 100 mils */
+    MIL_TO_COORD (10),		/* fine grid is 10 mils */
 };
 
 typedef struct
@@ -634,14 +634,14 @@ createPerturbation (PointerListTypePtr selected, double T)
     {
     case 0:
       {				/* shift! */
-	int grid;
-	double scaleX = MAX (250, MIN (sqrt (T), PCB->MaxWidth / 3));
-	double scaleY = MAX (250, MIN (sqrt (T), PCB->MaxHeight / 3));
+	Coord grid;
+	double scaleX = CLAMP (sqrt (T), MIL_TO_COORD (2.5), PCB->MaxWidth / 3);
+	double scaleY = CLAMP (sqrt (T), MIL_TO_COORD (2.5), PCB->MaxHeight / 3);
 	pt.which = SHIFT;
 	pt.DX = scaleX * 2 * ((((double) random ()) / RAND_MAX) - 0.5);
 	pt.DY = scaleY * 2 * ((((double) random ()) / RAND_MAX) - 0.5);
 	/* snap to grid. different grids for "high" and "low" T */
-	grid = (T > 1000) ? CostParameter.large_grid_size :
+	grid = (T > MIL_TO_COORD (10)) ? CostParameter.large_grid_size :
 	  CostParameter.small_grid_size;
 	/* (round away from zero) */
 	pt.DX = ((pt.DX / grid) + SGN (pt.DX)) * grid;
@@ -788,13 +788,13 @@ AutoPlaceSelected (void)
   /* simulated annealing */
   {				/* compute T0 by doing a random series of moves. */
     const int TRIALS = 10;
-    const double Tx = 3e5, P = 0.95;
+    const double Tx = MIL_TO_COORD (300), P = 0.95;
     double Cs = 0.0;
     int i;
     C0 = ComputeCost (Nets, Tx, Tx);
     for (i = 0; i < TRIALS; i++)
       {
-	pt = createPerturbation (&Selected, 1e6);
+	pt = createPerturbation (&Selected, INCH_TO_COORD (1));
 	doPerturb (&pt, false);
 	Cs += fabs (ComputeCost (Nets, Tx, Tx) - C0);
 	doPerturb (&pt, true);
diff --git a/src/crosshair.c b/src/crosshair.c
index 76b072b..2b0e9b8 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -688,6 +688,18 @@ DrawMark (void)
                   Marked.X - MARK_SIZE, Marked.Y + MARK_SIZE);
 }
 
+/* ---------------------------------------------------------------------------
+ * Returns the nearest grid-point to the given Coord
+ */
+Coord
+GridFit (Coord x, Coord grid_spacing, Coord grid_offset)
+{
+  x -= grid_offset;
+  x = grid_spacing * round ((double) x / grid_spacing);
+  x += grid_offset;
+  return x;
+}
+
 
 /* ---------------------------------------------------------------------------
  * notify the GUI that data relating to the crosshair is being changed.
@@ -793,7 +805,7 @@ struct snap_data {
   CrosshairType *crosshair;
   double nearest_sq_dist;
   bool nearest_is_grid;
-  LocationType x, y;
+  Coord x, y;
 };
 
 /* Snap to a given location if it is the closest thing we found so far.
@@ -914,30 +926,30 @@ check_snap_offgrid_line (struct snap_data *snap_data,
  * recalculates the passed coordinates to fit the current grid setting
  */
 void
-FitCrosshairIntoGrid (LocationType X, LocationType Y)
+FitCrosshairIntoGrid (Coord X, Coord Y)
 {
-  LocationType nearest_grid_x, nearest_grid_y;
+  Coord nearest_grid_x, nearest_grid_y;
   void *ptr1, *ptr2, *ptr3;
   struct snap_data snap_data;
   int ans;
 
-  Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X));
-  Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y));
+  Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX);
+  Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY);
 
   if (PCB->RatDraw)
     {
-      nearest_grid_x = -600;
-      nearest_grid_y = -600;
+      nearest_grid_x = -MIL_TO_COORD (6);
+      nearest_grid_y = -MIL_TO_COORD (6);
     }
   else
     {
-      nearest_grid_x = GRIDFIT_X (Crosshair.X, PCB->Grid);
-      nearest_grid_y = GRIDFIT_Y (Crosshair.Y, PCB->Grid);
+      nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX);
+      nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY);
 
       if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
 	{
-	  int dx = Crosshair.X - Marked.X;
-	  int dy = Crosshair.Y - Marked.Y;
+	  Coord dx = Crosshair.X - Marked.X;
+	  Coord dy = Crosshair.Y - Marked.Y;
 	  if (ABS (dx) > ABS (dy))
 	    nearest_grid_y = Marked.Y;
 	  else
diff --git a/src/crosshair.h b/src/crosshair.h
index 15b3470..3fbd998 100644
--- a/src/crosshair.h
+++ b/src/crosshair.h
@@ -34,18 +34,13 @@
 #include "global.h"
 
 /* ---------------------------------------------------------------------------
- * fits screen coordinates into grid
- */
-#define	GRIDFIT_X(x,g)	(int)(0.5 + ((int)(((x) -PCB->GridOffsetX + g/2) /(g)) *(g)) +PCB->GridOffsetX)
-#define	GRIDFIT_Y(y,g)	(int)(0.5 + ((int)(((y) -PCB->GridOffsetY + g/2) /(g)) *(g)) +PCB->GridOffsetY)
-
-/* ---------------------------------------------------------------------------
  * all possible states of an attached object
  */
 #define	STATE_FIRST		0	/* initial state */
 #define	STATE_SECOND	1
 #define	STATE_THIRD		2
 
+Coord GridFit (Coord x, Coord grid_spacing, Coord grid_offset);
 void notify_crosshair_change (bool changes_complete);
 void notify_mark_change (bool changes_complete);
 void HideCrosshair (void);
diff --git a/src/djopt.c b/src/djopt.c
index d25d621..80fa3c1 100644
--- a/src/djopt.c
+++ b/src/djopt.c
@@ -295,11 +295,11 @@ check2 (int srcline, corner_s * c, line_s * l)
 #define SWAP(a,b) { a^=b; b^=a; a^=b; }
 
 static int
-gridsnap (int n)
+gridsnap (Coord n)
 {
   if (n <= 0)
     return 0;
-  return n - n % (int) (Settings.Grid);
+  return n - n % (Settings.Grid);
 }
 
 /* Avoid commonly used names. */
@@ -1616,7 +1616,7 @@ orthopull_1 (corner_s * c, int fdir, int rdir, int any_sel)
     {
       if (pull < 0)
 	len += Settings.Grid - 1;
-      len -= len % (int) (Settings.Grid);
+      len = gridsnap (len);
     }
   if ((fdir == RIGHT && len == cs[0]->y) || (fdir == DOWN && len == cs[0]->x))
     return 0;
diff --git a/src/file.c b/src/file.c
index abdb444..ef37641 100644
--- a/src/file.c
+++ b/src/file.c
@@ -394,7 +394,6 @@ LoadPCB (char *Filename)
 {
   PCBTypePtr newPCB = CreateNewPCB (false);
   PCBTypePtr oldPCB;
-  bool units_mm;
 #ifdef DEBUG
   double elapsed;
   clock_t start, end;
@@ -438,9 +437,9 @@ LoadPCB (char *Filename)
       PCB->Filename = strdup (Filename);
       /* just in case a bad file saved file is loaded */
 
-      units_mm = (PCB->Grid != (int) PCB->Grid) ? true : false;
-
-      Settings.grid_units_mm = units_mm;
+      /* Use imperial if the grid is a multiple of .5cmil, else metric */
+      Settings.grid_units_mm = (1000000 * COORD_TO_MM (PCB->Grid) / 127.0) !=
+                                 (Coord) (1000000 * COORD_TO_MM (PCB->Grid)) / 127;
 
       sort_netlist ();
 
diff --git a/src/flags.c b/src/flags.c
index 499e59e..a167663 100644
--- a/src/flags.c
+++ b/src/flags.c
@@ -61,13 +61,13 @@ FlagCurrentStyle (int dummy)
 static int
 FlagGrid (int dummy)
 {
-  return PCB->Grid > 1.0;
+  return PCB->Grid > 1;
 }
 
 static int
 FlagGridSize (int dummy)
 {
-  return (int) (PCB->Grid + 0.5);
+  return PCB->Grid;
 }
 
 static int
diff --git a/src/fontmode.c b/src/fontmode.c
index 2575a33..04b230d 100644
--- a/src/fontmode.c
+++ b/src/fontmode.c
@@ -59,8 +59,8 @@ RCSID ("$Id$");
    should search the grid for the gridlines and use them to figure out
    where the symbols are. */
 
-#define CELL_SIZE	10000
-#define CELL_OFFSET	1000
+#define CELL_SIZE	MIL_TO_COORD (100)
+#define CELL_OFFSET	MIL_TO_COORD (10)
 
 #define XYtoSym(x,y) ((x1 + CELL_OFFSET) / CELL_SIZE - 1 \
 		      + 16 * ((y1 + CELL_OFFSET) / CELL_SIZE - 1))
@@ -93,7 +93,7 @@ FontEdit (int argc, char **argv, int Ux, int Uy)
     }
   PCB->MaxWidth = CELL_SIZE * 18;
   PCB->MaxHeight = CELL_SIZE * ((MAX_FONTPOSITION + 15) / 16 + 2);
-  PCB->Grid = 500.0;
+  PCB->Grid = MIL_TO_COORD (5);
   PCB->Data->Layer[0].Name = strdup ("Font");
   PCB->Data->Layer[1].Name = strdup ("OrigFont");
   PCB->Data->Layer[2].Name = strdup ("Width");
@@ -109,13 +109,13 @@ FontEdit (int argc, char **argv, int Ux, int Uy)
   font = &PCB->Font;
   for (s = 0; s <= MAX_FONTPOSITION; s++)
     {
-      int ox = (s % 16 + 1) * CELL_SIZE;
-      int oy = (s / 16 + 1) * CELL_SIZE;
-      int w, miny, maxy, maxx = 0;
+      Coord ox = (s % 16 + 1) * CELL_SIZE;
+      Coord oy = (s / 16 + 1) * CELL_SIZE;
+      Coord w, miny, maxy, maxx = 0;
 
       symbol = &font->Symbol[s];
 
-      miny = 500;
+      miny = MIL_TO_COORD (5);
       maxy = font->MaxHeight;
 
       for (l = 0; l < symbol->LineN; l++)
@@ -141,20 +141,20 @@ FontEdit (int argc, char **argv, int Ux, int Uy)
       w = maxx + symbol->Delta + ox;
       CreateDrawnLineOnLayer (lwidth,
 			      w, miny + oy,
-			      w, maxy + oy, 100, 100, NoFlags ());
+			      w, maxy + oy, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ());
     }
 
   for (l = 0; l < 16; l++)
     {
       int x = (l + 1) * CELL_SIZE;
-      CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, 100, 100,
-			      NoFlags ());
+      CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, MIL_TO_COORD (1),
+                              MIL_TO_COORD (1), NoFlags ());
     }
   for (l = 0; l <= MAX_FONTPOSITION / 16 + 1; l++)
     {
       int y = (l + 1) * CELL_SIZE;
-      CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, 100, 100,
-			      NoFlags ());
+      CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, MIL_TO_COORD (1),
+                              MIL_TO_COORD (1), NoFlags ());
     }
   return 0;
 }
@@ -218,9 +218,9 @@ FontSave (int argc, char **argv, int Ux, int Uy)
   for (ii = lwidth->Line; ii != NULL; ii = g_list_next (ii))
     {
       LineType *l = ii->data;
-      int x1 = l->Point1.X;
-      int y1 = l->Point1.Y;
-      int ox, s;
+      Coord x1 = l->Point1.X;
+      Coord y1 = l->Point1.Y;
+      Coord ox, s;
 
       s = XYtoSym (x1, y1);
       ox = (s % 16 + 1) * CELL_SIZE;
diff --git a/src/global.h b/src/global.h
index 0ae5d22..9341940 100644
--- a/src/global.h
+++ b/src/global.h
@@ -510,7 +510,7 @@ typedef struct PCBType
     GridOffsetY, MaxWidth,	/* allowed size */
     MaxHeight;
 
-  double Grid;			/* used grid with offsets */
+  Coord Grid;			/* used grid with offsets */
   double Zoom,			/* zoom factor */
     IsleArea,			/* minimum poly island to retain */
     ThermScale;			/* scale factor used with thermals */
@@ -637,7 +637,7 @@ typedef struct			/* some resources... */
     AlignmentDistance, Bloat,	/* default drc sizes */
     Shrink, minWid, minSlk, minDrill, minRing;
   int TextScale;		/* text scaling in % */
-  double Grid,			/* grid in pcb-units */
+  Coord Grid,			/* grid in pcb-units */
     grid_increment_mm,		/* key g and <shift>g value for mil units */
     grid_increment_mil,		/* key g and <shift>g value for mil units */
     size_increment_mm,		/* key s and <shift>s value for mil units */
diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
index 992f3e3..2ba295e 100644
--- a/src/hid/common/hidgl.c
+++ b/src/hid/common/hidgl.c
@@ -116,10 +116,10 @@ hidgl_draw_grid (BoxType *drawn_area)
   if (!Settings.DrawGrid)
     return;
 
-  x1 = GRIDFIT_X (MAX (0, drawn_area->X1), PCB->Grid);
-  y1 = GRIDFIT_Y (MAX (0, drawn_area->Y1), PCB->Grid);
-  x2 = GRIDFIT_X (MIN (PCB->MaxWidth, drawn_area->X2), PCB->Grid);
-  y2 = GRIDFIT_Y (MIN (PCB->MaxHeight, drawn_area->Y2), PCB->Grid);
+  x1 = GridFit (MAX (0, drawn_area->X1), PCB->Grid, PCB->GridOffsetX);
+  y1 = GridFit (MAX (0, drawn_area->Y1), PCB->Grid, PCB->GridOffsetY);
+  x2 = GridFit (MIN (PCB->MaxWidth, drawn_area->X2), PCB->Grid, PCB->GridOffsetX);
+  y2 = GridFit (MIN (PCB->MaxHeight, drawn_area->Y2), PCB->Grid, PCB->GridOffsetY);
 
   if (x1 > x2)
     {
diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index e9b5b3e..99472cd 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -149,8 +149,8 @@ ghid_draw_grid (void)
 {
   static GdkPoint *points = 0;
   static int npoints = 0;
-  int x1, y1, x2, y2, n, i;
-  double x, y;
+  Coord x1, y1, x2, y2, x, y;
+  int n, i;
   render_priv *priv = gport->render_priv;
 
   if (!Settings.DrawGrid)
@@ -172,20 +172,21 @@ ghid_draw_grid (void)
       gdk_gc_set_clip_origin (priv->grid_gc, 0, 0);
       set_clip (priv, priv->grid_gc);
     }
-  x1 = GRIDFIT_X (SIDE_X (gport->view_x0), PCB->Grid);
-  y1 = GRIDFIT_Y (SIDE_Y (gport->view_y0), PCB->Grid);
-  x2 = GRIDFIT_X (SIDE_X (gport->view_x0 + gport->view_width - 1), PCB->Grid);
-  y2 =
-    GRIDFIT_Y (SIDE_Y (gport->view_y0 + gport->view_height - 1), PCB->Grid);
+  x1 = GridFit (SIDE_X (gport->view_x0), PCB->Grid, PCB->GridOffsetX);
+  y1 = GridFit (SIDE_Y (gport->view_y0), PCB->Grid, PCB->GridOffsetY);
+  x2 = GridFit (SIDE_X (gport->view_x0 + gport->view_width - 1),
+                PCB->Grid, PCB->GridOffsetX);
+  y2 = GridFit (SIDE_Y (gport->view_y0 + gport->view_height - 1),
+                PCB->Grid, PCB->GridOffsetY);
   if (x1 > x2)
     {
-      int tmp = x1;
+      Coord tmp = x1;
       x1 = x2;
       x2 = tmp;
     }
   if (y1 > y2)
     {
-      int tmp = y1;
+      Coord tmp = y1;
       y1 = y2;
       y2 = tmp;
     }
@@ -197,7 +198,7 @@ ghid_draw_grid (void)
     x2 -= PCB->Grid;
   if (Vy (y2) >= gport->height)
     y2 -= PCB->Grid;
-  n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1;
+  n = (x2 - x1) / PCB->Grid + 1;
   if (n > npoints)
     {
       npoints = n + 10;
@@ -213,9 +214,8 @@ ghid_draw_grid (void)
     return;
   for (y = y1; y <= y2; y += PCB->Grid)
     {
-      int vy = Vy (y);
       for (i = 0; i < n; i++)
-	points[i].y = vy;
+	points[i].y = Vy (y);
       gdk_draw_points (gport->drawable, priv->grid_gc, points, n);
     }
 }
diff --git a/src/hid/gtk/gui-config.c b/src/hid/gtk/gui-config.c
index 79d543d..685e4b2 100644
--- a/src/hid/gtk/gui-config.c
+++ b/src/hid/gtk/gui-config.c
@@ -1157,7 +1157,7 @@ increment_spin_button_cb (GtkSpinButton * spin, void * dst)
   gdouble value;
 
   value = gtk_spin_button_get_value (spin);
-  *(gdouble *)dst = value;			/* Not using PCB units */
+  *(Coord *)dst = TO_PCB_UNITS (value);
 
 
   ghidgui->config_modified = TRUE;
@@ -1167,7 +1167,7 @@ static void
 config_increments_tab_create (GtkWidget * tab_vbox)
 {
   GtkWidget *vbox, *label;
-  gdouble *target;
+  Coord *target;
   gchar *str;
 
   /* Need a vbox we can destroy if user changes grid units.
diff --git a/src/hid/gtk/gui-misc.c b/src/hid/gtk/gui-misc.c
index cadd2aa..00791e3 100644
--- a/src/hid/gtk/gui-misc.c
+++ b/src/hid/gtk/gui-misc.c
@@ -82,55 +82,6 @@ ghid_cursor_position_relative_label_set_text (gchar * text)
   ghid_label_set_markup (ghidgui->cursor_position_relative_label, text);
 }
 
-void
-ghid_size_increment_get_value (const gchar * saction, gchar ** value,
-			       gchar ** units)
-{
-  gdouble increment;
-  gchar *fmt;
-  static gchar s_buf[64];
-
-  increment = Settings.grid_units_mm
-    ? Settings.size_increment_mm : Settings.size_increment_mil;
-  fmt = (*saction == '+') ? (gchar *)"+%f" : (gchar *)"-%f";
-  snprintf (s_buf, sizeof (s_buf), fmt, increment);
-  *value = s_buf;
-  *units = Settings.grid_units_mm ? (gchar *)"mm" : (gchar *)"mil";
-}
-
-void
-ghid_line_increment_get_value (const gchar * saction, gchar ** value,
-			       gchar ** units)
-{
-  gdouble increment;
-  gchar *fmt;
-  static gchar s_buf[64];
-
-  increment = Settings.grid_units_mm
-    ? Settings.line_increment_mm : Settings.line_increment_mil;
-  fmt = (*saction == '+') ? (gchar *)"+%f" : (gchar *)"-%f";
-  snprintf (s_buf, sizeof (s_buf), fmt, increment);
-  *value = s_buf;
-  *units = Settings.grid_units_mm ? (gchar *)"mm" : (gchar *)"mil";
-}
-
-void
-ghid_clear_increment_get_value (const gchar * saction, gchar ** value,
-				gchar ** units)
-{
-  gdouble increment;
-  gchar *fmt;
-  static gchar s_buf[64];
-
-  increment = Settings.grid_units_mm
-    ? Settings.clear_increment_mm : Settings.clear_increment_mil;
-  fmt = (*saction == '+') ? (gchar *)"+%f" : (gchar *)"-%f";
-  snprintf (s_buf, sizeof (s_buf), fmt, increment);
-  *value = s_buf;
-  *units = Settings.grid_units_mm ? (gchar *)"mm" : (gchar *)"mil";
-}
-
-
 static GdkCursorType
 gport_set_cursor (GdkCursorType shape)
 {
@@ -469,7 +420,7 @@ ghid_set_status_line_label (void)
             "<b>text</b>=%i%%  "
             "<b>buffer</b>=#%i"),
       Settings.ShowSolderSide ? _("solder") : _("component"),
-      (BDimension) PCB->Grid,
+      PCB->Grid,
       (int) Settings.GridFactor,
       flag, TEST_FLAG (RUBBERBANDFLAG, PCB) ? ",R  " : "  ",
       Settings.LineThickness,
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index c4da30f..bc15628 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -223,14 +223,6 @@ void ghid_set_menu_toggle_button (GtkActionGroup * ag,
 				  gchar * name, gboolean state);
 void ghid_pcb_saved_toggle_states_set (void);
 void ghid_sync_with_new_layout (void);
-void ghid_size_increment_get_value (const gchar * saction,
-				    gchar ** value, gchar ** units);
-void ghid_line_increment_get_value (const gchar * saction,
-				    gchar ** value, gchar ** units);
-void ghid_clear_increment_get_value (const gchar * saction,
-				     gchar ** value, gchar ** units);
-void ghid_grid_size_increment_get_value (const gchar * saction,
-					 gchar ** value, gchar ** units);
 
 void ghid_grid_setting_update_menu_actions (void);
 void ghid_change_selected_update_menu_actions (void);
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index ff6d8cd..d275af0 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -815,8 +815,8 @@ Benchmark (int argc, char **argv, int x, int y)
 static int
 Center(int argc, char **argv, int x, int y)
 {
-  x = GRIDFIT_X (x, PCB->Grid);
-  y = GRIDFIT_Y (y, PCB->Grid);
+  x = GridFit (x, PCB->Grid, PCB->GridOffsetX);
+  y = GridFit (y, PCB->Grid, PCB->GridOffsetY);
   view_left_x = x - (view_width * view_zoom) / 2;
   view_top_y = y - (view_height * view_zoom) / 2;
   lesstif_pan_fixup ();
@@ -2228,8 +2228,9 @@ draw_grid ()
 {
   static XPoint *points = 0;
   static int npoints = 0;
-  int x1, y1, x2, y2, n, prevx;
-  double x, y;
+  Coord x1, y1, x2, y2, prevx;
+  Coord x, y;
+  int n;
   static GC grid_gc = 0;
 
   if (!Settings.DrawGrid)
@@ -2244,8 +2245,8 @@ draw_grid ()
     }
   if (flip_x)
     {
-      x2 = GRIDFIT_X (Px (0), PCB->Grid);
-      x1 = GRIDFIT_X (Px (view_width), PCB->Grid);
+      x2 = GridFit (Px (0), PCB->Grid, PCB->GridOffsetX);
+      x1 = GridFit (Px (view_width), PCB->Grid, PCB->GridOffsetX);
       if (Vx (x2) < 0)
 	x2 -= PCB->Grid;
       if (Vx (x1) >= view_width)
@@ -2253,8 +2254,8 @@ draw_grid ()
     }
   else
     {
-      x1 = GRIDFIT_X (Px (0), PCB->Grid);
-      x2 = GRIDFIT_X (Px (view_width), PCB->Grid);
+      x1 = GridFit (Px (0), PCB->Grid, PCB->GridOffsetX);
+      x2 = GridFit (Px (view_width), PCB->Grid, PCB->GridOffsetX);
       if (Vx (x1) < 0)
 	x1 += PCB->Grid;
       if (Vx (x2) >= view_width)
@@ -2262,8 +2263,8 @@ draw_grid ()
     }
   if (flip_y)
     {
-      y2 = GRIDFIT_Y (Py (0), PCB->Grid);
-      y1 = GRIDFIT_Y (Py (view_height), PCB->Grid);
+      y2 = GridFit (Py (0), PCB->Grid, PCB->GridOffsetY);
+      y1 = GridFit (Py (view_height), PCB->Grid, PCB->GridOffsetY);
       if (Vy (y2) < 0)
 	y2 -= PCB->Grid;
       if (Vy (y1) >= view_height)
@@ -2271,14 +2272,14 @@ draw_grid ()
     }
   else
     {
-      y1 = GRIDFIT_Y (Py (0), PCB->Grid);
-      y2 = GRIDFIT_Y (Py (view_height), PCB->Grid);
+      y1 = GridFit (Py (0), PCB->Grid, PCB->GridOffsetY);
+      y2 = GridFit (Py (view_height), PCB->Grid, PCB->GridOffsetY);
       if (Vy (y1) < 0)
 	y1 += PCB->Grid;
       if (Vy (y2) >= view_height)
 	y2 -= PCB->Grid;
     }
-  n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1;
+  n = (x2 - x1) / PCB->Grid + 1;
   if (n > npoints)
     {
       npoints = n + 10;
@@ -2611,8 +2612,8 @@ idle_proc (XtPointer dummy)
   }
 
   {
-    static double old_grid = -1;
-    static BDimension old_gx, old_gy, old_mm;
+    static Coord old_grid = -1;
+    static Coord old_gx, old_gy, old_mm;
     XmString ms;
     if (PCB->Grid != old_grid
 	|| PCB->GridOffsetX != old_gx
@@ -2630,9 +2631,9 @@ idle_proc (XtPointer dummy)
 	else
 	  {
 	    if (old_gx || old_gy)
-	      pcb_sprintf (buf, "%m+%$mS @%mS,%mS", UUNIT, (BDimension) old_grid, old_gx, old_gy);
+	      pcb_sprintf (buf, "%m+%$mS @%mS,%mS", UUNIT, old_grid, old_gx, old_gy);
 	    else
-	      pcb_sprintf (buf, "%m+%$mS", UUNIT, (BDimension) old_grid);
+	      pcb_sprintf (buf, "%m+%$mS", UUNIT, old_grid);
 	  }
 	ms = XmStringCreatePCB (buf);
 	n = 0;
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index 4647fea..fe45b32 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -16,6 +16,7 @@
 #include "data.h"
 #include "error.h"
 #include "misc.h"
+#include "pcb-printf.h"
 
 #include "hid.h"
 #include "../hidint.h"
diff --git a/src/main.c b/src/main.c
index 8b51609..2754864 100644
--- a/src/main.c
+++ b/src/main.c
@@ -501,15 +501,15 @@ HID_Attribute main_attribute_list[] = {
   ISET (minDrill, MIL_TO_COORD(15), "min-drill", "DRC minimum drill diameter"),
   ISET (minRing, MIL_TO_COORD(10), "min-ring", "DRC minimum annular ring"),
 
-  RSET (Grid, MIL_TO_COORD(10), "grid", 0),
-  RSET (grid_increment_mm, 0.1, "grid-increment-mm", 0),
-  RSET (grid_increment_mil, 5.0, "grid-increment-mil", 0),
-  RSET (size_increment_mm, 0.2, "size-increment-mm", 0),
-  RSET (size_increment_mil, 10.0, "size-increment-mil", 0),
-  RSET (line_increment_mm, 0.1, "line-increment-mm", 0),
-  RSET (line_increment_mil, 5.0, "line-increment-mil", 0),
-  RSET (clear_increment_mm, 0.05, "clear-increment-mm", 0),
-  RSET (clear_increment_mil, 2.0, "clear-increment-mil", 0),
+  ISET (Grid, MIL_TO_COORD(10), "grid", 0),
+  ISET (grid_increment_mm, MM_TO_COORD (0.1), "grid-increment-mm", 0),
+  ISET (grid_increment_mil, MIL_TO_COORD (5.0), "grid-increment-mil", 0),
+  ISET (size_increment_mm, MM_TO_COORD (0.2), "size-increment-mm", 0),
+  ISET (size_increment_mil, MIL_TO_COORD (10.0), "size-increment-mil", 0),
+  ISET (line_increment_mm, MM_TO_COORD (0.1), "line-increment-mm", 0),
+  ISET (line_increment_mil, MIL_TO_COORD (5.0), "line-increment-mil", 0),
+  ISET (clear_increment_mm, MM_TO_COORD (0.05), "clear-increment-mm", 0),
+  ISET (clear_increment_mil, MIL_TO_COORD (2.0), "clear-increment-mil", 0),
   RSET (IsleArea, MIL_TO_COORD(1400) * MIL_TO_COORD(1400), "minimum polygon area", 0),
 
   ISET (BackupInterval, 60, "backup-interval", 0),
diff --git a/src/misc.c b/src/misc.c
index 0188404..e1dff74 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -766,9 +766,9 @@ GetDataBoundingBox (DataTypePtr Data)
  * centers the displayed PCB around the specified point (X,Y)
  */
 void
-CenterDisplay (LocationType X, LocationType Y)
+CenterDisplay (Coord X, Coord Y)
 {
-  double save_grid = PCB->Grid;
+  Coord save_grid = PCB->Grid;
   PCB->Grid = 1;
   if (MoveCrosshairAbsolute (X, Y))
     notify_crosshair_change (true);
@@ -1794,8 +1794,8 @@ AttachForCopy (LocationType PlaceX, LocationType PlaceY)
                               Crosshair.AttachedObject.Ptr1,
                               Crosshair.AttachedObject.Ptr2,
                               Crosshair.AttachedObject.Ptr3, &mx, &my);
-      mx = GRIDFIT_X (mx, PCB->Grid) - mx;
-      my = GRIDFIT_Y (my, PCB->Grid) - my;
+      mx = GridFit (mx, PCB->Grid, PCB->GridOffsetX) - mx;
+      my = GridFit (my, PCB->Grid, PCB->GridOffsetY) - my;
     }
   Crosshair.AttachedObject.X = PlaceX - mx;
   Crosshair.AttachedObject.Y = PlaceY - my;
diff --git a/src/misc.h b/src/misc.h
index f904e19..2f2ccec 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -59,7 +59,7 @@ bool IsLayerNumEmpty (int);
 bool IsLayerGroupEmpty (int);
 bool IsPasteEmpty (int);
 BoxTypePtr GetDataBoundingBox (DataTypePtr);
-void CenterDisplay (LocationType, LocationType);
+void CenterDisplay (Coord, Coord);
 void SetFontInfo (FontTypePtr);
 int ParseGroupString (char *, LayerGroupTypePtr, int /* LayerN */);
 int ParseRouteString (char *, RouteStyleTypePtr, const char *);
@@ -83,7 +83,6 @@ void SaveStackAndVisibility (void);
 void RestoreStackAndVisibility (void);
 char *GetWorkingDirectory (char *);
 void CreateQuotedString (DynamicStringTypePtr, char *);
-int GetGridFactor (void);
 BoxTypePtr GetArcEnds (ArcTypePtr);
 void ChangeArcAngles (LayerTypePtr, ArcTypePtr, long int, long int);
 char *UniqueElementName (DataTypePtr, char *);
diff --git a/src/set.c b/src/set.c
index c77129e..074a6ac 100644
--- a/src/set.c
+++ b/src/set.c
@@ -69,16 +69,14 @@ static int mode_stack[MAX_MODESTACK_DEPTH];
  * sets cursor grid with respect to grid offset values
  */
 void
-SetGrid (double Grid, bool align)
+SetGrid (Coord Grid, bool align)
 {
   if (Grid >= 1 && Grid <= MAX_GRID)
     {
       if (align)
 	{
-	  PCB->GridOffsetX =
-	    Crosshair.X - (int) (Crosshair.X / Grid) * Grid + 0.5;
-	  PCB->GridOffsetY =
-	    Crosshair.Y - (int) (Crosshair.Y / Grid) * Grid + 0.5;
+	  PCB->GridOffsetX = Crosshair.X % Grid;
+	  PCB->GridOffsetY = Crosshair.Y % Grid;
 	}
       PCB->Grid = Grid;
       if (Settings.DrawGrid)
diff --git a/src/set.h b/src/set.h
index 4985f9d..af6115a 100644
--- a/src/set.h
+++ b/src/set.h
@@ -34,7 +34,7 @@
 #include "global.h"
 
 void SetTextScale (Dimension);
-void SetGrid (double, bool);
+void SetGrid (Coord, bool);
 void SetZoom (float);
 void SetLineSize (BDimension);
 void SetViaSize (BDimension, bool);




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