You can subscribe to this list here.
| 2003 |
Jan
|
Feb
(4) |
Mar
(5) |
Apr
|
May
(5) |
Jun
(30) |
Jul
(2) |
Aug
(18) |
Sep
(14) |
Oct
(7) |
Nov
(21) |
Dec
(44) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(63) |
Feb
(94) |
Mar
(54) |
Apr
(39) |
May
(34) |
Jun
(25) |
Jul
(10) |
Aug
(33) |
Sep
(16) |
Oct
(62) |
Nov
(12) |
Dec
(2) |
| 2005 |
Jan
(71) |
Feb
(8) |
Mar
(50) |
Apr
|
May
(2) |
Jun
(12) |
Jul
(19) |
Aug
(8) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(8) |
| 2006 |
Jan
(10) |
Feb
(1) |
Mar
(301) |
Apr
(232) |
May
(26) |
Jun
(20) |
Jul
(26) |
Aug
(79) |
Sep
(92) |
Oct
(174) |
Nov
(17) |
Dec
(93) |
| 2007 |
Jan
(27) |
Feb
(179) |
Mar
(37) |
Apr
(81) |
May
(20) |
Jun
(5) |
Jul
|
Aug
(40) |
Sep
(68) |
Oct
(8) |
Nov
(47) |
Dec
(34) |
| 2008 |
Jan
(154) |
Feb
(15) |
Mar
(5) |
Apr
(21) |
May
(4) |
Jun
(1) |
Jul
(4) |
Aug
(6) |
Sep
(8) |
Oct
(9) |
Nov
(35) |
Dec
(50) |
| 2009 |
Jan
(8) |
Feb
(10) |
Mar
(6) |
Apr
(9) |
May
(7) |
Jun
(40) |
Jul
(7) |
Aug
(5) |
Sep
(2) |
Oct
(16) |
Nov
(42) |
Dec
(5) |
| 2010 |
Jan
(3) |
Feb
(15) |
Mar
(32) |
Apr
(18) |
May
(6) |
Jun
(9) |
Jul
|
Aug
(11) |
Sep
(16) |
Oct
|
Nov
(4) |
Dec
(35) |
| 2011 |
Jan
(24) |
Feb
(6) |
Mar
(27) |
Apr
(119) |
May
(72) |
Jun
(20) |
Jul
(31) |
Aug
(88) |
Sep
(86) |
Oct
(14) |
Nov
(11) |
Dec
(30) |
| 2012 |
Jan
(4) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <gi...@gp...> - 2011-05-13 00:22:15
|
The branch, master has been updated
via e2a5c0ee399d55799cce9ea62b1adc9494bb505f (commit)
via 72cdf2ecef3361a00fbd0ee3e540f7383e62272c (commit)
from ae08cfc9d2877a8697dbbf316434a6bd2ddfc640 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/Makefile.am | 4 ++--
src/hid/common/hidinit.c | 13 -------------
2 files changed, 2 insertions(+), 15 deletions(-)
=================
Commit Messages
=================
commit e2a5c0ee399d55799cce9ea62b1adc9494bb505f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/common: Remove unused function hid_register_gui()
GUIs are registered with the same API as exporter HIDs.
:100644 100644 554e592... 4233b4c... M src/hid/common/hidinit.c
commit 72cdf2ecef3361a00fbd0ee3e540f7383e62272c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
src/Makefile.am: Use AM_CFLAGS instead of overriding CFLAGS directly
:100644 100644 8129207... 0de23aa... M src/Makefile.am
=========
Changes
=========
commit e2a5c0ee399d55799cce9ea62b1adc9494bb505f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/common: Remove unused function hid_register_gui()
GUIs are registered with the same API as exporter HIDs.
diff --git a/src/hid/common/hidinit.c b/src/hid/common/hidinit.c
index 554e592..4233b4c 100644
--- a/src/hid/common/hidinit.c
+++ b/src/hid/common/hidinit.c
@@ -176,19 +176,6 @@ hid_register_hid (HID * hid)
hid_list[hid_num_hids] = 0;
}
-static void (*gui_start) (int *, char ***) = 0;
-static HID *default_gui = 0;
-
-void
-hid_register_gui (HID * Pgui, void (*func) (int *, char ***))
-{
- if (gui_start)
- return;
-
- default_gui = Pgui;
- gui_start = func;
-}
-
HID *
hid_find_gui ()
commit 72cdf2ecef3361a00fbd0ee3e540f7383e62272c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
src/Makefile.am: Use AM_CFLAGS instead of overriding CFLAGS directly
diff --git a/src/Makefile.am b/src/Makefile.am
index 8129207..0de23aa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,7 +5,7 @@
SUBDIRS= icons
CC = @CC_OR_CXX@
-CFLAGS = @CC_OR_CXX_FLAGS@
+AM_CFLAGS = @CC_OR_CXX_FLAGS@
pcbtreedir= @PCBTREEDIR@
pcblibdir= @PCBLIBDIR@
@@ -28,7 +28,7 @@ bin_PROGRAMS= pcb
if DEBUG_BUILD
# don't disable assert()
else
-AM_CFLAGS = -DNDEBUG
+AM_CFLAGS += -DNDEBUG
endif
PCB_SRCS = \
|
|
From: <gi...@gp...> - 2011-05-12 23:44:54
|
The branch, master has been updated
via ae08cfc9d2877a8697dbbf316434a6bd2ddfc640 (commit)
from 75a822c666ac903dacaa40fc09f6b3b3b7cd2812 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-main.c | 1 +
src/hid/lesstif/main.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
=================
Commit Messages
=================
commit ae08cfc9d2877a8697dbbf316434a6bd2ddfc640
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Apply the default hidnogui HID to the GUIs as well.
This saves them having to re-implement NOOP implementations for
functions the "nogui" HID provides a non "CRASH;" implementation
for.
:100644 100644 ea0a0dd... 091f472... M src/hid/gtk/gtkhid-main.c
:100644 100644 4f7e12a... c2513bf... M src/hid/lesstif/main.c
=========
Changes
=========
commit ae08cfc9d2877a8697dbbf316434a6bd2ddfc640
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Apply the default hidnogui HID to the GUIs as well.
This saves them having to re-implement NOOP implementations for
functions the "nogui" HID provides a non "CRASH;" implementation
for.
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index ea0a0dd..091f472 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -2330,6 +2330,7 @@ hid_gtk_init ()
ghid_hid.flush_debug_draw = ghid_flush_debug_draw;
ghid_hid.finish_debug_draw = ghid_finish_debug_draw;
+ apply_default_hid (&ghid_hid, 0);
hid_register_hid (&ghid_hid);
#include "gtk_lists.h"
}
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 4f7e12a..c2513bf 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -4065,6 +4065,7 @@ hid_lesstif_init ()
lesstif_hid.flush_debug_draw = lesstif_flush_debug_draw;
lesstif_hid.finish_debug_draw = lesstif_finish_debug_draw;
+ apply_default_hid (&lesstif_hid, 0);
hid_register_hid (&lesstif_hid);
#include "lesstif_lists.h"
}
|
|
From: <gi...@gp...> - 2011-05-12 15:55:45
|
The branch, master has been updated
via 75a822c666ac903dacaa40fc09f6b3b3b7cd2812 (commit)
from cec4f8c85e35ab012673703ce789568711b0e3a4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/batch/batch.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
=================
Commit Messages
=================
commit 75a822c666ac903dacaa40fc09f6b3b3b7cd2812
Author: Ineiev <in...@us...>
Commit: Ineiev <in...@us...>
fix batch gui
:100644 100644 3ccca3a... a51d058... M src/hid/batch/batch.c
=========
Changes
=========
commit 75a822c666ac903dacaa40fc09f6b3b3b7cd2812
Author: Ineiev <in...@us...>
Commit: Ineiev <in...@us...>
fix batch gui
diff --git a/src/hid/batch/batch.c b/src/hid/batch/batch.c
index 3ccca3a..a51d058 100644
--- a/src/hid/batch/batch.c
+++ b/src/hid/batch/batch.c
@@ -87,8 +87,8 @@ info (int argc, char **argv, int x, int y)
printf("Size: %g x %g mils, %g x %g mm\n",
COORD_TO_MIL(PCB->MaxWidth),
COORD_TO_MIL(PCB->MaxHeight),
- PCB->MaxWidth * COOR_TO_MM,
- PCB->MaxHeight * COOR_TO_MM);
+ COORD_TO_MM (PCB->MaxWidth),
+ COORD_TO_MM (PCB->MaxHeight));
cg = GetLayerGroupNumberByNumber (component_silk_layer);
sg = GetLayerGroupNumberByNumber (solder_silk_layer);
for (i=0; i<MAX_LAYER; i++)
|
|
From: <gi...@gp...> - 2011-05-10 13:30:42
|
The branch, master has been updated
discards aa357bf1ad609487f42db9c54b320087837898dc (commit)
via cec4f8c85e35ab012673703ce789568711b0e3a4 (commit)
from aa357bf1ad609487f42db9c54b320087837898dc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/search.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
=================
Commit Messages
=================
commit cec4f8c85e35ab012673703ce789568711b0e3a4
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
search.c: Don't allow selecting pads or pins of locked elements
The locked flag test was mistakenly being applied ot the
pad or pin its-self, not the parent element.
:100644 100644 3fafcd4... 30fe883... M src/search.c
=========
Changes
=========
commit cec4f8c85e35ab012673703ce789568711b0e3a4
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
search.c: Don't allow selecting pads or pins of locked elements
The locked flag test was mistakenly being applied ot the
pad or pin its-self, not the parent element.
diff --git a/src/search.c b/src/search.c
index 3fafcd4..30fe883 100644
--- a/src/search.c
+++ b/src/search.c
@@ -114,13 +114,14 @@ pinorvia_callback (const BoxType * box, void *cl)
{
struct ans_info *i = (struct ans_info *) cl;
PinTypePtr pin = (PinTypePtr) box;
+ AnyObjectType *ptr1 = pin->Element ? pin->Element : pin;
- if (TEST_FLAG (i->locked, pin))
+ if (TEST_FLAG (i->locked, ptr1))
return 0;
if (!IsPointOnPin (PosX, PosY, SearchRadius, pin))
return 0;
- *i->ptr1 = pin->Element ? pin->Element : pin;
+ *i->ptr1 = ptr1;
*i->ptr2 = *i->ptr3 = pin;
longjmp (i->env, 1);
return 1; /* never reached */
@@ -181,15 +182,16 @@ pad_callback (const BoxType * b, void *cl)
{
PadTypePtr pad = (PadTypePtr) b;
struct ans_info *i = (struct ans_info *) cl;
+ AnyObjectType *ptr1 = pad->Element;
- if (TEST_FLAG (i->locked, pad))
+ if (TEST_FLAG (i->locked, ptr1))
return 0;
if (FRONT (pad) || i->BackToo)
{
if (IsPointInPad (PosX, PosY, SearchRadius, pad))
{
- *i->ptr1 = pad->Element;
+ *i->ptr1 = ptr1;
*i->ptr2 = *i->ptr3 = pad;
longjmp (i->env, 1);
}
|
|
From: <gi...@gp...> - 2011-05-10 12:45:45
|
The branch, master has been updated
via aa357bf1ad609487f42db9c54b320087837898dc (commit)
from 53bd26d2735fd8e0a443bc724e2e4f7bfaca85cc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/search.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
=================
Commit Messages
=================
commit aa357bf1ad609487f42db9c54b320087837898dc
Author: Peter Clifton (none) <peterc@paramita-desktop-2>
Commit: Peter Clifton <peterc@paramita-desktop-2.(none)>
From 224cea120af8989e553944cd5a81b0034d1ec50c Mon Sep 17 00:00:00 2001
Subject: [PATCH] search.c: Don't allow selecting pads or pins of locked elements
The locked flag test was mistakenly being applied ot the
pad or pin its-self, not the parent element.
:100644 100644 3fafcd4... ff86bc7... M src/search.c
=========
Changes
=========
commit aa357bf1ad609487f42db9c54b320087837898dc
Author: Peter Clifton (none) <peterc@paramita-desktop-2>
Commit: Peter Clifton <peterc@paramita-desktop-2.(none)>
From 224cea120af8989e553944cd5a81b0034d1ec50c Mon Sep 17 00:00:00 2001
Subject: [PATCH] search.c: Don't allow selecting pads or pins of locked elements
The locked flag test was mistakenly being applied ot the
pad or pin its-self, not the parent element.
diff --git a/src/search.c b/src/search.c
index 3fafcd4..ff86bc7 100644
--- a/src/search.c
+++ b/src/search.c
@@ -115,7 +115,7 @@ pinorvia_callback (const BoxType * box, void *cl)
struct ans_info *i = (struct ans_info *) cl;
PinTypePtr pin = (PinTypePtr) box;
- if (TEST_FLAG (i->locked, pin))
+ if (TEST_FLAG (i->locked, *(AnyObjectType **)i->ptr1))
return 0;
if (!IsPointOnPin (PosX, PosY, SearchRadius, pin))
@@ -182,7 +182,7 @@ pad_callback (const BoxType * b, void *cl)
PadTypePtr pad = (PadTypePtr) b;
struct ans_info *i = (struct ans_info *) cl;
- if (TEST_FLAG (i->locked, pad))
+ if (TEST_FLAG (i->locked, *(AnyObjectType **)i->ptr1))
return 0;
if (FRONT (pad) || i->BackToo)
|
|
From: <gi...@gp...> - 2011-05-09 06:38:06
|
The branch, master has been updated
via 53bd26d2735fd8e0a443bc724e2e4f7bfaca85cc (commit)
from b0177cbf7a124f5bf537dfaebc7a78c9aa01bf28 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-gl.c | 65 +++++++++++++++++++++++++++++------------------
1 files changed, 40 insertions(+), 25 deletions(-)
=================
Commit Messages
=================
commit 53bd26d2735fd8e0a443bc724e2e4f7bfaca85cc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Split out sub-compositing setup into a separate function.
:100644 100644 3c12833... 8af8a03... M src/hid/gtk/gtkhid-gl.c
=========
Changes
=========
commit 53bd26d2735fd8e0a443bc724e2e4f7bfaca85cc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Split out sub-compositing setup into a separate function.
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 3c12833..8af8a03 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -60,12 +60,47 @@ typedef struct hid_gc_struct
}
hid_gc_struct;
+static void
+start_subcomposite (void)
+{
+ render_priv *priv = gport->render_priv;
+ int stencil_bit;
+
+ /* Flush out any existing geoemtry to be rendered */
+ hidgl_flush_triangles (&buffer);
+
+ glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+
+ stencil_bit = hidgl_assign_clear_stencil_bit(); /* Get a new (clean) bitplane to stencil with */
+ glStencilMask (stencil_bit); /* Only write to our subcompositing stencil bitplane */
+ glStencilFunc (GL_GREATER, stencil_bit, stencil_bit); /* Pass stencil test if our assigned bit is clear */
+
+ priv->subcomposite_stencil_bit = stencil_bit;
+}
+
+static void
+end_subcomposite (void)
+{
+ render_priv *priv = gport->render_priv;
+
+ /* Flush out any existing geoemtry to be rendered */
+ hidgl_flush_triangles (&buffer);
+
+ hidgl_return_stencil_bit (priv->subcomposite_stencil_bit); /* Relinquish any bitplane we previously used */
+
+ glStencilMask (0);
+ glStencilFunc (GL_ALWAYS, 0, 0); /* Always pass stencil test */
+ glDisable (GL_STENCIL_TEST); /* Disable Stencil test */
+
+ priv->subcomposite_stencil_bit = 0;
+}
+
int
ghid_set_layer (const char *name, int group, int empty)
{
render_priv *priv = gport->render_priv;
- int stencil_bit;
int idx = group;
if (idx >= 0 && idx < max_group)
{
@@ -78,19 +113,10 @@ ghid_set_layer (const char *name, int group, int empty)
break;
}
idx = PCB->LayerGroups.Entries[group][idx];
- }
-
- /* Flush out any existing geoemtry to be rendered */
- hidgl_flush_triangles (&buffer);
+ }
- glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
- glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
-
- hidgl_return_stencil_bit (priv->subcomposite_stencil_bit); /* Relinquish any bitplane we previously used */
- stencil_bit = hidgl_assign_clear_stencil_bit(); /* Get a new (clean) bitplane to stencil with */
- glStencilFunc (GL_GREATER, stencil_bit, stencil_bit); /* Pass stencil test if our assigned bit is clear */
- glStencilMask (stencil_bit); /* Only write to our subcompositing stencil bitplane */
- priv->subcomposite_stencil_bit = stencil_bit;
+ end_subcomposite ();
+ start_subcomposite ();
if (idx >= 0 && idx < max_copper_layer + 2)
{
@@ -129,18 +155,7 @@ ghid_set_layer (const char *name, int group, int empty)
static void
ghid_end_layer (void)
{
- render_priv *priv = gport->render_priv;
-
- /* Flush out any existing geoemtry to be rendered */
- hidgl_flush_triangles (&buffer);
-
- /* Relinquish any bitplane we previously used */
- hidgl_return_stencil_bit (priv->subcomposite_stencil_bit);
- priv->subcomposite_stencil_bit = 0;
-
- /* Always pass stencil test */
- glStencilMask (0);
- glStencilFunc (GL_ALWAYS, 0, 0);
+ end_subcomposite ();
}
void
|
|
From: <gi...@gp...> - 2011-05-08 21:16:13
|
The branch, master has been updated
via b0177cbf7a124f5bf537dfaebc7a78c9aa01bf28 (commit)
from 600676f9b5a293724c5499e9e276e8678a438bd6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-gl.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
=================
Commit Messages
=================
commit b0177cbf7a124f5bf537dfaebc7a78c9aa01bf28
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Make the silk layer translucent
:100644 100644 a7278df... 3c12833... M src/hid/gtk/gtkhid-gl.c
=========
Changes
=========
commit b0177cbf7a124f5bf537dfaebc7a78c9aa01bf28
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Make the silk layer translucent
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index a7278df..3c12833 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -108,7 +108,7 @@ ghid_set_layer (const char *name, int group, int empty)
return TEST_FLAG (SHOWMASKFLAG, PCB);
return 0;
case SL_SILK:
- priv->trans_lines = false;
+ priv->trans_lines = true;
if (SL_MYSIDE (idx))
return PCB->ElementOn;
return 0;
|
|
From: <gi...@gp...> - 2011-05-08 21:15:49
|
The branch, master has been updated
via 600676f9b5a293724c5499e9e276e8678a438bd6 (commit)
from 81c9e2b71b621cebc070624e84397eef4af1598f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-gl.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
=================
Commit Messages
=================
commit 600676f9b5a293724c5499e9e276e8678a438bd6
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Sub-composite objects on each layer using the stencil buffer
This avoids the highlight where translucent objects on a given layer
are drawn over each other. It enables us to have a translucent silk
screen layer and still be able to read the text.
:100644 100644 910fd2d... a7278df... M src/hid/gtk/gtkhid-gl.c
=========
Changes
=========
commit 600676f9b5a293724c5499e9e276e8678a438bd6
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
GTK/GL: Sub-composite objects on each layer using the stencil buffer
This avoids the highlight where translucent objects on a given layer
are drawn over each other. It enables us to have a translucent silk
screen layer and still be able to read the text.
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 910fd2d..a7278df 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -44,6 +44,7 @@ typedef struct render_priv {
GdkGLConfig *glconfig;
bool trans_lines;
bool in_context;
+ int subcomposite_stencil_bit;
} render_priv;
@@ -64,6 +65,7 @@ int
ghid_set_layer (const char *name, int group, int empty)
{
render_priv *priv = gport->render_priv;
+ int stencil_bit;
int idx = group;
if (idx >= 0 && idx < max_group)
{
@@ -78,6 +80,18 @@ ghid_set_layer (const char *name, int group, int empty)
idx = PCB->LayerGroups.Entries[group][idx];
}
+ /* Flush out any existing geoemtry to be rendered */
+ hidgl_flush_triangles (&buffer);
+
+ glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+
+ hidgl_return_stencil_bit (priv->subcomposite_stencil_bit); /* Relinquish any bitplane we previously used */
+ stencil_bit = hidgl_assign_clear_stencil_bit(); /* Get a new (clean) bitplane to stencil with */
+ glStencilFunc (GL_GREATER, stencil_bit, stencil_bit); /* Pass stencil test if our assigned bit is clear */
+ glStencilMask (stencil_bit); /* Only write to our subcompositing stencil bitplane */
+ priv->subcomposite_stencil_bit = stencil_bit;
+
if (idx >= 0 && idx < max_copper_layer + 2)
{
priv->trans_lines = true;
@@ -112,6 +126,23 @@ ghid_set_layer (const char *name, int group, int empty)
return 0;
}
+static void
+ghid_end_layer (void)
+{
+ render_priv *priv = gport->render_priv;
+
+ /* Flush out any existing geoemtry to be rendered */
+ hidgl_flush_triangles (&buffer);
+
+ /* Relinquish any bitplane we previously used */
+ hidgl_return_stencil_bit (priv->subcomposite_stencil_bit);
+ priv->subcomposite_stencil_bit = 0;
+
+ /* Always pass stencil test */
+ glStencilMask (0);
+ glStencilFunc (GL_ALWAYS, 0, 0);
+}
+
void
ghid_destroy_gc (hidGC gc)
{
@@ -751,6 +782,9 @@ ghid_init_renderer (int *argc, char ***argv, GHidPort *port)
printf ("Could not setup GL-context!\n");
return; /* Should we abort? */
}
+
+ /* Setup HID function pointers specific to the GL renderer*/
+ ghid_hid.end_layer = ghid_end_layer;
}
void
@@ -1169,6 +1203,9 @@ ghid_request_debug_draw (void)
hidgl_init_triangle_array (&buffer);
ghid_invalidate_current_gc ();
+ /* Setup stenciling */
+ glDisable (GL_STENCIL_TEST);
+
glPushMatrix ();
glScalef ((ghid_flip_x ? -1. : 1.) / port->zoom,
(ghid_flip_y ? -1. : 1.) / port->zoom,
|
|
From: <gi...@gp...> - 2011-05-08 20:56:07
|
The branch, master has been updated
via 81c9e2b71b621cebc070624e84397eef4af1598f (commit)
from 0b59748da88acdd0463c4d29fbc1bba744854e0e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/draw.c | 70 ++++++++++++++++++++++++++++++++++++---------
src/hid.h | 3 ++
src/hid/common/hidnogui.c | 7 ++++
3 files changed, 66 insertions(+), 14 deletions(-)
=================
Commit Messages
=================
commit 81c9e2b71b621cebc070624e84397eef4af1598f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Add end_layer() function to HID API to mark the end of a layer's drawing
This is going to be useful for the GTK/GL renderer to manage sub-
compositing translucent objects within each layer.
:100644 100644 e1ae2dc... 6c3d709... M src/draw.c
:100644 100644 3919db0... eeb09ab... M src/hid.h
:100644 100644 5289c71... 08061fe... M src/hid/common/hidnogui.c
=========
Changes
=========
commit 81c9e2b71b621cebc070624e84397eef4af1598f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Add end_layer() function to HID API to mark the end of a layer's drawing
This is going to be useful for the GTK/GL renderer to manage sub-
compositing translucent objects within each layer.
diff --git a/src/draw.c b/src/draw.c
index e1ae2dc..6c3d709 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -693,6 +693,7 @@ DrawEverything (BoxTypePtr drawn_area)
DrawLayer (&(PCB->Data->Layer[max_copper_layer + side]), drawn_area);
}
r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side);
+ gui->end_layer ();
}
/* draw all layers in layerstack order */
@@ -701,8 +702,11 @@ DrawEverything (BoxTypePtr drawn_area)
int group = drawn_groups[i];
if (gui->set_layer (0, group, 0))
- if (DrawLayerGroup (group, drawn_area) && !gui->gui)
- DrawPPV (group, drawn_area);
+ {
+ if (DrawLayerGroup (group, drawn_area) && !gui->gui)
+ DrawPPV (group, drawn_area);
+ gui->end_layer ();
+ }
}
if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui)
@@ -716,24 +720,42 @@ DrawEverything (BoxTypePtr drawn_area)
CountHoles (&plated, &unplated, drawn_area);
if (plated && gui->set_layer ("plated-drill", SL (PDRILL, 0), 0))
- DrawHoles (true, false, drawn_area);
+ {
+ DrawHoles (true, false, drawn_area);
+ gui->end_layer ();
+ }
if (unplated && gui->set_layer ("unplated-drill", SL (PDRILL, 0), 0))
- DrawHoles (false, true, drawn_area);
+ {
+ DrawHoles (false, true, drawn_area);
+ gui->end_layer ();
+ }
}
/* Draw the solder mask if turned on */
if (gui->set_layer ("componentmask", SL (MASK, TOP), 0))
- DrawMask (COMPONENT_LAYER, drawn_area);
+ {
+ DrawMask (COMPONENT_LAYER, drawn_area);
+ gui->end_layer ();
+ }
if (gui->set_layer ("soldermask", SL (MASK, BOTTOM), 0))
- DrawMask (SOLDER_LAYER, drawn_area);
+ {
+ DrawMask (SOLDER_LAYER, drawn_area);
+ gui->end_layer ();
+ }
if (gui->set_layer ("topsilk", SL (SILK, TOP), 0))
- DrawSilk (COMPONENT_LAYER, drawn_area);
+ {
+ DrawSilk (COMPONENT_LAYER, drawn_area);
+ gui->end_layer ();
+ }
if (gui->set_layer ("bottomsilk", SL (SILK, BOTTOM), 0))
- DrawSilk (SOLDER_LAYER, drawn_area);
+ {
+ DrawSilk (SOLDER_LAYER, drawn_area);
+ gui->end_layer ();
+ }
if (gui->gui)
{
@@ -743,27 +765,47 @@ DrawEverything (BoxTypePtr drawn_area)
NULL);
/* Draw rat lines on top */
if (gui->set_layer ("rats", SL (RATS, 0), 0))
- DrawRats(drawn_area);
+ {
+ DrawRats(drawn_area);
+ gui->end_layer ();
+ }
}
paste_empty = IsPasteEmpty (COMPONENT_LAYER);
if (gui->set_layer ("toppaste", SL (PASTE, TOP), paste_empty))
- DrawPaste (COMPONENT_LAYER, drawn_area);
+ {
+ DrawPaste (COMPONENT_LAYER, drawn_area);
+ gui->end_layer ();
+ }
paste_empty = IsPasteEmpty (SOLDER_LAYER);
if (gui->set_layer ("bottompaste", SL (PASTE, BOTTOM), paste_empty))
- DrawPaste (SOLDER_LAYER, drawn_area);
+ {
+ DrawPaste (SOLDER_LAYER, drawn_area);
+ gui->end_layer ();
+ }
doing_assy = true;
+
if (gui->set_layer ("topassembly", SL (ASSY, TOP), 0))
- PrintAssembly (COMPONENT_LAYER, drawn_area);
+ {
+ PrintAssembly (COMPONENT_LAYER, drawn_area);
+ gui->end_layer ();
+ }
if (gui->set_layer ("bottomassembly", SL (ASSY, BOTTOM), 0))
- PrintAssembly (SOLDER_LAYER, drawn_area);
+ {
+ PrintAssembly (SOLDER_LAYER, drawn_area);
+ gui->end_layer ();
+ }
+
doing_assy = false;
if (gui->set_layer ("fab", SL (FAB, 0), 0))
- PrintFab (Output.fgGC);
+ {
+ PrintFab (Output.fgGC);
+ gui->end_layer ();
+ }
}
static void
diff --git a/src/hid.h b/src/hid.h
index 3919db0..eeb09ab 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -311,6 +311,9 @@ typedef enum
layer is empty, if zero it may be non-empty. */
int (*set_layer) (const char *name_, int group_, int _empty);
+ /* Tell the GUI the layer last selected has been finished with */
+ void (*end_layer) (void);
+
/* Drawing Functions. Coordinates and distances are ALWAYS in PCB's
default coordinates (1/100 mil at the time this comment was
written). Angles are always in degrees, with 0 being "right"
diff --git a/src/hid/common/hidnogui.c b/src/hid/common/hidnogui.c
index 5289c71..08061fe 100644
--- a/src/hid/common/hidnogui.c
+++ b/src/hid/common/hidnogui.c
@@ -68,6 +68,11 @@ nogui_set_layer (const char *name, int idx, int empty)
return 0;
}
+static void
+nogui_end_layer (void)
+{
+}
+
static hidGC
nogui_make_gc (void)
{
@@ -456,6 +461,7 @@ HID hid_nogui = {
0 /* nogui_notify_crosshair_change */ ,
0 /* nogui_notify_mark_change */ ,
nogui_set_layer,
+ nogui_end_layer,
nogui_make_gc,
nogui_destroy_gc,
nogui_use_mask,
@@ -521,6 +527,7 @@ apply_default_hid (HID * d, HID * s)
AD (notify_crosshair_change);
AD (notify_mark_change);
AD (set_layer);
+ AD (end_layer);
AD (make_gc);
AD (destroy_gc);
AD (use_mask);
|
|
From: <gi...@gp...> - 2011-05-08 20:55:51
|
The branch, master has been updated
via 0b59748da88acdd0463c4d29fbc1bba744854e0e (commit)
from 2945db9faabb42d229442fe9e48f24607c5adef2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-gl.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
=================
Commit Messages
=================
commit 0b59748da88acdd0463c4d29fbc1bba744854e0e
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Enable transparent lines in GL renderer
:100644 100644 e7614db... 910fd2d... M src/hid/gtk/gtkhid-gl.c
=========
Changes
=========
commit 0b59748da88acdd0463c4d29fbc1bba744854e0e
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Enable transparent lines in GL renderer
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index e7614db..910fd2d 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -80,7 +80,7 @@ ghid_set_layer (const char *name, int group, int empty)
if (idx >= 0 && idx < max_copper_layer + 2)
{
- priv->trans_lines = false;
+ priv->trans_lines = true;
return PCB->Data->Layer[idx].On;
}
if (idx < 0)
|
|
From: <gi...@gp...> - 2011-05-08 18:04:59
|
The branch, master has been updated
via 2945db9faabb42d229442fe9e48f24607c5adef2 (commit)
from 0686163ed9fff234e5b817baa398f2f2bcbda949 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/common/hidgl.c | 132 ++++++++++++++++++++++++++++++++++++++++++----
src/hid/common/hidgl.h | 5 ++
src/hid/gtk/gtkhid-gl.c | 50 ++++++++++++-----
3 files changed, 160 insertions(+), 27 deletions(-)
=================
Commit Messages
=================
commit 2945db9faabb42d229442fe9e48f24607c5adef2
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Manage stencil bitplanes so we don't have to clear them every time.
Clearing the stencil buffer is a slow operation (especially on cards
limited by fill rate (cough.. Intel.. cough), so the more clears we
can avoid, the better.
:100644 100644 453c7f9... fb6b118... M src/hid/common/hidgl.c
:100644 100644 d2ab3c4... 37d35b9... M src/hid/common/hidgl.h
:100644 100644 d9ee158... e7614db... M src/hid/gtk/gtkhid-gl.c
=========
Changes
=========
commit 2945db9faabb42d229442fe9e48f24607c5adef2
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Manage stencil bitplanes so we don't have to clear them every time.
Clearing the stencil buffer is a slow operation (especially on cards
limited by fill rate (cough.. Intel.. cough), so the more clears we
can avoid, the better.
diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
index 453c7f9..fb6b118 100644
--- a/src/hid/common/hidgl.c
+++ b/src/hid/common/hidgl.c
@@ -590,6 +590,9 @@ do_hole (const BoxType *b, void *cl)
return 1;
}
+static GLint stencil_bits;
+static int dirty_bits = 0;
+static int assigned_bits = 0;
/* FIXME: JUST DRAWS THE FIRST PIECE.. TODO: SUPPORT FOR FULLPOLY POLYGONS */
void
@@ -598,6 +601,7 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
int vertex_count = 0;
PLINE *contour;
struct do_hole_info info;
+ int stencil_bit;
global_scale = scale;
@@ -607,6 +611,13 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
return;
}
+ stencil_bit = hidgl_assign_clear_stencil_bit ();
+ if (!stencil_bit)
+ {
+ printf ("hidgl_fill_pcb_polygon: No free stencil bits, aborting polygon\n");
+ return;
+ }
+
/* Flush out any existing geoemtry to be rendered */
hidgl_flush_triangles (&buffer);
@@ -623,29 +634,41 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
gluTessCallback(info.tobj, GLU_TESS_COMBINE, myCombine);
gluTessCallback(info.tobj, GLU_TESS_ERROR, myError);
- glClearStencil (0);
- glClear (GL_STENCIL_BUFFER_BIT);
- glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
+ glPushAttrib (GL_STENCIL_BUFFER_BIT); /* Save the write mask etc.. for final restore */
glEnable (GL_STENCIL_TEST);
+ glPushAttrib (GL_STENCIL_BUFFER_BIT | /* Resave the stencil write-mask etc.., and */
+ GL_COLOR_BUFFER_BIT); /* the colour buffer write mask etc.. for part way restore */
+ glStencilMask (stencil_bit); /* Only write to our stencil bit */
+ glStencilFunc (GL_ALWAYS, stencil_bit, stencil_bit); /* Always pass stencil test, ref value is our bit */
+ glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
+
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value */
- /* Drawing operations set the stencil buffer to '1' */
- glStencilFunc (GL_ALWAYS, 1, 1); /* Test always passes, value written 1 */
- glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+ /* Drawing operations now set our reference bit in the stencil buffer */
r_search (poly->Clipped->contour_tree, clip_box, NULL, do_hole, &info);
hidgl_flush_triangles (&buffer);
- /* Drawing operations as masked to areas where the stencil buffer is '1' */
- glColorMask (1, 1, 1, 1); /* Enable drawing of r, g, b & a */
- glStencilFunc (GL_EQUAL, 0, 1); /* Draw only where stencil buffer is 0 */
- glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); /* Stencil buffer read only */
+ glPopAttrib (); /* Restore the colour and stencil buffer write-mask etc.. */
+
+ glStencilOp (GL_KEEP, GL_KEEP, GL_INVERT); /* This allows us to toggle the bit on any subcompositing bitplane */
+ /* If the stencil test has passed, we know that bit is 0, so we're */
+ /* effectively just setting it to 1. */
+
+ glStencilFunc (GL_GEQUAL, 0, assigned_bits); /* Pass stencil test if all assigned bits clear, */
+ /* reference is all assigned bits so we set */
+ /* any bits permitted by the stencil writemask */
+
+ /* Drawing operations as masked to areas where the stencil buffer is '0' */
/* Draw the polygon outer */
tesselate_contour (info.tobj, poly->Clipped->contours, info.vertices);
hidgl_flush_triangles (&buffer);
- glClear (GL_STENCIL_BUFFER_BIT);
- glDisable (GL_STENCIL_TEST); /* Disable Stencil test */
+ /* Unassign our stencil buffer bit */
+ hidgl_return_stencil_bit (stencil_bit);
+
+ glPopAttrib (); /* Restore the stencil buffer write-mask etc.. */
gluDeleteTess (info.tobj);
myFreeCombined ();
@@ -659,3 +682,88 @@ hidgl_fill_rect (int x1, int y1, int x2, int y2)
hidgl_add_triangle (&buffer, x1, y1, x1, y2, x2, y2);
hidgl_add_triangle (&buffer, x2, y1, x2, y2, x1, y1);
}
+
+void
+hidgl_init (void)
+{
+ glGetIntegerv (GL_STENCIL_BITS, &stencil_bits);
+
+ if (stencil_bits == 0)
+ {
+ printf ("No stencil bits available.\n"
+ "Cannot mask polygon holes or subcomposite layers\n");
+ /* TODO: Flag this to the HID so it can revert to the dicer? */
+ }
+ else if (stencil_bits == 1)
+ {
+ printf ("Only one stencil bitplane avilable\n"
+ "Cannot use stencil buffer to sub-composite layers.\n");
+ /* Do we need to disable that somewhere? */
+ }
+}
+
+int
+hidgl_stencil_bits (void)
+{
+ return stencil_bits;
+}
+
+static void
+hidgl_clean_unassigned_stencil (void)
+{
+ glPushAttrib (GL_STENCIL_BUFFER_BIT);
+ glStencilMask (~assigned_bits);
+ glClearStencil (0);
+ glClear (GL_STENCIL_BUFFER_BIT);
+ glPopAttrib ();
+}
+
+int
+hidgl_assign_clear_stencil_bit (void)
+{
+ int stencil_bitmask = (1 << stencil_bits) - 1;
+ int test;
+ int first_dirty = 0;
+
+ if (assigned_bits == stencil_bitmask)
+ {
+ printf ("No more stencil bits available, total of %i already assigned\n",
+ stencil_bits);
+ return 0;
+ }
+
+ /* Look for a bitplane we don't have to clear */
+ for (test = 1; test & stencil_bitmask; test <<= 1)
+ {
+ if (!(test & dirty_bits))
+ {
+ assigned_bits |= test;
+ dirty_bits |= test;
+ return test;
+ }
+ else if (!first_dirty && !(test & assigned_bits))
+ {
+ first_dirty = test;
+ }
+ }
+
+ /* Didn't find any non dirty planes. Clear those dirty ones which aren't in use */
+ hidgl_clean_unassigned_stencil ();
+ assigned_bits |= first_dirty;
+ dirty_bits = assigned_bits;
+
+ return first_dirty;
+}
+
+void
+hidgl_return_stencil_bit (int bit)
+{
+ assigned_bits &= ~bit;
+}
+
+void
+hidgl_reset_stencil_usage (void)
+{
+ assigned_bits = 0;
+ dirty_bits = 0;
+}
diff --git a/src/hid/common/hidgl.h b/src/hid/common/hidgl.h
index d2ab3c4..37d35b9 100644
--- a/src/hid/common/hidgl.h
+++ b/src/hid/common/hidgl.h
@@ -76,5 +76,10 @@ void hidgl_fill_polygon (int n_coords, int *x, int *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_init (void);
+int hidgl_stencil_bits (void);
+int hidgl_assign_clear_stencil_bit (void);
+void hidgl_return_stencil_bit (int bit);
+void hidgl_reset_stencil_usage (void);
#endif /* __HIDGL_INCLUDED__ */
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index d9ee158..e7614db 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -21,6 +21,7 @@
#include <GL/gl.h>
#include <gtk/gtkgl.h>
#include "hid/common/hidgl.h"
+#include "hid/common/draw_helpers.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
@@ -213,17 +214,12 @@ ghid_draw_bg_image (void)
void
ghid_use_mask (int use_it)
{
- /* NOTE: We are assuming the stencil buffer bit plane is clear at the start
- * of a masked drawing operation.
- *
- * For our current usage we know that it will start clean at the
- * beginning of the frame - and that the mask is only used at most
- * once during rendering (for the solder-mask layer).
- */
+ static int stencil_bit = 0;
if (use_it == cur_mask)
return;
+ /* Flush out any existing geoemtry to be rendered */
hidgl_flush_triangles (&buffer);
switch (use_it)
@@ -234,22 +230,25 @@ ghid_use_mask (int use_it)
case HID_MASK_CLEAR:
/* Write '1' to the stencil buffer where the solder-mask should not be drawn. */
- glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
- glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
- glStencilFunc (GL_ALWAYS, 1, 1); /* Test always passes, value written 1 */
- glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+ glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
+ glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
+ stencil_bit = hidgl_assign_clear_stencil_bit(); /* Get a new (clean) bitplane to stencil with */
+ glStencilFunc (GL_ALWAYS, stencil_bit, stencil_bit); /* Always pass stencil test, write stencil_bit */
+ glStencilMask (stencil_bit); /* Only write to our subcompositing stencil bitplane */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
break;
case HID_MASK_AFTER:
/* Drawing operations as masked to areas where the stencil buffer is '0' */
glColorMask (1, 1, 1, 1); /* Enable drawing of r, g, b & a */
- glStencilFunc (GL_EQUAL, 0, 1); /* Draw only where stencil buffer is 1 */
+ glStencilFunc (GL_GEQUAL, 0, stencil_bit); /* Draw only where our bit of the stencil buffer is clear */
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); /* Stencil buffer read only */
break;
case HID_MASK_OFF:
/* Disable stenciling */
- glDisable (GL_STENCIL_TEST);
+ hidgl_return_stencil_bit (stencil_bit); /* Relinquish any bitplane we previously used */
+ glDisable (GL_STENCIL_TEST); /* Disable Stencil test */
break;
}
cur_mask = use_it;
@@ -819,6 +818,14 @@ ghid_drawing_area_expose_cb (GtkWidget *widget,
ghid_start_drawing (port);
+ hidgl_init ();
+
+ /* If we don't have any stencil bits available,
+ we can't use the hidgl polygon drawing routine */
+ /* TODO: We could use the GLU tessellator though */
+ if (hidgl_stencil_bits() == 0)
+ ghid_hid.fill_pcb_polygon = common_fill_pcb_polygon;
+
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -836,12 +843,20 @@ ghid_drawing_area_expose_cb (GtkWidget *widget,
glLoadIdentity ();
glTranslatef (0.0f, 0.0f, -Z_NEAR);
+ glEnable (GL_STENCIL_TEST);
glClearColor (port->offlimits_color.red / 65535.,
port->offlimits_color.green / 65535.,
port->offlimits_color.blue / 65535.,
1.);
-
+ glStencilMask (~0);
+ glClearStencil (0);
glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ hidgl_reset_stencil_usage ();
+
+ /* Disable the stencil test until we need it - otherwise it gets dirty */
+ glDisable (GL_STENCIL_TEST);
+ glStencilMask (0);
+ glStencilFunc (GL_ALWAYS, 0, 0);
region.X1 = MIN (Px (ev->area.x), Px (ev->area.x + ev->area.width + 1));
region.X2 = MAX (Px (ev->area.x), Px (ev->area.x + ev->area.width + 1));
@@ -977,9 +992,12 @@ ghid_pinout_preview_expose (GtkWidget *widget,
gport->bg_color.green / 65535.,
gport->bg_color.blue / 65535.,
1.);
-
+ glStencilMask (~0);
+ glClearStencil (0);
glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ hidgl_reset_stencil_usage ();
+
/* call the drawing routine */
hidgl_init_triangle_array (&buffer);
ghid_invalidate_current_gc ();
@@ -1086,8 +1104,10 @@ ghid_render_pixmap (int cx, int cy, double zoom, int width, int height, int dept
gport->bg_color.green / 65535.,
gport->bg_color.blue / 65535.,
1.);
+ glStencilMask (~0);
glClearStencil (0);
glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ hidgl_reset_stencil_usage ();
/* call the drawing routine */
hidgl_init_triangle_array (&buffer);
|
|
From: <gi...@gp...> - 2011-05-08 10:50:31
|
The branch, master has been updated
via 0686163ed9fff234e5b817baa398f2f2bcbda949 (commit)
from f8eba07aa7fad02c0462d2f9b46718f6398b800c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/common/hidgl.c | 31 +++++++++++--------------------
1 files changed, 11 insertions(+), 20 deletions(-)
=================
Commit Messages
=================
commit 0686163ed9fff234e5b817baa398f2f2bcbda949
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/common/hidgl.c: Tidy up polygon contour tessleation
Move the gluTessBeginPolygon and gluTessEndPolygon calls inside
tesselate_contour, rather than duplicating it in each caller.
Also, fix up some comments which were out of date or inaccurate.
:100644 100644 64639d5... 453c7f9... M src/hid/common/hidgl.c
=========
Changes
=========
commit 0686163ed9fff234e5b817baa398f2f2bcbda949
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/common/hidgl.c: Tidy up polygon contour tessleation
Move the gluTessBeginPolygon and gluTessEndPolygon calls inside
tesselate_contour, rather than duplicating it in each caller.
Also, fix up some comments which were out of date or inaccurate.
diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
index 64639d5..453c7f9 100644
--- a/src/hid/common/hidgl.c
+++ b/src/hid/common/hidgl.c
@@ -552,28 +552,27 @@ hidgl_fill_polygon (int n_coords, int *x, int *y)
}
void
-tesselate_contour (GLUtesselator *tobj, PLINE *contour, GLdouble *vertices,
- int *i)
+tesselate_contour (GLUtesselator *tobj, PLINE *contour, GLdouble *vertices)
{
VNODE *vn = &contour->head;
- int offset = *i * 3;
+ int offset = 0;
+ gluTessBeginPolygon (tobj, NULL);
gluTessBeginContour (tobj);
do {
vertices [0 + offset] = vn->point[0];
vertices [1 + offset] = vn->point[1];
vertices [2 + offset] = 0.;
gluTessVertex (tobj, &vertices [offset], &vertices [offset]);
- (*i)++;
offset += 3;
} while ((vn = vn->next) != &contour->head);
gluTessEndContour (tobj);
+ gluTessEndPolygon (tobj);
}
struct do_hole_info {
GLUtesselator *tobj;
GLdouble *vertices;
- int *i;
};
static int
@@ -586,21 +585,20 @@ do_hole (const BoxType *b, void *cl)
if (curc->Flags.orient == PLF_DIR) {
return 0;
}
- gluTessBeginPolygon (info->tobj, NULL);
- tesselate_contour (info->tobj, curc, info->vertices, info->i);
- gluTessEndPolygon (info->tobj);
+
+ tesselate_contour (info->tobj, curc, info->vertices);
return 1;
}
+
+/* FIXME: JUST DRAWS THE FIRST PIECE.. TODO: SUPPORT FOR FULLPOLY POLYGONS */
void
hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale)
{
- int i, cc;
int vertex_count = 0;
PLINE *contour;
struct do_hole_info info;
-
global_scale = scale;
if (poly->Clipped == NULL)
@@ -609,19 +607,17 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
return;
}
- /* TODO: Just draw our triangles, no need to flush the buffer */
+ /* Flush out any existing geoemtry to be rendered */
hidgl_flush_triangles (&buffer);
- /* JUST DRAW THE FIRST PIECE */
/* Walk the polygon structure, counting vertices */
/* This gives an upper bound on the amount of storage required */
for (contour = poly->Clipped->contours;
contour != NULL; contour = contour->next)
- vertex_count += contour->Count;
+ vertex_count = MAX (vertex_count, contour->Count);
info.vertices = malloc (sizeof(GLdouble) * vertex_count * 3);
info.tobj = gluNewTess ();
- info.i = &i;
gluTessCallback(info.tobj, GLU_TESS_BEGIN, myBegin);
gluTessCallback(info.tobj, GLU_TESS_VERTEX, myVertex);
gluTessCallback(info.tobj, GLU_TESS_COMBINE, myCombine);
@@ -632,9 +628,6 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
glEnable (GL_STENCIL_TEST);
- i = 0;
- cc = 1;
-
/* Drawing operations set the stencil buffer to '1' */
glStencilFunc (GL_ALWAYS, 1, 1); /* Test always passes, value written 1 */
glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
@@ -648,9 +641,7 @@ hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); /* Stencil buffer read only */
/* Draw the polygon outer */
- gluTessBeginPolygon (info.tobj, NULL);
- tesselate_contour (info.tobj, poly->Clipped->contours, info.vertices, &i);
- gluTessEndPolygon (info.tobj);
+ tesselate_contour (info.tobj, poly->Clipped->contours, info.vertices);
hidgl_flush_triangles (&buffer);
glClear (GL_STENCIL_BUFFER_BIT);
|
|
From: <gi...@gp...> - 2011-05-08 09:29:31
|
The branch, master has been updated
via f8eba07aa7fad02c0462d2f9b46718f6398b800c (commit)
from a86abb93ed0424827123a2f9e348bc36afb35555 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid.h | 4 ----
src/hid/common/draw_helpers.c | 4 ----
src/hid/common/hidnogui.c | 2 +-
src/hid/gerber/gerber.c | 1 -
src/hid/png/png.c | 1 -
5 files changed, 1 insertions(+), 11 deletions(-)
=================
Commit Messages
=================
commit f8eba07aa7fad02c0462d2f9b46718f6398b800c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
HID: Remove "dicer" flag from HID structure.
We don't pay any attention to this flag - always dicing the polygons
in our common_fill_pcb_polygon routine. HIDs which don't want diced
polygons implement their own hook for fill_pcb_polygon.
:100644 100644 9104190... 3919db0... M src/hid.h
:100644 100644 7d529ba... 543b99f... M src/hid/common/draw_helpers.c
:100644 100644 f9d5949... 5289c71... M src/hid/common/hidnogui.c
:100644 100644 b6d7585... 47e6124... M src/hid/gerber/gerber.c
:100644 100644 29ffae3... 9890364... M src/hid/png/png.c
=========
Changes
=========
commit f8eba07aa7fad02c0462d2f9b46718f6398b800c
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
HID: Remove "dicer" flag from HID structure.
We don't pay any attention to this flag - always dicing the polygons
in our common_fill_pcb_polygon routine. HIDs which don't want diced
polygons implement their own hook for fill_pcb_polygon.
diff --git a/src/hid.h b/src/hid.h
index 9104190..3919db0 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -273,10 +273,6 @@ typedef enum
polygons will be drawn twice. */
char poly_after:1;
- /* If set, the redraw code will dice the polygons, so that there
- are no clearances in any polygons. */
- char poly_dicer:1;
-
/* Returns a set of resources describing options the export or print
HID supports. In GUI mode, the print/export dialogs use this to
set up the selectable options. In command line mode, these are
diff --git a/src/hid/common/draw_helpers.c b/src/hid/common/draw_helpers.c
index 7d529ba..543b99f 100644
--- a/src/hid/common/draw_helpers.c
+++ b/src/hid/common/draw_helpers.c
@@ -142,10 +142,6 @@ should_compute_no_holes (PolygonType *poly, const BoxType *clip_box)
void
common_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box)
{
- /* FIXME: We aren't checking the gui's dicer flag..
- we are dicing for every case. Some GUIs
- rely on this, and need their flags fixing. */
-
if (!poly->NoHolesValid)
{
/* If enough of the polygon is on-screen, compute the entire
diff --git a/src/hid/common/hidnogui.c b/src/hid/common/hidnogui.c
index f9d5949..5289c71 100644
--- a/src/hid/common/hidnogui.c
+++ b/src/hid/common/hidnogui.c
@@ -447,7 +447,7 @@ HID hid_nogui = {
sizeof (HID),
"nogui",
"Default GUI when no other GUI is present. Does nothing.",
- 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
nogui_get_export_options,
nogui_do_export,
nogui_parse_arguments,
diff --git a/src/hid/gerber/gerber.c b/src/hid/gerber/gerber.c
index b6d7585..47e6124 100644
--- a/src/hid/gerber/gerber.c
+++ b/src/hid/gerber/gerber.c
@@ -1166,7 +1166,6 @@ hid_gerber_init ()
gerber_hid.name = "gerber";
gerber_hid.description = "RS-274X (Gerber) export.";
gerber_hid.exporter = 1;
- gerber_hid.poly_dicer = 1;
gerber_hid.get_export_options = gerber_get_export_options;
gerber_hid.do_export = gerber_do_export;
diff --git a/src/hid/png/png.c b/src/hid/png/png.c
index 29ffae3..9890364 100644
--- a/src/hid/png/png.c
+++ b/src/hid/png/png.c
@@ -1522,7 +1522,6 @@ hid_png_init ()
png_hid.description = "GIF/JPEG/PNG export.";
png_hid.exporter = 1;
png_hid.poly_before = 1;
- png_hid.poly_dicer = 1;
png_hid.get_export_options = png_get_export_options;
png_hid.do_export = png_do_export;
|
|
From: <gi...@gp...> - 2011-05-07 16:54:46
|
The branch, master has been updated
via a86abb93ed0424827123a2f9e348bc36afb35555 (commit)
from dc72353fcba7bfc5242b6d4ea40da4750d65f679 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/common/hidgl.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
src/hid/common/hidgl.h | 1 +
src/hid/gtk/gtkhid-gdk.c | 7 +++
src/hid/gtk/gtkhid-gl.c | 8 +++
src/hid/gtk/gtkhid-main.c | 1 +
src/hid/gtk/gui.h | 2 +
6 files changed, 132 insertions(+), 0 deletions(-)
=================
Commit Messages
=================
commit a86abb93ed0424827123a2f9e348bc36afb35555
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Add raw polygons support for the GTK+GL HID, bypassing the no-holes dicer
Uses the OpenGL stencil buffer to make drawing polygons with holes faster.
1. Turn Stenciling on, updates to colour buffer off
2. Clear stencil buffer to 0
3. Paint polygon holes, setting those areas of the stencil buffer to 1
4. Switch on stencil test (== 0), turn on updates to colour buffer
5. Paint outer polygon through areas of the stencil buffer still 0
6. Clear stencil buffer, switch off stencilling.
Caveat:
This function might throw up if it is used whilst drawing the mask, since
that uses stenciling as well. We don't use polygons on the mask, so its
not a a problem. (Mask cutouts for octagonal pins do work correctly).
:100644 100644 1745891... 64639d5... M src/hid/common/hidgl.c
:100644 100644 282b144... d2ab3c4... M src/hid/common/hidgl.h
:100644 100644 882af60... 4cb9a02... M src/hid/gtk/gtkhid-gdk.c
:100644 100644 16247a8... d9ee158... M src/hid/gtk/gtkhid-gl.c
:100644 100644 4a231c9... ea0a0dd... M src/hid/gtk/gtkhid-main.c
:100644 100644 31ee636... 00856da... M src/hid/gtk/gui.h
=========
Changes
=========
commit a86abb93ed0424827123a2f9e348bc36afb35555
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Add raw polygons support for the GTK+GL HID, bypassing the no-holes dicer
Uses the OpenGL stencil buffer to make drawing polygons with holes faster.
1. Turn Stenciling on, updates to colour buffer off
2. Clear stencil buffer to 0
3. Paint polygon holes, setting those areas of the stencil buffer to 1
4. Switch on stencil test (== 0), turn on updates to colour buffer
5. Paint outer polygon through areas of the stencil buffer still 0
6. Clear stencil buffer, switch off stencilling.
Caveat:
This function might throw up if it is used whilst drawing the mask, since
that uses stenciling as well. We don't use polygons on the mask, so its
not a a problem. (Mask cutouts for octagonal pins do work correctly).
diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
index 1745891..64639d5 100644
--- a/src/hid/common/hidgl.c
+++ b/src/hid/common/hidgl.c
@@ -53,6 +53,7 @@
#include "hid.h"
#include "hidgl.h"
+#include "rtree.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
@@ -459,6 +460,8 @@ myBegin (GLenum type)
triangle_comp_idx = 0;
}
+static double global_scale;
+
static void
myVertex (GLdouble *vertex_data)
{
@@ -549,6 +552,116 @@ hidgl_fill_polygon (int n_coords, int *x, int *y)
}
void
+tesselate_contour (GLUtesselator *tobj, PLINE *contour, GLdouble *vertices,
+ int *i)
+{
+ VNODE *vn = &contour->head;
+ int offset = *i * 3;
+
+ gluTessBeginContour (tobj);
+ do {
+ vertices [0 + offset] = vn->point[0];
+ vertices [1 + offset] = vn->point[1];
+ vertices [2 + offset] = 0.;
+ gluTessVertex (tobj, &vertices [offset], &vertices [offset]);
+ (*i)++;
+ offset += 3;
+ } while ((vn = vn->next) != &contour->head);
+ gluTessEndContour (tobj);
+}
+
+struct do_hole_info {
+ GLUtesselator *tobj;
+ GLdouble *vertices;
+ int *i;
+};
+
+static int
+do_hole (const BoxType *b, void *cl)
+{
+ struct do_hole_info *info = cl;
+ PLINE *curc = (PLINE *) b;
+
+ /* Ignore the outer contour - we draw it first explicitly*/
+ if (curc->Flags.orient == PLF_DIR) {
+ return 0;
+ }
+ gluTessBeginPolygon (info->tobj, NULL);
+ tesselate_contour (info->tobj, curc, info->vertices, info->i);
+ gluTessEndPolygon (info->tobj);
+ return 1;
+}
+
+void
+hidgl_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale)
+{
+ int i, cc;
+ int vertex_count = 0;
+ PLINE *contour;
+ struct do_hole_info info;
+
+
+ global_scale = scale;
+
+ if (poly->Clipped == NULL)
+ {
+ fprintf (stderr, "hidgl_fill_pcb_polygon: poly->Clipped == NULL\n");
+ return;
+ }
+
+ /* TODO: Just draw our triangles, no need to flush the buffer */
+ hidgl_flush_triangles (&buffer);
+
+ /* JUST DRAW THE FIRST PIECE */
+ /* Walk the polygon structure, counting vertices */
+ /* This gives an upper bound on the amount of storage required */
+ for (contour = poly->Clipped->contours;
+ contour != NULL; contour = contour->next)
+ vertex_count += contour->Count;
+
+ info.vertices = malloc (sizeof(GLdouble) * vertex_count * 3);
+ info.tobj = gluNewTess ();
+ info.i = &i;
+ gluTessCallback(info.tobj, GLU_TESS_BEGIN, myBegin);
+ gluTessCallback(info.tobj, GLU_TESS_VERTEX, myVertex);
+ gluTessCallback(info.tobj, GLU_TESS_COMBINE, myCombine);
+ gluTessCallback(info.tobj, GLU_TESS_ERROR, myError);
+
+ glClearStencil (0);
+ glClear (GL_STENCIL_BUFFER_BIT);
+ glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
+ glEnable (GL_STENCIL_TEST);
+
+ i = 0;
+ cc = 1;
+
+ /* Drawing operations set the stencil buffer to '1' */
+ glStencilFunc (GL_ALWAYS, 1, 1); /* Test always passes, value written 1 */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+
+ r_search (poly->Clipped->contour_tree, clip_box, NULL, do_hole, &info);
+ hidgl_flush_triangles (&buffer);
+
+ /* Drawing operations as masked to areas where the stencil buffer is '1' */
+ glColorMask (1, 1, 1, 1); /* Enable drawing of r, g, b & a */
+ glStencilFunc (GL_EQUAL, 0, 1); /* Draw only where stencil buffer is 0 */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); /* Stencil buffer read only */
+
+ /* Draw the polygon outer */
+ gluTessBeginPolygon (info.tobj, NULL);
+ tesselate_contour (info.tobj, poly->Clipped->contours, info.vertices, &i);
+ gluTessEndPolygon (info.tobj);
+ hidgl_flush_triangles (&buffer);
+
+ glClear (GL_STENCIL_BUFFER_BIT);
+ glDisable (GL_STENCIL_TEST); /* Disable Stencil test */
+
+ gluDeleteTess (info.tobj);
+ myFreeCombined ();
+ free (info.vertices);
+}
+
+void
hidgl_fill_rect (int x1, int y1, int x2, int y2)
{
hidgl_ensure_triangle_space (&buffer, 2);
diff --git a/src/hid/common/hidgl.h b/src/hid/common/hidgl.h
index 282b144..d2ab3c4 100644
--- a/src/hid/common/hidgl.h
+++ b/src/hid/common/hidgl.h
@@ -73,6 +73,7 @@ void hidgl_draw_arc (double width, int vx, int vy, int vrx, int vry, int start_a
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_fill_pcb_polygon (PolygonType *poly, const BoxType *clip_box, double scale);
void hidgl_fill_rect (int x1, int y1, int x2, int y2);
diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index 882af60..4cb9a02 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -10,6 +10,7 @@
#include "clip.h"
#include "../hidint.h"
#include "gui.h"
+#include "hid/common/draw_helpers.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
@@ -654,6 +655,12 @@ ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
}
void
+ghid_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box)
+{
+ common_fill_pcb_polygon (gc, poly, clip_box);
+}
+
+void
ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
{
gint w, h, lw, xx, yy;
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 16247a8..d9ee158 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -519,6 +519,14 @@ ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
}
void
+ghid_fill_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box)
+{
+ USE_GC (gc);
+
+ hidgl_fill_pcb_polygon (poly, clip_box, gport->zoom);
+}
+
+void
ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
{
USE_GC (gc);
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index 4a231c9..ea0a0dd 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -2296,6 +2296,7 @@ hid_gtk_init ()
ghid_hid.draw_rect = ghid_draw_rect;
ghid_hid.fill_circle = ghid_fill_circle;
ghid_hid.fill_polygon = ghid_fill_polygon;
+ ghid_hid.fill_pcb_polygon = ghid_fill_pcb_polygon;
ghid_hid.fill_rect = ghid_fill_rect;
ghid_hid.calibrate = ghid_calibrate;
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 31ee636..00856da 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -485,6 +485,8 @@ void 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);
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_pcb_polygon (hidGC gc, PolygonType *poly,
+ const BoxType *clip_box); /* GL ONLY */
void ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2);
void ghid_invalidate_lr (int left, int right, int top, int bottom);
void ghid_invalidate_all ();
|
|
From: <gi...@gp...> - 2011-05-05 19:52:14
|
The branch, master has been updated
via dc72353fcba7bfc5242b6d4ea40da4750d65f679 (commit)
from d48c1ffe3dd90259ca9dc93b0231f822ff36454f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/lesstif/main.c | 8 --------
1 files changed, 0 insertions(+), 8 deletions(-)
=================
Commit Messages
=================
commit dc72353fcba7bfc5242b6d4ea40da4750d65f679
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
Don't prematurely dismiss the progress dialog.
:100644 100644 dd63f68... 4f7e12a... M src/hid/lesstif/main.c
=========
Changes
=========
commit dc72353fcba7bfc5242b6d4ea40da4750d65f679
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
Don't prematurely dismiss the progress dialog.
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index dd63f68..4f7e12a 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -3958,14 +3958,6 @@ lesstif_progress (int so_far, int total, const char *message)
}
idle_proc (NULL);
- if (progress_cancelled)
- {
- started = 0;
- visible = 0;
- XtUnmanageChild (progress_dialog);
- lesstif_invalidate_all ();
- }
-
/* If rendering takes a while, make sure the core has enough time to
do work. */
gettimeofday (&time, NULL);
|
|
From: <gi...@gp...> - 2011-05-05 05:18:34
|
The branch, master has been updated
via d48c1ffe3dd90259ca9dc93b0231f822ff36454f (commit)
from d9925040eaf2007765ad0e86445b597e31d79885 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/lesstif/main.c | 70 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 55 insertions(+), 15 deletions(-)
=================
Commit Messages
=================
commit d48c1ffe3dd90259ca9dc93b0231f822ff36454f
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
Improve lesstif progress dialog.
Closing the progress dialog cancels the operation.
Add a sliding scale that shows progress.
Make the dialog modal so you can't edit the pcb while autorouting.
Fix event loop to handle all pending events and redraw.
Fix elapsed time logic.
:100644 100644 a4b9975... dd63f68... M src/hid/lesstif/main.c
=========
Changes
=========
commit d48c1ffe3dd90259ca9dc93b0231f822ff36454f
Author: DJ Delorie <dj...@de...>
Commit: DJ Delorie <dj...@de...>
Improve lesstif progress dialog.
Closing the progress dialog cancels the operation.
Add a sliding scale that shows progress.
Make the dialog modal so you can't edit the pcb while autorouting.
Fix event loop to handle all pending events and redraw.
Fix elapsed time logic.
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index a4b9975..dd63f68 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -3851,9 +3851,10 @@ progress_cancel_callback (Widget w, void *v, void *cbs)
static Widget progress_dialog = 0;
static Widget progress_cancel, progress_label;
+static Widget progress_scale;
static void
-lesstif_progress_dialog (int sp_far, int total, const char *msg)
+lesstif_progress_dialog (int so_far, int total, const char *msg)
{
XmString xs;
@@ -3862,11 +3863,14 @@ lesstif_progress_dialog (int sp_far, int total, const char *msg)
if (progress_dialog == 0)
{
+ Atom close_atom;
+
n = 0;
stdarg (XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
stdarg (XmNtitle, "Progress");
+ stdarg (XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);
stdarg (XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
- progress_dialog = XmCreateQuestionDialog (mainwind, "progress", args, n);
+ progress_dialog = XmCreateInformationDialog (mainwind, "progress", args, n);
XtAddCallback (progress_dialog, XmNcancelCallback,
(XtCallbackProc) progress_cancel_callback, NULL);
@@ -3878,9 +3882,28 @@ lesstif_progress_dialog (int sp_far, int total, const char *msg)
stdarg (XmNdefaultPosition, False);
XtSetValues (progress_dialog, args, n);
+
+ n = 0;
+ stdarg(XmNminimum, 0);
+ stdarg(XmNvalue, 0);
+ stdarg(XmNmaximum, total > 0 ? total : 1);
+ stdarg(XmNorientation, XmHORIZONTAL);
+ stdarg(XmNshowArrows, false);
+ progress_scale = XmCreateScrollBar (progress_dialog, "scale", args, n);
+ XtManageChild (progress_scale);
+
+ close_atom = XmInternAtom (display, "WM_DELETE_WINDOW", 0);
+ XmAddWMProtocolCallback (XtParent (progress_dialog), close_atom,
+ (XtCallbackProc) progress_cancel_callback, 0);
}
n = 0;
+ stdarg(XmNvalue, 0);
+ stdarg(XmNsliderSize, (so_far <= total) ? (so_far < 0) ? 0 : so_far : total);
+ stdarg(XmNmaximum, total > 0 ? total : 1);
+ XtSetValues (progress_scale, args, n);
+
+ n = 0;
xs = XmStringCreateLocalized ((char *)msg);
stdarg (XmNmessageString, xs);
XtSetValues (progress_dialog, args, n);
@@ -3888,7 +3911,8 @@ lesstif_progress_dialog (int sp_far, int total, const char *msg)
return;
}
-#define MIN_TIME_SEPARATION (50./1000.) /* 50ms */
+#define MIN_TIME_SEPARATION 0.1 /* seconds */
+
static int
lesstif_progress (int so_far, int total, const char *message)
{
@@ -3896,22 +3920,23 @@ lesstif_progress (int so_far, int total, const char *message)
static bool started = false;
XEvent e;
struct timeval time;
- static struct timeval last_time;
- double time_delta;
+ double time_delta, time_now;
+ static double time_then = 0.0;
int retval = 0;
if (so_far == 0 && total == 0 && message == NULL)
{
XtUnmanageChild (progress_dialog);
visible = false;
+ started = false;
progress_cancelled = false;
return retval;
}
gettimeofday (&time, NULL);
+ time_now = time.tv_sec + time.tv_usec / 1000000.0;
- time_delta = (time.tv_sec - last_time.tv_sec) +
- (double)(time.tv_usec - last_time.tv_usec) / 1000000.;
+ time_delta = time_now - time_then;
if (started && time_delta < MIN_TIME_SEPARATION)
return retval;
@@ -3920,16 +3945,31 @@ lesstif_progress (int so_far, int total, const char *message)
lesstif_progress_dialog (so_far, total, message);
if (!started)
- XtManageChild (progress_dialog);
+ {
+ XtManageChild (progress_dialog);
+ started = true;
+ }
- /* Dispatch one event - ideally we would keep dispatching until we
- * were about to block, but I can't see how to do this with Xt
- */
- XtAppNextEvent (app_context, &e);
- XtDispatchEvent (&e);
+ /* Dispatch pending events */
+ while (XtAppPending (app_context))
+ {
+ XtAppNextEvent (app_context, &e);
+ XtDispatchEvent (&e);
+ }
+ idle_proc (NULL);
- /* Note the time we did this */
- gettimeofday (&last_time, NULL);
+ if (progress_cancelled)
+ {
+ started = 0;
+ visible = 0;
+ XtUnmanageChild (progress_dialog);
+ lesstif_invalidate_all ();
+ }
+
+ /* If rendering takes a while, make sure the core has enough time to
+ do work. */
+ gettimeofday (&time, NULL);
+ time_then = time.tv_sec + time.tv_usec / 1000000.0;
return progress_cancelled;
}
|
|
From: <gi...@gp...> - 2011-05-05 01:53:53
|
The branch, master has been updated
via d9925040eaf2007765ad0e86445b597e31d79885 (commit)
from d368ea48b8c5afee7622a46a6371e5b15d84208a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-main.c | 38 +++++---------------------------------
1 files changed, 5 insertions(+), 33 deletions(-)
=================
Commit Messages
=================
commit d9925040eaf2007765ad0e86445b597e31d79885
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Don't auto-close progress dialog until commanded to
We pass the cancel return value to our caller, but it is up to them
to dismiss the progress dialog.
Utilise the response_id to determine when the dialog has been closed
or cancelled, rather than a separate stop_loop variable (which was a
legacy from the blocking gtk_dialog_run() this code was based upon.
Tidy up due to resulting simplifications.
:100644 100644 963a691... 4a231c9... M src/hid/gtk/gtkhid-main.c
=========
Changes
=========
commit d9925040eaf2007765ad0e86445b597e31d79885
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Don't auto-close progress dialog until commanded to
We pass the cancel return value to our caller, but it is up to them
to dismiss the progress dialog.
Utilise the response_id to determine when the dialog has been closed
or cancelled, rather than a separate stop_loop variable (which was a
legacy from the blocking gtk_dialog_run() this code was based upon.
Tidy up due to resulting simplifications.
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index 963a691..4a231c9 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -747,25 +747,15 @@ struct progress_dialog
gint response_id;
GMainLoop *loop;
gboolean destroyed;
- gboolean stop_loop;
gboolean started;
GTimer *timer;
gulong response_handler;
- gulong unmap_handler;
gulong destroy_handler;
gulong delete_handler;
};
static void
-run_unmap_handler (GtkDialog *dialog, gpointer data)
-{
- struct progress_dialog *pd = data;
-
- pd->stop_loop = TRUE;
-}
-
-static void
run_response_handler (GtkDialog *dialog,
gint response_id,
gpointer data)
@@ -773,7 +763,6 @@ run_response_handler (GtkDialog *dialog,
struct progress_dialog *pd = data;
pd->response_id = response_id;
- pd->stop_loop = TRUE;
}
static gint
@@ -783,7 +772,7 @@ run_delete_handler (GtkDialog *dialog,
{
struct progress_dialog *pd = data;
- pd->stop_loop = TRUE;
+ pd->response_id = GTK_RESPONSE_DELETE_EVENT;
return TRUE; /* Do not destroy */
}
@@ -793,8 +782,6 @@ run_destroy_handler (GtkDialog *dialog, gpointer data)
{
struct progress_dialog *pd = data;
- /* stop_loop will be set by run_unmap_handler */
-
pd->destroyed = TRUE;
}
@@ -847,9 +834,6 @@ make_progress_dialog (void)
pd->response_handler =
g_signal_connect (pd->dialog, "response",
G_CALLBACK (run_response_handler), pd);
- pd->unmap_handler =
- g_signal_connect (pd->dialog, "unmap",
- G_CALLBACK (run_unmap_handler), pd);
pd->delete_handler =
g_signal_connect (pd->dialog, "delete-event",
G_CALLBACK (run_delete_handler), pd);
@@ -872,7 +856,6 @@ destroy_progress_dialog (struct progress_dialog *pd)
if (!pd->destroyed)
{
g_signal_handler_disconnect (pd->dialog, pd->response_handler);
- g_signal_handler_disconnect (pd->dialog, pd->unmap_handler);
g_signal_handler_disconnect (pd->dialog, pd->delete_handler);
g_signal_handler_disconnect (pd->dialog, pd->destroy_handler);
}
@@ -904,20 +887,17 @@ static int
ghid_progress (int so_far, int total, const char *message)
{
static struct progress_dialog *pd = NULL;
- int retval = 0;
/* If we are finished, destroy any dialog */
if (so_far == 0 && total == 0 && message == NULL)
{
destroy_progress_dialog (pd);
pd = NULL;
- return retval;
+ return 0;
}
if (pd == NULL)
- {
- pd = make_progress_dialog ();
- }
+ pd = make_progress_dialog ();
/* We don't want to keep the underlying process too busy whilst we
* process events. If we get called quickly after the last progress
@@ -939,16 +919,8 @@ ghid_progress (int so_far, int total, const char *message)
pd->started = TRUE;
- if (pd->stop_loop)
- {
- retval = (pd->response_id == GTK_RESPONSE_CANCEL ||
- pd->response_id == GTK_RESPONSE_DELETE_EVENT ||
- pd->response_id == GTK_RESPONSE_NONE);
- destroy_progress_dialog (pd);
- pd = NULL;
- }
-
- return retval;
+ return (pd->response_id == GTK_RESPONSE_CANCEL ||
+ pd->response_id == GTK_RESPONSE_DELETE_EVENT) ? 1 : 0;
}
/* ---------------------------------------------------------------------- */
|
|
From: <gi...@gp...> - 2011-05-05 01:19:05
|
The branch, master has been updated
via d368ea48b8c5afee7622a46a6371e5b15d84208a (commit)
from 78fd1e9c758e6df30e7f953fcdd8ac4f39fb864f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/lesstif/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
=================
Commit Messages
=================
commit d368ea48b8c5afee7622a46a6371e5b15d84208a
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/lesstif: Fix testing timeout value in lesstif_progress
This looks like a typo, but was me testing different values of time
interval between processing events.
:100644 100644 f43d7d7... a4b9975... M src/hid/lesstif/main.c
=========
Changes
=========
commit d368ea48b8c5afee7622a46a6371e5b15d84208a
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/lesstif: Fix testing timeout value in lesstif_progress
This looks like a typo, but was me testing different values of time
interval between processing events.
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index f43d7d7..a4b9975 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -3888,7 +3888,7 @@ lesstif_progress_dialog (int sp_far, int total, const char *msg)
return;
}
-#define MIN_TIME_SEPARATION (500./1000.) /* 50ms */
+#define MIN_TIME_SEPARATION (50./1000.) /* 50ms */
static int
lesstif_progress (int so_far, int total, const char *message)
{
|
|
From: <gi...@gp...> - 2011-05-05 01:17:00
|
The branch, master has been updated
via 78fd1e9c758e6df30e7f953fcdd8ac4f39fb864f (commit)
via 944752767041b782599180d132c1aa58251e2dbc (commit)
from 07a98acbf1cb75536e777a9f240d5e338ce22f51 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/autoroute.c | 24 +++++++-----
src/hid/lesstif/main.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 11 deletions(-)
=================
Commit Messages
=================
commit 78fd1e9c758e6df30e7f953fcdd8ac4f39fb864f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/lesstif: Simple progress() implementation to present a cancel button
Does not yet draw an actual progress bar, as I'm not familiar enough
with coding for Lesstif.
:100644 100644 b2c1098... f43d7d7... M src/hid/lesstif/main.c
commit 944752767041b782599180d132c1aa58251e2dbc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
autoroute.c: When live-drawing, only emit one via per location
I'd accidentally put the live-draw via in a place where it would
emit one via for every layer group - causing warnings in PCB's
log about dropped vias.
:100644 100644 8aca7d0... c766c14... M src/autoroute.c
=========
Changes
=========
commit 78fd1e9c758e6df30e7f953fcdd8ac4f39fb864f
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/lesstif: Simple progress() implementation to present a cancel button
Does not yet draw an actual progress bar, as I'm not familiar enough
with coding for Lesstif.
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index b2c1098..f43d7d7 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -3840,10 +3840,98 @@ lesstif_beep (void)
fflush (stdout);
}
+
+static bool progress_cancelled = false;
+
+static void
+progress_cancel_callback (Widget w, void *v, void *cbs)
+{
+ progress_cancelled = true;
+}
+
+static Widget progress_dialog = 0;
+static Widget progress_cancel, progress_label;
+
+static void
+lesstif_progress_dialog (int sp_far, int total, const char *msg)
+{
+ XmString xs;
+
+ if (mainwind == 0)
+ return;
+
+ if (progress_dialog == 0)
+ {
+ n = 0;
+ stdarg (XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
+ stdarg (XmNtitle, "Progress");
+ stdarg (XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
+ progress_dialog = XmCreateQuestionDialog (mainwind, "progress", args, n);
+ XtAddCallback (progress_dialog, XmNcancelCallback,
+ (XtCallbackProc) progress_cancel_callback, NULL);
+
+ progress_cancel = XmMessageBoxGetChild (progress_dialog, XmDIALOG_CANCEL_BUTTON);
+ progress_label = XmMessageBoxGetChild (progress_dialog, XmDIALOG_MESSAGE_LABEL);
+
+ XtUnmanageChild (XmMessageBoxGetChild (progress_dialog, XmDIALOG_OK_BUTTON));
+ XtUnmanageChild (XmMessageBoxGetChild (progress_dialog, XmDIALOG_HELP_BUTTON));
+
+ stdarg (XmNdefaultPosition, False);
+ XtSetValues (progress_dialog, args, n);
+ }
+
+ n = 0;
+ xs = XmStringCreateLocalized ((char *)msg);
+ stdarg (XmNmessageString, xs);
+ XtSetValues (progress_dialog, args, n);
+
+ return;
+}
+
+#define MIN_TIME_SEPARATION (500./1000.) /* 50ms */
static int
lesstif_progress (int so_far, int total, const char *message)
{
- return 0;
+ static bool visible = false;
+ static bool started = false;
+ XEvent e;
+ struct timeval time;
+ static struct timeval last_time;
+ double time_delta;
+ int retval = 0;
+
+ if (so_far == 0 && total == 0 && message == NULL)
+ {
+ XtUnmanageChild (progress_dialog);
+ visible = false;
+ progress_cancelled = false;
+ return retval;
+ }
+
+ gettimeofday (&time, NULL);
+
+ time_delta = (time.tv_sec - last_time.tv_sec) +
+ (double)(time.tv_usec - last_time.tv_usec) / 1000000.;
+
+ if (started && time_delta < MIN_TIME_SEPARATION)
+ return retval;
+
+ /* Create or update the progress dialog */
+ lesstif_progress_dialog (so_far, total, message);
+
+ if (!started)
+ XtManageChild (progress_dialog);
+
+ /* Dispatch one event - ideally we would keep dispatching until we
+ * were about to block, but I can't see how to do this with Xt
+ */
+ XtAppNextEvent (app_context, &e);
+ XtDispatchEvent (&e);
+
+ /* Note the time we did this */
+ gettimeofday (&last_time, NULL);
+
+ return progress_cancelled;
}
static HID *
commit 944752767041b782599180d132c1aa58251e2dbc
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
autoroute.c: When live-drawing, only emit one via per location
I'd accidentally put the live-draw via in a place where it would
emit one via for every layer group - causing warnings in PCB's
log about dropped vias.
diff --git a/src/autoroute.c b/src/autoroute.c
index 8aca7d0..c766c14 100644
--- a/src/autoroute.c
+++ b/src/autoroute.c
@@ -3205,6 +3205,17 @@ RD_DrawVia (routedata_t * rd, LocationType X, LocationType Y,
routebox_t *rb, *first_via = NULL;
int i;
int ka = AutoRouteParameters.style->Keepaway;
+ PinType *live_via = NULL;
+
+ if (TEST_FLAG (LIVEROUTEFLAG, PCB))
+ {
+ live_via = CreateNewVia (PCB->Data, X, Y, radius * 2,
+ 2 * AutoRouteParameters.style->Keepaway, 0,
+ AutoRouteParameters.style->Hole, NULL,
+ MakeFlags (0));
+ if (live_via != NULL)
+ DrawVia (live_via);
+ }
/* a via cuts through every layer group */
for (i = 0; i < max_group; i++)
@@ -3246,16 +3257,7 @@ RD_DrawVia (routedata_t * rd, LocationType X, LocationType Y,
/* and add it to the r-tree! */
r_insert_entry (rd->layergrouptree[rb->group], &rb->box, 1);
rb->flags.homeless = 0; /* not homeless anymore */
-
- if (TEST_FLAG (LIVEROUTEFLAG, PCB))
- {
- PinType *via = CreateNewVia (PCB->Data, X, Y, radius * 2,
- 2 * rb->style->Keepaway, 0,
- rb->style->Hole, NULL, MakeFlags (0));
- rb->livedraw_obj.via = via;
- if (via != NULL)
- DrawVia (via);
- }
+ rb->livedraw_obj.via = live_via;
}
}
static void
@@ -4614,11 +4616,13 @@ ripout_livedraw_obj (routebox_t *rb)
LayerType *layer = LAYER_PTR (PCB->LayerGroups.Entries[rb->group][0]);
EraseLine (rb->livedraw_obj.line);
DestroyObject (PCB->Data, LINE_TYPE, layer, rb->livedraw_obj.line, NULL);
+ rb->livedraw_obj.line = NULL;
}
if (rb->type == VIA && rb->livedraw_obj.via)
{
EraseVia (rb->livedraw_obj.via);
DestroyObject (PCB->Data, VIA_TYPE, rb->livedraw_obj.via, NULL, NULL);
+ rb->livedraw_obj.via = NULL;
}
}
|
|
From: <gi...@gp...> - 2011-05-04 02:15:43
|
The branch, master has been updated
via 07a98acbf1cb75536e777a9f240d5e338ce22f51 (commit)
from 94bad9f93afb9c18e314519d9e943ba2164f3571 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gui-library-window.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
=================
Commit Messages
=================
commit 07a98acbf1cb75536e777a9f240d5e338ce22f51
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Fix crash in library window
I missed a (GList *)->data dereference when converting to GList
object storage. Unfortunately, the parameter in question was
void * typed, so the compiler didn't notice my mistake.
:100644 100644 8c8ae17... 3c0c077... M src/hid/gtk/gui-library-window.c
=========
Changes
=========
commit 07a98acbf1cb75536e777a9f240d5e338ce22f51
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Fix crash in library window
I missed a (GList *)->data dereference when converting to GList
object storage. Unfortunately, the parameter in question was
void * typed, so the compiler didn't notice my mistake.
diff --git a/src/hid/gtk/gui-library-window.c b/src/hid/gtk/gui-library-window.c
index 8c8ae17..3c0c077 100644
--- a/src/hid/gtk/gui-library-window.c
+++ b/src/hid/gtk/gui-library-window.c
@@ -405,7 +405,7 @@ out:
/* update the preview with new symbol data */
g_object_set (library_window->preview,
- "element-data", PASTEBUFFER->Data->Element, NULL);
+ "element-data", PASTEBUFFER->Data->Element->data, NULL);
}
/*! \brief Requests re-evaluation of the filter.
|
|
From: <gi...@gp...> - 2011-05-04 01:21:39
|
The branch, master has been updated
via 94bad9f93afb9c18e314519d9e943ba2164f3571 (commit)
via 6fc0a418fb9f209b01a9525a8f762fb560bc897d (commit)
from e26a2968ba2419a4c55fb68ae9c92f0278322acb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/autoroute.c | 39 ++++++++-
src/hid/gtk/gtkhid-main.c | 208 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 243 insertions(+), 4 deletions(-)
=================
Commit Messages
=================
commit 94bad9f93afb9c18e314519d9e943ba2164f3571
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
autoroute.c: Provide a progress update for the autorouter
Provide a completion metric related to what pass the auto-router
is processing, how many objects on its heap within a given pass
it has processed, and how many sub-nets it has routed from the total.
The progress isn't entirely linear, but the subdivision of process
steps means it does at least march along without too many pauses.
It is now possible to cancel the autorouting with a non-zero response
code from the gui's progress dialog.
Tested with the GTK HID, Lesstif doesn't yet have an implementation
for HID->progress()
:100644 100644 1669a36... 8aca7d0... M src/autoroute.c
commit 6fc0a418fb9f209b01a9525a8f762fb560bc897d
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Provide a simple progress dialog implementation
:100644 100644 fd092c6... 963a691... M src/hid/gtk/gtkhid-main.c
=========
Changes
=========
commit 94bad9f93afb9c18e314519d9e943ba2164f3571
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
autoroute.c: Provide a progress update for the autorouter
Provide a completion metric related to what pass the auto-router
is processing, how many objects on its heap within a given pass
it has processed, and how many sub-nets it has routed from the total.
The progress isn't entirely linear, but the subdivision of process
steps means it does at least march along without too many pauses.
It is now possible to cancel the autorouting with a non-zero response
code from the gui's progress dialog.
Tested with the GTK HID, Lesstif doesn't yet have an implementation
for HID->progress()
diff --git a/src/autoroute.c b/src/autoroute.c
index 1669a36..8aca7d0 100644
--- a/src/autoroute.c
+++ b/src/autoroute.c
@@ -4644,12 +4644,28 @@ struct routeall_status
int ripped;
int total_nets_routed;
};
+
+static double
+calculate_progress (double this_heap_item, double this_heap_size,
+ struct routeall_status *ras)
+{
+ double total_passes = passes + smoothes + 1; /* + 1 is the refinement pass */
+ double this_pass = AutoRouteParameters.pass - 1; /* Number passes from zero */
+ double heap_fraction = (double)(ras->routed_subnets + ras->conflict_subnets + ras->failed) /
+ (double)ras->total_subnets;
+ double pass_fraction = (this_heap_item + heap_fraction ) / this_heap_size;
+ double process_fraction = (this_pass + pass_fraction) / total_passes;
+
+ return process_fraction;
+}
+
struct routeall_status
RouteAll (routedata_t * rd)
{
struct routeall_status ras;
struct routeone_status ros;
bool rip;
+ int request_cancel;
#ifdef NET_HEAP
heap_t *net_heap;
#endif
@@ -4657,6 +4673,8 @@ RouteAll (routedata_t * rd)
routebox_t *net, *p, *pp;
cost_t total_net_cost, last_cost = 0, this_cost = 0;
int i;
+ int this_heap_size;
+ int this_heap_item;
/* initialize heap for first pass;
* do smallest area first; that makes
@@ -4698,7 +4716,8 @@ RouteAll (routedata_t * rd)
ras.failed = ras.ripped = 0;
assert (heap_is_empty (next_pass));
- while (!heap_is_empty (this_pass))
+ this_heap_size = heap_size (this_pass);
+ for (this_heap_item = 0; !heap_is_empty (this_pass); this_heap_item++)
{
#ifdef ROUTE_DEBUG
if (aabort)
@@ -4822,6 +4841,8 @@ RouteAll (routedata_t * rd)
while (!ros.net_completely_routed)
{
+ double percent;
+
assert (no_expansion_boxes (rd));
/* FIX ME: the number of edges to examine should be in autoroute parameters
* i.e. the 2000 and 800 hard-coded below should be controllable by the user
@@ -4857,6 +4878,16 @@ RouteAll (routedata_t * rd)
* on the number of calls to RouteOne, because we may be unable
* to route a net from a particular starting point, but perfectly
* able to route it from some other. */
+ percent = calculate_progress (this_heap_item, this_heap_size, &ras);
+ request_cancel = gui->progress (percent * 100., 100,
+ _("Autorouting tracks"));
+ if (request_cancel)
+ {
+ ras.total_nets_routed = 0;
+ ras.conflict_subnets = 0;
+ Message ("Autorouting cancelled\n");
+ goto out;
+ }
}
}
#ifndef NET_HEAP
@@ -4887,7 +4918,6 @@ RouteAll (routedata_t * rd)
tmp = this_pass;
this_pass = next_pass;
next_pass = tmp;
- /* XXX: here we should update a status bar */
#if defined(ROUTE_DEBUG) || defined (ROUTE_VERBOSE)
printf
("END OF PASS %d: %d/%d subnets routed without conflicts at cost %.0f, %d conflicts, %d failed %d ripped\n",
@@ -4908,9 +4938,11 @@ RouteAll (routedata_t * rd)
last_cost = this_cost;
this_cost = 0;
}
+
Message ("%d of %d nets successfully routed.\n",
ras.routed_subnets, ras.total_subnets);
+out:
heap_destroy (&this_pass);
heap_destroy (&next_pass);
#ifdef NET_HEAP
@@ -5286,7 +5318,8 @@ AutoRoute (bool selected)
/* auto-route all nets */
changed = (RouteAll (rd).total_nets_routed > 0) || changed;
donerouting:
- if (changed && TEST_FLAG (LIVEROUTEFLAG, PCB))
+ gui->progress (0, 0, NULL);
+ if (TEST_FLAG (LIVEROUTEFLAG, PCB))
{
int i;
BoxType big = {0, 0, MAX_COORD, MAX_COORD};
commit 6fc0a418fb9f209b01a9525a8f762fb560bc897d
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Provide a simple progress dialog implementation
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index fd092c6..963a691 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -739,10 +739,216 @@ ghid_beep ()
gdk_beep ();
}
+struct progress_dialog
+{
+ GtkWidget *dialog;
+ GtkWidget *message;
+ GtkWidget *progress;
+ gint response_id;
+ GMainLoop *loop;
+ gboolean destroyed;
+ gboolean stop_loop;
+ gboolean started;
+ GTimer *timer;
+
+ gulong response_handler;
+ gulong unmap_handler;
+ gulong destroy_handler;
+ gulong delete_handler;
+};
+
+static void
+run_unmap_handler (GtkDialog *dialog, gpointer data)
+{
+ struct progress_dialog *pd = data;
+
+ pd->stop_loop = TRUE;
+}
+
+static void
+run_response_handler (GtkDialog *dialog,
+ gint response_id,
+ gpointer data)
+{
+ struct progress_dialog *pd = data;
+
+ pd->response_id = response_id;
+ pd->stop_loop = TRUE;
+}
+
+static gint
+run_delete_handler (GtkDialog *dialog,
+ GdkEventAny *event,
+ gpointer data)
+{
+ struct progress_dialog *pd = data;
+
+ pd->stop_loop = TRUE;
+
+ return TRUE; /* Do not destroy */
+}
+
+static void
+run_destroy_handler (GtkDialog *dialog, gpointer data)
+{
+ struct progress_dialog *pd = data;
+
+ /* stop_loop will be set by run_unmap_handler */
+
+ pd->destroyed = TRUE;
+}
+
+static struct progress_dialog *
+make_progress_dialog (void)
+{
+ struct progress_dialog *pd;
+ GtkWidget *alignment;
+ GtkWidget *vbox;
+
+ pd = g_new0 (struct progress_dialog, 1);
+ pd->response_id = GTK_RESPONSE_NONE;
+
+ pd->dialog = gtk_dialog_new_with_buttons (_("Progress"),
+ GTK_WINDOW (gport->top_window),
+ /* Modal so nothing else can get events whilst
+ the main mainloop isn't running */
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+
+ gtk_window_set_deletable (GTK_WINDOW (pd->dialog), FALSE);
+ gtk_window_set_skip_pager_hint (GTK_WINDOW (pd->dialog), TRUE);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (pd->dialog), TRUE);
+ gtk_widget_set_size_request (pd->dialog, 300, -1);
+
+ pd->message = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (pd->message), 0., 0.);
+
+ pd->progress = gtk_progress_bar_new ();
+ gtk_widget_set_size_request (pd->progress, -1, 26);
+
+ vbox = gtk_vbox_new (false, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), pd->message, true, true, 8);
+ gtk_box_pack_start (GTK_BOX (vbox), pd->progress, false, true, 8);
+
+ alignment = gtk_alignment_new (0., 0., 1., 1.);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 8, 8, 8, 8);
+ gtk_container_add (GTK_CONTAINER (alignment), vbox);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pd->dialog)->vbox),
+ alignment, true, true, 0);
+
+ gtk_widget_show_all (alignment);
+
+ g_object_ref (pd->dialog);
+ gtk_window_present (GTK_WINDOW (pd->dialog));
+
+ pd->response_handler =
+ g_signal_connect (pd->dialog, "response",
+ G_CALLBACK (run_response_handler), pd);
+ pd->unmap_handler =
+ g_signal_connect (pd->dialog, "unmap",
+ G_CALLBACK (run_unmap_handler), pd);
+ pd->delete_handler =
+ g_signal_connect (pd->dialog, "delete-event",
+ G_CALLBACK (run_delete_handler), pd);
+ pd->destroy_handler =
+ g_signal_connect (pd->dialog, "destroy",
+ G_CALLBACK (run_destroy_handler), pd);
+
+ pd->loop = g_main_loop_new (NULL, FALSE);
+ pd->timer = g_timer_new ();
+
+ return pd;
+}
+
+static void
+destroy_progress_dialog (struct progress_dialog *pd)
+{
+ if (pd == NULL)
+ return;
+
+ if (!pd->destroyed)
+ {
+ g_signal_handler_disconnect (pd->dialog, pd->response_handler);
+ g_signal_handler_disconnect (pd->dialog, pd->unmap_handler);
+ g_signal_handler_disconnect (pd->dialog, pd->delete_handler);
+ g_signal_handler_disconnect (pd->dialog, pd->destroy_handler);
+ }
+
+ g_timer_destroy (pd->timer);
+ g_object_unref (pd->dialog);
+ g_main_loop_unref (pd->loop);
+
+ gtk_widget_destroy (pd->dialog);
+
+ pd->loop = NULL;
+ g_free (pd);
+}
+
+static void
+handle_progress_dialog_events (struct progress_dialog *pd)
+{
+ GMainContext * context = g_main_loop_get_context (pd->loop);
+
+ /* Process events */
+ while (g_main_context_pending (context))
+ {
+ g_main_context_iteration (context, FALSE);
+ }
+}
+
+#define MIN_TIME_SEPARATION (50./1000.) /* 50ms */
static int
ghid_progress (int so_far, int total, const char *message)
{
- return 0;
+ static struct progress_dialog *pd = NULL;
+ int retval = 0;
+
+ /* If we are finished, destroy any dialog */
+ if (so_far == 0 && total == 0 && message == NULL)
+ {
+ destroy_progress_dialog (pd);
+ pd = NULL;
+ return retval;
+ }
+
+ if (pd == NULL)
+ {
+ pd = make_progress_dialog ();
+ }
+
+ /* We don't want to keep the underlying process too busy whilst we
+ * process events. If we get called quickly after the last progress
+ * update, wait a little bit before we respond - perhaps the next
+ * time progress is reported.
+
+ * The exception here is that we always want to process the first
+ * batch of events after having shown the dialog for the first time
+ */
+ if (pd->started && g_timer_elapsed (pd->timer, NULL) < MIN_TIME_SEPARATION)
+ return 0;
+
+ gtk_label_set_text (GTK_LABEL (pd->message), message);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pd->progress),
+ (double)so_far / (double)total);
+
+ handle_progress_dialog_events (pd);
+ g_timer_start (pd->timer);
+
+ pd->started = TRUE;
+
+ if (pd->stop_loop)
+ {
+ retval = (pd->response_id == GTK_RESPONSE_CANCEL ||
+ pd->response_id == GTK_RESPONSE_DELETE_EVENT ||
+ pd->response_id == GTK_RESPONSE_NONE);
+ destroy_progress_dialog (pd);
+ pd = NULL;
+ }
+
+ return retval;
}
/* ---------------------------------------------------------------------- */
|
|
From: <gi...@gp...> - 2011-05-03 22:01:39
|
The branch, master has been updated
via e26a2968ba2419a4c55fb68ae9c92f0278322acb (commit)
from 1ee3dff0de39f0cfbfa91d3643b47ba37215f692 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/gtk/gtkhid-gdk.c | 5 +++++
src/hid/gtk/gtkhid-gl.c | 18 ++++++++++++++++++
src/hid/gtk/gui-top-window.c | 3 +++
src/hid/gtk/gui.h | 1 +
4 files changed, 27 insertions(+), 0 deletions(-)
=================
Commit Messages
=================
commit e26a2968ba2419a4c55fb68ae9c92f0278322acb
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Fix mesa crash on startup (for some mesa versions)
I'm not sure why it crashed, but it seems that providing a realize
handler which fiddles with the GL context solves it. The underlying
problem appears to have been fixed in later mesa versions.
Leaving this commit for the benefit users of broken mesa versions.
:100644 100644 4534905... 882af60... M src/hid/gtk/gtkhid-gdk.c
:100644 100644 0923110... 16247a8... M src/hid/gtk/gtkhid-gl.c
:100644 100644 ca82b96... 31be13a... M src/hid/gtk/gui-top-window.c
:100644 100644 7a18906... 31ee636... M src/hid/gtk/gui.h
=========
Changes
=========
commit e26a2968ba2419a4c55fb68ae9c92f0278322acb
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Fix mesa crash on startup (for some mesa versions)
I'm not sure why it crashed, but it seems that providing a realize
handler which fiddles with the GL context solves it. The underlying
problem appears to have been fixed in later mesa versions.
Leaving this commit for the benefit users of broken mesa versions.
diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index 4534905..882af60 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -1130,6 +1130,11 @@ ghid_drawing_area_expose_cb (GtkWidget *widget,
return FALSE;
}
+void
+ghid_port_drawing_realize_cb (GtkWidget *widget, gpointer data)
+{
+}
+
gboolean
ghid_pinout_preview_expose (GtkWidget *widget,
GdkEventExpose *ev)
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index 0923110..16247a8 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -885,6 +885,24 @@ ghid_drawing_area_expose_cb (GtkWidget *widget,
return FALSE;
}
+/* This realize callback is used to work around a crash bug in some mesa
+ * versions (observed on a machine running the intel i965 driver. It isn't
+ * obvious why it helps, but somehow fiddling with the GL context here solves
+ * the issue. The problem appears to have been fixed in recent mesa versions.
+ */
+void
+ghid_port_drawing_realize_cb (GtkWidget *widget, gpointer data)
+{
+ GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
+
+ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
+ return;
+
+ gdk_gl_drawable_gl_end (gldrawable);
+ return;
+}
+
gboolean
ghid_pinout_preview_expose (GtkWidget *widget,
GdkEventExpose *ev)
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index ca82b96..31be13a 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -2357,6 +2357,9 @@ ghid_build_pcb_top_window (void)
| the user does a command entry.
*/
+ g_signal_connect (G_OBJECT (gport->drawing_area), "realize",
+ G_CALLBACK (ghid_port_drawing_realize_cb),
+ port);
g_signal_connect (G_OBJECT (gport->drawing_area), "expose_event",
G_CALLBACK (ghid_drawing_area_expose_cb),
port);
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 7a18906..31ee636 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -496,6 +496,7 @@ void ghid_drawing_area_configure_hook (GHidPort *port);
void ghid_screen_update (void);
gboolean ghid_drawing_area_expose_cb (GtkWidget *, GdkEventExpose *,
GHidPort *);
+void ghid_port_drawing_realize_cb (GtkWidget *, gpointer);
gboolean ghid_pinout_preview_expose (GtkWidget * widget, GdkEventExpose * ev);
GdkPixmap *ghid_render_pixmap (int cx, int cy, double zoom,
int width, int height, int depth);
|
|
From: <gi...@gp...> - 2011-05-03 21:23:57
|
The branch, master has been updated
via 1ee3dff0de39f0cfbfa91d3643b47ba37215f692 (commit)
from d9f4025a8c9adbbedcdef5aee4f5af3036b326a8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
configure.ac | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
=================
Commit Messages
=================
commit 1ee3dff0de39f0cfbfa91d3643b47ba37215f692
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Make --enable-gl default when building the GTK HID
Lets get this feature some testing for now - we may decide to revert
the default before the next release, depending on how things progress.
:100644 100644 2637495... 94c6779... M configure.ac
=========
Changes
=========
commit 1ee3dff0de39f0cfbfa91d3643b47ba37215f692
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
Make --enable-gl default when building the GTK HID
Lets get this feature some testing for now - we may decide to revert
the default before the next release, depending on how things progress.
diff --git a/configure.ac b/configure.ac
index 2637495..94c6779 100644
--- a/configure.ac
+++ b/configure.ac
@@ -393,8 +393,12 @@ fi
AC_MSG_CHECKING([for whether to use GL drawing])
AC_ARG_ENABLE([gl],
[ --enable-gl Enable GL drawing (with GTK HID)],
-[],[enable_gl=no])
-
+[],[
+ case " $with_gui " in
+ *\ gtk\ *) enable_gl=yes;;
+ * ) enable_gl=no;;
+ esac
+])
AC_MSG_RESULT([$enable_gl])
AM_CONDITIONAL(USE_GL, test x$enable_gl = xyes)
|
|
From: <gi...@gp...> - 2011-05-03 21:23:42
|
The branch, master has been updated
via d9f4025a8c9adbbedcdef5aee4f5af3036b326a8 (commit)
from 9acdd88e22717510ff5dde277ecbd6f1de60b69d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
configure.ac | 55 +++-
src/Makefile.am | 21 +-
src/hid/common/hidgl.c | 557 +++++++++++++++++++++++
src/hid/common/hidgl.h | 79 ++++
src/hid/gtk/gtkhid-gl.c | 1159 +++++++++++++++++++++++++++++++++++++++++++++++
src/hid/gtk/gui.h | 2 +-
6 files changed, 1868 insertions(+), 5 deletions(-)
create mode 100644 src/hid/common/hidgl.c
create mode 100644 src/hid/common/hidgl.h
create mode 100644 src/hid/gtk/gtkhid-gl.c
=================
Commit Messages
=================
commit d9f4025a8c9adbbedcdef5aee4f5af3036b326a8
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Drop in GL renderer - WOOT!
Much of the generic GL drawing stuff lives in a new common helper,
hid/common/hidgl.[ch]. Unavoidably, there is a lot of GUI specific
setup and teardown code.
There are probably still bits of code in hid/gtk/gtkhid-gl.c which
could be moved to a shared place if / when other HIDs wish to use
GL rendering.
Currently only rat lines are drawn transparent, as we need to sub-
composite each layer to avoid a confusing field of hightlights being
drawn where line ends overlap.
configure --enable-gl now checks for the required GL, glu and GtkGLEext.
More good stuff to come soon!
Credits:
Algorithm to calculate number of segments to use in circular
curve approximation suggested by DJ Delorie.
Thanks to Krzysztof KoÅciuszkiewicz for testing and debugging
some issues with the GL_SCISSOR_TEST being used.
An small team of dedicated testers who have provided feedback,
bug reports and encoragement throught the long development of
this branch.
:100644 100644 ab6986f... 2637495... M configure.ac
:100644 100644 5abbfb2... 8129207... M src/Makefile.am
:000000 100644 0000000... 1745891... A src/hid/common/hidgl.c
:000000 100644 0000000... 282b144... A src/hid/common/hidgl.h
:000000 100644 0000000... 0923110... A src/hid/gtk/gtkhid-gl.c
:100644 100644 d52d088... 7a18906... M src/hid/gtk/gui.h
=========
Changes
=========
commit d9f4025a8c9adbbedcdef5aee4f5af3036b326a8
Author: Peter Clifton <pc...@ca...>
Commit: Peter Clifton <pc...@ca...>
hid/gtk: Drop in GL renderer - WOOT!
Much of the generic GL drawing stuff lives in a new common helper,
hid/common/hidgl.[ch]. Unavoidably, there is a lot of GUI specific
setup and teardown code.
There are probably still bits of code in hid/gtk/gtkhid-gl.c which
could be moved to a shared place if / when other HIDs wish to use
GL rendering.
Currently only rat lines are drawn transparent, as we need to sub-
composite each layer to avoid a confusing field of hightlights being
drawn where line ends overlap.
configure --enable-gl now checks for the required GL, glu and GtkGLEext.
More good stuff to come soon!
Credits:
Algorithm to calculate number of segments to use in circular
curve approximation suggested by DJ Delorie.
Thanks to Krzysztof KoÅciuszkiewicz for testing and debugging
some issues with the GL_SCISSOR_TEST being used.
An small team of dedicated testers who have provided feedback,
bug reports and encoragement throught the long development of
this branch.
diff --git a/configure.ac b/configure.ac
index ab6986f..2637495 100644
--- a/configure.ac
+++ b/configure.ac
@@ -389,6 +389,46 @@ $DBUS_PKG_ERRORS])]
fi
+
+AC_MSG_CHECKING([for whether to use GL drawing])
+AC_ARG_ENABLE([gl],
+[ --enable-gl Enable GL drawing (with GTK HID)],
+[],[enable_gl=no])
+
+AC_MSG_RESULT([$enable_gl])
+AM_CONDITIONAL(USE_GL, test x$enable_gl = xyes)
+
+if test "x$enable_gl" = "xyes"; then
+ case " $with_gui " in
+ *\ gtk\ *) ;;
+ * ) AC_MSG_ERROR([GL drawing enabled but only works with the GTK HID.
+Either do not use --enable-gl or enable the gtk HID.])
+ ;;
+ esac
+
+ AC_CHECK_HEADERS(GL/gl.h)
+ case $ac_cv_header_GL_gl_h in
+ no )
+ AC_MSG_ERROR([You don't seem to have the GL library headers installed.])
+ ;;
+ * ) ;;
+ esac
+
+ AC_CHECK_HEADERS(GL/glu.h)
+ case $ac_cv_header_GL_glu_h in
+ no )
+ AC_MSG_ERROR([You don't seem to have the GL glu library headers installed.])
+ ;;
+ * ) ;;
+ esac
+
+ GLU_CFLAGS=
+ GLU_LIBS=-lGLU
+
+ AC_DEFINE([ENABLE_GL], 1,
+ [Define to 1 if GL support is to be compiled in])
+fi
+
AC_MSG_CHECKING([for which printer to use])
AC_ARG_WITH([printer],
[ --with-printer= Specify the printer: lpr [[default=lpr]]],
@@ -723,6 +763,17 @@ $GTK_PKG_ERRORS])]
)
GTK_VERSION=`$PKG_CONFIG gtk+-2.0 --modversion`
GLIB_VERSION=`$PKG_CONFIG glib-2.0 --modversion`
+
+ if test "x$enable_gl" = "xyes"; then
+ # Check for GtkGLExt
+ PKG_CHECK_MODULES(GTKGLEXT, gtkglext-1.0 >= 1.0.0, , [AC_MSG_ERROR([
+*** Required version of gtkglext is not installed - please install first ***
+Please review the following errors:
+$GTKGLEXT_PKG_ERRORS])]
+ )
+ GTKGLEXT_VER=`$PKG_CONFIG gtkglext-1.0 --modversion`
+ fi
+
;;
gcode|nelma|png )
@@ -1015,8 +1066,8 @@ AX_FUNC_MKDIR
# ------------- Complete set of CFLAGS and LIBS -------------------
-CFLAGS="$CFLAGS $X_CFLAGS $DBUS_CFLAGS $GLIB_CFLAGS $GTK_CFLAGS $CAIRO_CFLAGS"
-LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GLIB_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS $INTLLIBS $CAIRO_LIBS"
+CFLAGS="$CFLAGS $X_CFLAGS $DBUS_CFLAGS $GLIB_CFLAGS $GTK_CFLAGS $CAIRO_CFLAGS $GTKGLEXT_CFLAGS $GLU_CFLAGS"
+LIBS="$LIBS $XM_LIBS $DBUS_LIBS $X_LIBS $GLIB_LIBS $GTK_LIBS $DMALLOC_LIBS $GD_LIBS $INTLLIBS $CAIRO_LIBS $GTKGLEXT_LIBS $GLU_LIBS"
# if we have gcc then add -Wall
diff --git a/src/Makefile.am b/src/Makefile.am
index 5abbfb2..8129207 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -157,13 +157,23 @@ PCB_SRCS = \
hid/common/hid_resource.h \
hid/hidint.h
-EXTRA_pcb_SOURCES = ${DBUS_SRCS} toporouter.c toporouter.h
+EXTRA_pcb_SOURCES = ${DBUS_SRCS} ${GL_SRCS} toporouter.c toporouter.h
DBUS_SRCS= \
dbus-pcbmain.c \
dbus-pcbmain.h \
dbus.h \
dbus.c
+LIBGTK_GDK_SRCS= \
+ hid/gtk/gtkhid-gdk.c
+
+LIBGTK_GL_SRCS= \
+ hid/gtk/gtkhid-gl.c
+
+GL_SRCS= \
+ hid/common/hidgl.c \
+ hid/common/hidgl.h
+
BUILT_SOURCES = \
core_lists.h \
gpcb-menu.h \
@@ -250,7 +260,6 @@ LIBGTK_SRCS = \
dolists.h \
hid/hidint.h \
hid/gtk/gtkhid-main.c \
- hid/gtk/gtkhid-gdk.c \
hid/gtk/gtkhid.h \
hid/gtk/gui.h \
hid/gtk/gui-command-window.c \
@@ -294,6 +303,14 @@ BUILT_SOURCES+= dbus-introspect.h
endif
+# If we are building with GL support, we need some extra files
+if USE_GL
+PCB_SRCS+= ${GL_SRCS}
+LIBGTK_SRCS+= ${LIBGTK_GL_SRCS}
+else
+LIBGTK_SRCS+= ${LIBGTK_GDK_SRCS}
+endif
+
# If we are building on win32, then compile in some icons for the
# desktop and application toolbar
if WIN32
diff --git a/src/hid/common/hidgl.c b/src/hid/common/hidgl.c
new file mode 100644
index 0000000..1745891
--- /dev/null
+++ b/src/hid/common/hidgl.c
@@ -0,0 +1,557 @@
+/*
+ * COPYRIGHT
+ *
+ * PCB, interactive printed circuit board design
+ * Copyright (C) 2009-2011 PCB Contributers (See ChangeLog for details)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <math.h>
+#include <assert.h>
+
+/* The Linux OpenGL ABI 1.0 spec requires that we define
+ * GL_GLEXT_PROTOTYPES before including gl.h or glx.h for extensions
+ * in order to get prototypes:
+ * http://www.opengl.org/registry/ABI/
+ */
+#define GL_GLEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include "action.h"
+#include "crosshair.h"
+#include "data.h"
+#include "draw.h"
+#include "error.h"
+#include "global.h"
+#include "mymem.h"
+#include "draw.h"
+#include "clip.h"
+
+#include "hid.h"
+#include "hidgl.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+
+triangle_buffer buffer;
+float global_depth = 0;
+
+void
+hidgl_init_triangle_array (triangle_buffer *buffer)
+{
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glVertexPointer (3, GL_FLOAT, 0, buffer->triangle_array);
+ buffer->triangle_count = 0;
+ buffer->coord_comp_count = 0;
+}
+
+void
+hidgl_flush_triangles (triangle_buffer *buffer)
+{
+ if (buffer->triangle_count == 0)
+ return;
+
+ glDrawArrays (GL_TRIANGLES, 0, buffer->triangle_count * 3);
+ buffer->triangle_count = 0;
+ buffer->coord_comp_count = 0;
+}
+
+void
+hidgl_ensure_triangle_space (triangle_buffer *buffer, int count)
+{
+ if (count > TRIANGLE_ARRAY_SIZE)
+ {
+ fprintf (stderr, "Not enough space in vertex buffer\n");
+ fprintf (stderr, "Requested %i triangles, %i available\n",
+ count, TRIANGLE_ARRAY_SIZE);
+ exit (1);
+ }
+ if (count > TRIANGLE_ARRAY_SIZE - buffer->triangle_count)
+ hidgl_flush_triangles (buffer);
+}
+
+void
+hidgl_set_depth (float depth)
+{
+ global_depth = depth;
+}
+
+void
+hidgl_draw_grid (BoxType *drawn_area)
+{
+ static GLfloat *points = 0;
+ static int npoints = 0;
+ int x1, y1, x2, y2, n, i;
+ double x, y;
+
+ 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);
+
+ if (x1 > x2)
+ {
+ int tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+
+ if (y1 > y2)
+ {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1;
+ if (n > npoints)
+ {
+ npoints = n + 10;
+ points = realloc (points, npoints * 3 * sizeof (GLfloat));
+ }
+
+ glEnableClientState (GL_VERTEX_ARRAY);
+ glVertexPointer (3, GL_FLOAT, 0, points);
+
+ n = 0;
+ for (x = x1; x <= x2; x += PCB->Grid)
+ {
+ points[3 * n + 0] = x;
+ points[3 * n + 2] = global_depth;
+ n++;
+ }
+ for (y = y1; y <= y2; y += PCB->Grid)
+ {
+ for (i = 0; i < n; i++)
+ points[3 * i + 1] = y;
+ glDrawArrays (GL_POINTS, 0, n);
+ }
+
+ glDisableClientState (GL_VERTEX_ARRAY);
+}
+
+#define MAX_PIXELS_ARC_TO_CHORD 0.5
+#define MIN_SLICES 6
+int calc_slices (float pix_radius, float sweep_angle)
+{
+ float slices;
+
+ if (pix_radius <= MAX_PIXELS_ARC_TO_CHORD)
+ return MIN_SLICES;
+
+ slices = sweep_angle / acosf (1 - MAX_PIXELS_ARC_TO_CHORD / pix_radius) / 2.;
+ return (int)ceilf (slices);
+}
+
+#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)
+{
+ float last_capx, last_capy;
+ float capx, capy;
+ float radius = width / 2.;
+ int slices = calc_slices (radius / scale, M_PI);
+ int i;
+
+ if (slices < MIN_TRIANGLES_PER_CAP)
+ slices = MIN_TRIANGLES_PER_CAP;
+
+ if (slices > MAX_TRIANGLES_PER_CAP)
+ slices = MAX_TRIANGLES_PER_CAP;
+
+ hidgl_ensure_triangle_space (&buffer, slices);
+
+ last_capx = radius * cosf (angle * M_PI / 180.) + x;
+ last_capy = -radius * sinf (angle * M_PI / 180.) + y;
+ for (i = 0; i < slices; i++) {
+ capx = radius * cosf (angle * M_PI / 180. + ((float)(i + 1)) * M_PI / (float)slices) + x;
+ capy = -radius * sinf (angle * M_PI / 180. + ((float)(i + 1)) * M_PI / (float)slices) + y;
+ hidgl_add_triangle (&buffer, last_capx, last_capy, capx, capy, x, y);
+ last_capx = capx;
+ last_capy = capy;
+ }
+}
+
+void
+hidgl_draw_line (int cap, double width, int x1, int y1, int x2, int y2, double scale)
+{
+ double angle;
+ float deltax, deltay, length;
+ float wdx, wdy;
+ int circular_caps = 0;
+ int hairline = 0;
+
+ if (width == 0.0)
+ hairline = 1;
+
+ if (width < scale)
+ width = scale;
+
+ deltax = x2 - x1;
+ deltay = y2 - y1;
+
+ length = sqrt (deltax * deltax + deltay * deltay);
+
+ if (length == 0) {
+ /* Assume the orientation of the line is horizontal */
+ angle = 0;
+ wdx = -width / 2.;
+ wdy = 0;
+ length = 1.;
+ deltax = 1.;
+ deltay = 0.;
+ } else {
+ wdy = deltax * width / 2. / length;
+ wdx = -deltay * width / 2. / length;
+
+ if (deltay == 0.)
+ angle = (deltax < 0) ? 270. : 90.;
+ else
+ angle = 180. / M_PI * atanl (deltax / deltay);
+
+ if (deltay < 0)
+ angle += 180.;
+ }
+
+ switch (cap) {
+ case Trace_Cap:
+ case Round_Cap:
+ circular_caps = 1;
+ break;
+
+ case Square_Cap:
+ case Beveled_Cap:
+ x1 -= deltax * width / 2. / length;
+ y1 -= deltay * width / 2. / length;
+ x2 += deltax * width / 2. / length;
+ y2 += deltay * width / 2. / length;
+ break;
+ }
+
+ hidgl_ensure_triangle_space (&buffer, 2);
+ hidgl_add_triangle (&buffer, x1 - wdx, y1 - wdy,
+ x2 - wdx, y2 - wdy,
+ x2 + wdx, y2 + wdy);
+ hidgl_add_triangle (&buffer, x1 - wdx, y1 - wdy,
+ x2 + wdx, y2 + wdy,
+ x1 + wdx, y1 + wdy);
+
+ /* Don't bother capping hairlines */
+ if (circular_caps && !hairline)
+ {
+ draw_cap (width, x1, y1, angle, scale);
+ draw_cap (width, x2, y2, angle + 180., scale);
+ }
+}
+
+#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)
+{
+ float last_inner_x, last_inner_y;
+ float last_outer_x, last_outer_y;
+ float inner_x, inner_y;
+ float outer_x, outer_y;
+ float inner_r;
+ float outer_r;
+ float cos_ang, sin_ang;
+ float start_angle_rad;
+ float delta_angle_rad;
+ float angle_incr_rad;
+ int slices;
+ int i;
+ int hairline = 0;
+
+ if (width == 0.0)
+ hairline = 1;
+
+ if (width < scale)
+ width = scale;
+
+ inner_r = rx - width / 2.;
+ outer_r = rx + width / 2.;
+
+ if (delta_angle < 0) {
+ start_angle += delta_angle;
+ delta_angle = - delta_angle;
+ }
+
+ start_angle_rad = start_angle * M_PI / 180.;
+ delta_angle_rad = delta_angle * M_PI / 180.;
+
+ slices = calc_slices ((rx + width / 2.) / scale, delta_angle_rad);
+
+ if (slices < MIN_SLICES_PER_ARC)
+ slices = MIN_SLICES_PER_ARC;
+
+ if (slices > MAX_SLICES_PER_ARC)
+ slices = MAX_SLICES_PER_ARC;
+
+ hidgl_ensure_triangle_space (&buffer, 2 * slices);
+
+ angle_incr_rad = delta_angle_rad / (float)slices;
+
+ cos_ang = cosf (start_angle_rad);
+ sin_ang = sinf (start_angle_rad);
+ last_inner_x = -inner_r * cos_ang + x; last_inner_y = inner_r * sin_ang + y;
+ last_outer_x = -outer_r * cos_ang + x; last_outer_y = outer_r * sin_ang + y;
+ for (i = 1; i <= slices; i++) {
+ cos_ang = cosf (start_angle_rad + ((float)(i)) * angle_incr_rad);
+ sin_ang = sinf (start_angle_rad + ((float)(i)) * angle_incr_rad);
+ inner_x = -inner_r * cos_ang + x; inner_y = inner_r * sin_ang + y;
+ outer_x = -outer_r * cos_ang + x; outer_y = outer_r * sin_ang + y;
+ hidgl_add_triangle (&buffer, last_inner_x, last_inner_y,
+ last_outer_x, last_outer_y,
+ outer_x, outer_y);
+ hidgl_add_triangle (&buffer, last_inner_x, last_inner_y,
+ inner_x, inner_y,
+ outer_x, outer_y);
+ last_inner_x = inner_x; last_inner_y = inner_y;
+ last_outer_x = outer_x; last_outer_y = outer_y;
+ }
+
+ /* Don't bother capping hairlines */
+ if (hairline)
+ return;
+
+ draw_cap (width, x + rx * -cosf (start_angle_rad),
+ y + rx * sinf (start_angle_rad),
+ start_angle, scale);
+ draw_cap (width, x + rx * -cosf (start_angle_rad + delta_angle_rad),
+ y + rx * sinf (start_angle_rad + delta_angle_rad),
+ start_angle + delta_angle + 180., scale);
+}
+
+void
+hidgl_draw_rect (int x1, int y1, int x2, int y2)
+{
+ glBegin (GL_LINE_LOOP);
+ glVertex3f (x1, y1, global_depth);
+ glVertex3f (x1, y2, global_depth);
+ glVertex3f (x2, y2, global_depth);
+ glVertex3f (x2, y1, global_depth);
+ glEnd ();
+}
+
+
+void
+hidgl_fill_circle (int vx, int vy, int vr, double scale)
+{
+#define MIN_TRIANGLES_PER_CIRCLE 6
+#define MAX_TRIANGLES_PER_CIRCLE 360
+ float last_x, last_y;
+ float radius = vr;
+ int slices;
+ int i;
+
+ slices = calc_slices (vr / scale, 2 * M_PI);
+
+ if (slices < MIN_TRIANGLES_PER_CIRCLE)
+ slices = MIN_TRIANGLES_PER_CIRCLE;
+
+ if (slices > MAX_TRIANGLES_PER_CIRCLE)
+ slices = MAX_TRIANGLES_PER_CIRCLE;
+
+ hidgl_ensure_triangle_space (&buffer, slices);
+
+ last_x = vx + vr;
+ last_y = vy;
+
+ for (i = 0; i < slices; i++) {
+ float x, y;
+ x = radius * cosf (((float)(i + 1)) * 2. * M_PI / (float)slices) + vx;
+ y = radius * sinf (((float)(i + 1)) * 2. * M_PI / (float)slices) + vy;
+ hidgl_add_triangle (&buffer, vx, vy, last_x, last_y, x, y);
+ last_x = x;
+ last_y = y;
+ }
+}
+
+#define MAX_COMBINED_MALLOCS 2500
+static void *combined_to_free [MAX_COMBINED_MALLOCS];
+static int combined_num_to_free = 0;
+
+static GLenum tessVertexType;
+static int stashed_vertices;
+static int triangle_comp_idx;
+
+
+static void
+myError (GLenum errno)
+{
+ printf ("gluTess error: %s\n", gluErrorString (errno));
+}
+
+static void
+myFreeCombined ()
+{
+ while (combined_num_to_free)
+ free (combined_to_free [-- combined_num_to_free]);
+}
+
+static void
+myCombine ( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **dataOut )
+{
+#define MAX_COMBINED_VERTICES 2500
+ static GLdouble combined_vertices [3 * MAX_COMBINED_VERTICES];
+ static int num_combined_vertices = 0;
+
+ GLdouble *new_vertex;
+
+ if (num_combined_vertices < MAX_COMBINED_VERTICES)
+ {
+ new_vertex = &combined_vertices [3 * num_combined_vertices];
+ num_combined_vertices ++;
+ }
+ else
+ {
+ new_vertex = malloc (3 * sizeof (GLdouble));
+
+ if (combined_num_to_free < MAX_COMBINED_MALLOCS)
+ combined_to_free [combined_num_to_free ++] = new_vertex;
+ else
+ printf ("myCombine leaking %lu bytes of memory\n", 3 * sizeof (GLdouble));
+ }
+
+ new_vertex[0] = coords[0];
+ new_vertex[1] = coords[1];
+ new_vertex[2] = coords[2];
+
+ *dataOut = new_vertex;
+}
+
+static void
+myBegin (GLenum type)
+{
+ tessVertexType = type;
+ stashed_vertices = 0;
+ triangle_comp_idx = 0;
+}
+
+static void
+myVertex (GLdouble *vertex_data)
+{
+ static GLfloat triangle_vertices [2 * 3];
+
+ if (tessVertexType == GL_TRIANGLE_STRIP ||
+ tessVertexType == GL_TRIANGLE_FAN)
+ {
+ if (stashed_vertices < 2)
+ {
+ triangle_vertices [triangle_comp_idx ++] = vertex_data [0];
+ triangle_vertices [triangle_comp_idx ++] = vertex_data [1];
+ stashed_vertices ++;
+ }
+ else
+ {
+ hidgl_ensure_triangle_space (&buffer, 1);
+ hidgl_add_triangle (&buffer,
+ triangle_vertices [0], triangle_vertices [1],
+ triangle_vertices [2], triangle_vertices [3],
+ vertex_data [0], vertex_data [1]);
+
+ if (tessVertexType == GL_TRIANGLE_STRIP)
+ {
+ /* STRIP saves the last two vertices for re-use in the next triangle */
+ triangle_vertices [0] = triangle_vertices [2];
+ triangle_vertices [1] = triangle_vertices [3];
+ }
+ /* Both FAN and STRIP save the last vertex for re-use in the next triangle */
+ triangle_vertices [2] = vertex_data [0];
+ triangle_vertices [3] = vertex_data [1];
+ }
+ }
+ else if (tessVertexType == GL_TRIANGLES)
+ {
+ triangle_vertices [triangle_comp_idx ++] = vertex_data [0];
+ triangle_vertices [triangle_comp_idx ++] = vertex_data [1];
+ stashed_vertices ++;
+ if (stashed_vertices == 3)
+ {
+ hidgl_ensure_triangle_space (&buffer, 1);
+ hidgl_add_triangle (&buffer,
+ triangle_vertices [0], triangle_vertices [1],
+ triangle_vertices [2], triangle_vertices [3],
+ triangle_vertices [4], triangle_vertices [5]);
+ triangle_comp_idx = 0;
+ stashed_vertices = 0;
+ }
+ }
+ else
+ printf ("Vertex recieved with unknown type\n");
+}
+
+void
+hidgl_fill_polygon (int n_coords, int *x, int *y)
+{
+ int i;
+ GLUtesselator *tobj;
+ GLdouble *vertices;
+
+ assert (n_coords > 0);
+
+ vertices = malloc (sizeof(GLdouble) * n_coords * 3);
+
+ tobj = gluNewTess ();
+ gluTessCallback(tobj, GLU_TESS_BEGIN, myBegin);
+ gluTessCallback(tobj, GLU_TESS_VERTEX, myVertex);
+ gluTessCallback(tobj, GLU_TESS_COMBINE, myCombine);
+ gluTessCallback(tobj, GLU_TESS_ERROR, myError);
+
+ gluTessBeginPolygon (tobj, NULL);
+ gluTessBeginContour (tobj);
+
+ for (i = 0; i < n_coords; i++)
+ {
+ vertices [0 + i * 3] = x[i];
+ vertices [1 + i * 3] = y[i];
+ vertices [2 + i * 3] = 0.;
+ gluTessVertex (tobj, &vertices [i * 3], &vertices [i * 3]);
+ }
+
+ gluTessEndContour (tobj);
+ gluTessEndPolygon (tobj);
+ gluDeleteTess (tobj);
+
+ myFreeCombined ();
+ free (vertices);
+}
+
+void
+hidgl_fill_rect (int x1, int y1, int x2, int y2)
+{
+ hidgl_ensure_triangle_space (&buffer, 2);
+ hidgl_add_triangle (&buffer, x1, y1, x1, y2, x2, y2);
+ hidgl_add_triangle (&buffer, x2, y1, x2, y2, x1, y1);
+}
diff --git a/src/hid/common/hidgl.h b/src/hid/common/hidgl.h
new file mode 100644
index 0000000..282b144
--- /dev/null
+++ b/src/hid/common/hidgl.h
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT
+ *
+ * PCB, interactive printed circuit board design
+ * Copyright (C) 2009-2011 PCB Contributors (See ChangeLog for details).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __HIDGL_INCLUDED__
+#define __HIDGL_INCLUDED__
+
+#define TRIANGLE_ARRAY_SIZE 5461
+typedef struct {
+ GLfloat triangle_array [3 * 3 * TRIANGLE_ARRAY_SIZE];
+ unsigned int triangle_count;
+ unsigned int coord_comp_count;
+} triangle_buffer;
+
+extern triangle_buffer buffer;
+extern float global_depth;
+
+void hidgl_init_triangle_array (triangle_buffer *buffer);
+void hidgl_flush_triangles (triangle_buffer *buffer);
+void hidgl_ensure_triangle_space (triangle_buffer *buffer, int count);
+
+static inline void
+hidgl_add_triangle_3D (triangle_buffer *buffer,
+ GLfloat x1, GLfloat y1, GLfloat z1,
+ GLfloat x2, GLfloat y2, GLfloat z2,
+ GLfloat x3, GLfloat y3, GLfloat z3)
+{
+ buffer->triangle_array [buffer->coord_comp_count++] = x1;
+ buffer->triangle_array [buffer->coord_comp_count++] = y1;
+ buffer->triangle_array [buffer->coord_comp_count++] = z1;
+ buffer->triangle_array [buffer->coord_comp_count++] = x2;
+ buffer->triangle_array [buffer->coord_comp_count++] = y2;
+ buffer->triangle_array [buffer->coord_comp_count++] = z2;
+ buffer->triangle_array [buffer->coord_comp_count++] = x3;
+ buffer->triangle_array [buffer->coord_comp_count++] = y3;
+ buffer->triangle_array [buffer->coord_comp_count++] = z3;
+ buffer->triangle_count++;
+}
+
+static inline void
+hidgl_add_triangle (triangle_buffer *buffer,
+ GLfloat x1, GLfloat y1,
+ GLfloat x2, GLfloat y2,
+ GLfloat x3, GLfloat y3)
+{
+ hidgl_add_triangle_3D (buffer, x1, y1, global_depth,
+ x2, y2, global_depth,
+ x3, y3, global_depth);
+}
+
+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_fill_rect (int x1, int y1, int x2, int y2);
+
+
+#endif /* __HIDGL_INCLUDED__ */
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
new file mode 100644
index 0000000..0923110
--- /dev/null
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -0,0 +1,1159 @@
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "crosshair.h"
+#include "clip.h"
+#include "../hidint.h"
+#include "gui.h"
+#include "gui-pinout-preview.h"
+
+/* The Linux OpenGL ABI 1.0 spec requires that we define
+ * GL_GLEXT_PROTOTYPES before including gl.h or glx.h for extensions
+ * in order to get prototypes:
+ * http://www.opengl.org/registry/ABI/
+ */
+#define GL_GLEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <gtk/gtkgl.h>
+#include "hid/common/hidgl.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+RCSID ("$Id$");
+
+
+extern HID ghid_hid;
+
+static hidGC current_gc = NULL;
+
+/* Sets gport->u_gc to the "right" GC to use (wrt mask or window)
+*/
+#define USE_GC(gc) if (!use_gc(gc)) return
+
+static int cur_mask = -1;
+
+typedef struct render_priv {
+ GdkGLConfig *glconfig;
+ bool trans_lines;
+ bool in_context;
+} render_priv;
+
+
+typedef struct hid_gc_struct
+{
+ HID *me_pointer;
+
+ gchar *colorname;
+ gint width;
+ gint cap, join;
+ gchar xor;
+ gchar erase;
+}
+hid_gc_struct;
+
+
+int
+ghid_set_layer (const char *name, int group, int empty)
+{
+ render_priv *priv = gport->render_priv;
+ int idx = group;
+ if (idx >= 0 && idx < max_group)
+ {
+ int n = PCB->LayerGroups.Number[group];
+ for (idx = 0; idx < n-1; idx ++)
+ {
+ int ni = PCB->LayerGroups.Entries[group][idx];
+ if (ni >= 0 && ni < max_copper_layer + 2
+ && PCB->Data->Layer[ni].On)
+ break;
+ }
+ idx = PCB->LayerGroups.Entries[group][idx];
+ }
+
+ if (idx >= 0 && idx < max_copper_layer + 2)
+ {
+ priv->trans_lines = false;
+ return PCB->Data->Layer[idx].On;
+ }
+ if (idx < 0)
+ {
+ switch (SL_TYPE (idx))
+ {
+ case SL_INVISIBLE:
+ return PCB->InvisibleObjectsOn;
+ case SL_MASK:
+ if (SL_MYSIDE (idx))
+ return TEST_FLAG (SHOWMASKFLAG, PCB);
+ return 0;
+ case SL_SILK:
+ priv->trans_lines = false;
+ if (SL_MYSIDE (idx))
+ return PCB->ElementOn;
+ return 0;
+ case SL_ASSY:
+ return 0;
+ case SL_PDRILL:
+ case SL_UDRILL:
+ return 1;
+ case SL_RATS:
+ if (PCB->RatOn)
+ priv->trans_lines = true;
+ return PCB->RatOn;
+ }
+ }
+ return 0;
+}
+
+void
+ghid_destroy_gc (hidGC gc)
+{
+ g_free (gc);
+}
+
+hidGC
+ghid_make_gc (void)
+{
+ hidGC rv;
+
+ rv = g_new0 (hid_gc_struct, 1);
+ rv->me_pointer = &ghid_hid;
+ rv->colorname = Settings.BackgroundColor;
+ return rv;
+}
+
+static void
+ghid_draw_grid (BoxTypePtr drawn_area)
+{
+ if (Vz (PCB->Grid) < MIN_GRID_DISTANCE)
+ return;
+
+ if (gdk_color_parse (Settings.GridColor, &gport->grid_color))
+ {
+ gport->grid_color.red ^= gport->bg_color.red;
+ gport->grid_color.green ^= gport->bg_color.green;
+ gport->grid_color.blue ^= gport->bg_color.blue;
+ }
+
+ glEnable (GL_COLOR_LOGIC_OP);
+ glLogicOp (GL_XOR);
+
+ glColor3f (gport->grid_color.red / 65535.,
+ gport->grid_color.green / 65535.,
+ gport->grid_color.blue / 65535.);
+
+ hidgl_draw_grid (drawn_area);
+
+ glDisable (GL_COLOR_LOGIC_OP);
+}
+
+static void
+ghid_draw_bg_image (void)
+{
+ static GLuint texture_handle = 0;
+
+ if (!ghidgui->bg_pixbuf)
+ return;
+
+ if (texture_handle == 0)
+ {
+ int width = gdk_pixbuf_get_width (ghidgui->bg_pixbuf);
+ int height = gdk_pixbuf_get_height (ghidgui->bg_pixbuf);
+ int rowstride = gdk_pixbuf_get_rowstride (ghidgui->bg_pixbuf);
+ int bits_per_sample = gdk_pixbuf_get_bits_per_sample (ghidgui->bg_pixbuf);
+ int n_channels = gdk_pixbuf_get_n_channels (ghidgui->bg_pixbuf);
+ unsigned char *pixels = gdk_pixbuf_get_pixels (ghidgui->bg_pixbuf);
+
+ g_warn_if_fail (bits_per_sample == 8);
+ g_warn_if_fail (rowstride == width * n_channels);
+
+ glGenTextures (1, &texture_handle);
+ glBindTexture (GL_TEXTURE_2D, texture_handle);
+
+ /* XXX: We should proabbly determine what the maxmimum texture supported is,
+ * and if our image is larger, shrink it down using GDK pixbuf routines
+ * rather than having it fail below.
+ */
+
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
+ (n_channels == 4) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ }
+
+ glBindTexture (GL_TEXTURE_2D, texture_handle);
+
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glEnable (GL_TEXTURE_2D);
+
+ /* Render a quad with the background as a texture */
+
+ glBegin (GL_QUADS);
+ glTexCoord2d (0., 0.);
+ glVertex3i (0, 0, 0);
+ glTexCoord2d (1., 0.);
+ glVertex3i (PCB->MaxWidth, 0, 0);
+ glTexCoord2d (1., 1.);
+ glVertex3i (PCB->MaxWidth, PCB->MaxHeight, 0);
+ glTexCoord2d (0., 1.);
+ glVertex3i (0, PCB->MaxHeight, 0);
+ glEnd ();
+
+ glDisable (GL_TEXTURE_2D);
+}
+
+void
+ghid_use_mask (int use_it)
+{
+ /* NOTE: We are assuming the stencil buffer bit plane is clear at the start
+ * of a masked drawing operation.
+ *
+ * For our current usage we know that it will start clean at the
+ * beginning of the frame - and that the mask is only used at most
+ * once during rendering (for the solder-mask layer).
+ */
+
+ if (use_it == cur_mask)
+ return;
+
+ hidgl_flush_triangles (&buffer);
+
+ switch (use_it)
+ {
+ case HID_MASK_BEFORE:
+ /* The HID asks not to receive this mask type, so warn if we get it */
+ g_return_if_reached ();
+
+ case HID_MASK_CLEAR:
+ /* Write '1' to the stencil buffer where the solder-mask should not be drawn. */
+ glColorMask (0, 0, 0, 0); /* Disable writting in color buffer */
+ glEnable (GL_STENCIL_TEST); /* Enable Stencil test */
+ glStencilFunc (GL_ALWAYS, 1, 1); /* Test always passes, value written 1 */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); /* Stencil pass => replace stencil value (with 1) */
+ break;
+
+ case HID_MASK_AFTER:
+ /* Drawing operations as masked to areas where the stencil buffer is '0' */
+ glColorMask (1, 1, 1, 1); /* Enable drawing of r, g, b & a */
+ glStencilFunc (GL_EQUAL, 0, 1); /* Draw only where stencil buffer is 1 */
+ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); /* Stencil buffer read only */
+ break;
+
+ case HID_MASK_OFF:
+ /* Disable stenciling */
+ glDisable (GL_STENCIL_TEST);
+ break;
+ }
+ cur_mask = use_it;
+}
+
+
+ /* Config helper functions for when the user changes color preferences.
+ | set_special colors used in the gtkhid.
+ */
+static void
+set_special_grid_color (void)
+{
+ if (!gport->colormap)
+ return;
+ gport->grid_color.red ^= gport->bg_color.red;
+ gport->grid_color.green ^= gport->bg_color.green;
+ gport->grid_color.blue ^= gport->bg_color.blue;
+}
+
+void
+ghid_set_special_colors (HID_Attribute * ha)
+{
+ if (!ha->name || !ha->value)
+ return;
+ if (!strcmp (ha->name, "background-color"))
+ {
+ ghid_map_color_string (*(char **) ha->value, &gport->bg_color);
+ set_special_grid_color ();
+ }
+ else if (!strcmp (ha->name, "off-limit-color"))
+ {
+ ghid_map_color_string (*(char **) ha->value, &gport->offlimits_color);
+ }
+ else if (!strcmp (ha->name, "grid-color"))
+ {
+ ghid_map_color_string (*(char **) ha->value, &gport->grid_color);
+ set_special_grid_color ();
+ }
+}
+
+typedef struct
+{
+ int color_set;
+ GdkColor color;
+ int xor_set;
+ GdkColor xor_color;
+ double red;
+ double green;
+ double blue;
+} ColorCache;
+
+void
+ghid_set_color (hidGC gc, const char *name)
+{
+ render_priv *priv = gport->render_priv;
+ static void *cache = NULL;
+ static char *old_name = NULL;
+ hidval cval;
+ ColorCache *cc;
+ double alpha_mult = 1.0;
+ double r, g, b, a;
+ a = 1.0;
+
+ current_gc = gc;
+
+ if (old_name != NULL)
+ {
+ if (strcmp (name, old_name) == 0)
+ return;
+ free (old_name);
+ }
+
+ old_name = strdup (name);
+
+ if (name == NULL)
+ {
+ fprintf (stderr, "%s(): name = NULL, setting to magenta\n",
+ __FUNCTION__);
+ name = "magenta";
+ }
+
+ gc->colorname = (char *) name;
+
+ if (gport->colormap == NULL)
+ gport->colormap = gtk_widget_get_colormap (gport->top_window);
+ if (strcmp (name, "erase") == 0)
+ {
+ gc->erase = 1;
+ r = gport->bg_color.red / 65535.;
+ g = gport->bg_color.green / 65535.;
+ b = gport->bg_color.blue / 65535.;
+ }
+ else if (strcmp (name, "drill") == 0)
+ {
+ gc->erase = 0;
+ alpha_mult = 0.85;
+ r = gport->offlimits_color.red / 65535.;
+ g = gport->offlimits_color.green / 65535.;
+ b = gport->offlimits_color.blue / 65535.;
+ }
+ else
+ {
+ alpha_mult = 0.7;
+ if (hid_cache_color (0, name, &cval, &cache))
+ cc = (ColorCache *) cval.ptr;
+ else
+ {
+ cc = (ColorCache *) malloc (sizeof (ColorCache));
+ memset (cc, 0, sizeof (*cc));
+ cval.ptr = cc;
+ hid_cache_color (1, name, &cval, &cache);
+ }
+
+ if (!cc->color_set)
+ {
+ if (gdk_color_parse (name, &cc->color))
+ gdk_color_alloc (gport->colormap, &cc->color);
+ else
+ gdk_color_white (gport->colormap, &cc->color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
+ cc->color_set = 1;
+ }
+ if (gc->xor)
+ {
+ if (!cc->xor_set)
+ {
+ cc->xor_color.red = cc->color.red ^ gport->bg_color.red;
+ cc->xor_color.green = cc->color.green ^ gport->bg_color.green;
+ cc->xor_color.blue = cc->color.blue ^ gport->bg_color.blue;
+ gdk_color_alloc (gport->colormap, &cc->xor_color);
+ cc->red = cc->color.red / 65535.;
+ cc->green = cc->color.green / 65535.;
+ cc->blue = cc->color.blue / 65535.;
+ cc->xor_set = 1;
+ }
+ }
+ r = cc->red;
+ g = cc->green;
+ b = cc->blue;
+
+ gc->erase = 0;
+ }
+ if (1) {
+ double maxi, mult;
+ if (priv->trans_lines)
+ a = a * alpha_mult;
+ maxi = r;
+ if (g > maxi) maxi = g;
+ if (b > maxi) maxi = b;
+ mult = MIN (1 / alpha_mult, 1 / maxi);
+#if 1
+ r = r * mult;
+ g = g * mult;
+ b = b * mult;
+#endif
+ }
+
+ if(!priv->in_context)
+ return;
+
+ hidgl_flush_triangles (&buffer);
+ glColor4d (r, g, b, a);
+}
+
+void
+ghid_set_line_cap (hidGC gc, EndCapStyle style)
+{
+ gc->cap = style;
+}
+
+void
+ghid_set_line_width (hidGC gc, int width)
+{
+ gc->width = width;
+}
+
+
+void
+ghid_set_draw_xor (hidGC gc, int xor)
+{
+ /* NOT IMPLEMENTED */
+
+ /* Only presently called when setting up a crosshair GC.
+ * We manage our own drawing model for that anyway. */
+}
+
+void
+ghid_set_draw_faded (hidGC gc, int faded)
+{
+ printf ("ghid_set_draw_faded(%p,%d) -- not implemented\n", gc, faded);
+}
+
+void
+ghid_set_line_cap_angle (hidGC gc, int x1, int y1, int x2, int y2)
+{
+ printf ("ghid_set_line_cap_angle() -- not implemented\n");
+}
+
+static void
+ghid_invalidate_current_gc (void)
+{
+ current_gc = NULL;
+}
+
+static int
+use_gc (hidGC gc)
+{
+ if (gc->me_pointer != &ghid_hid)
+ {
+ fprintf (stderr, "Fatal: GC from another HID passed to GTK HID\n");
+ abort ();
+ }
+
+ if (current_gc == gc)
+ return 1;
+
+ current_gc = gc;
+
+ ghid_set_color (gc, gc->colorname);
+ return 1;
+}
+
+void
+ghid_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
+{
+ USE_GC (gc);
+
+ hidgl_draw_line (gc->cap, gc->width, x1, y1, x2, y2, gport->zoom);
+}
+
+void
+ghid_draw_arc (hidGC gc, int cx, int cy, int xradius, int yradius,
+ int start_angle, int delta_angle)
+{
+ USE_GC (gc);
+
+ hidgl_draw_arc (gc->width, cx, cy, xradius, yradius,
+ start_angle, delta_angle, gport->zoom);
+}
+
+void
+ghid_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
+{
+ USE_GC (gc);
+
+ hidgl_draw_rect (x1, y1, x2, y2);
+}
+
+
+void
+ghid_fill_circle (hidGC gc, int cx, int cy, int radius)
+{
+ USE_GC (gc);
+
+ hidgl_fill_circle (cx, cy, radius, gport->zoom);
+}
+
+
+void
+ghid_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
+{
+ USE_GC (gc);
+
+ hidgl_fill_polygon (n_coords, x, y);
+}
+
+void
+ghid_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+{
+ USE_GC (gc);
+
+ hidgl_fill_rect (x1, y1, x2, y2);
+}
+
+void
+ghid_invalidate_lr (int left, int right, int top, int bottom)
+{
+ ghid_invalidate_all ();
+}
+
+void
+ghid_invalidate_all ()
+{
+ ghid_draw_area_update (gport, NULL);
+}
+
+void
+ghid_notify_crosshair_change (bool changes_complete)
+{
+ /* We sometimes get called before the GUI is up */
+ if (gport->drawing_area == NULL)
+ return;
+
+ /* FIXME: We could just invalidate the bounds of the crosshair attached objects? */
+ ghid_invalidate_all ();
+}
+
+void
+ghid_notify_mark_change (bool changes_complete)
+{
+ /* We sometimes get called before the GUI is up */
+ if (gport->drawing_area == NULL)
+ return;
+
+ /* FIXME: We could just invalidate the bounds of the mark? */
+ ghid_invalidate_all ();
+}
+
+static void
+draw_right_cross (gint x, gint y)
+{
+ glVertex2i (x, 0);
+ glVertex2i (x, gport->height);
+ glVertex2i (0, y);
+ glVertex2i (gport->width, y);
+}
+
+static void
+draw_slanted_cross (gint x, gint y)
+{
+ gint x0, y0, x1, y1;
+
+ x0 = x + (gport->height - y);
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x - y;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + (gport->width - x);
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - x;
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+
+ x0 = x - (gport->height - y);
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x + y;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + x;
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - (gport->width - x);
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+}
+
+static void
+draw_dozen_cross (gint x, gint y)
+{
+ gint x0, y0, x1, y1;
+ gdouble tan60 = sqrt (3);
+
+ x0 = x + (gport->height - y) / tan60;
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x - y / tan60;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + (gport->width - x) * tan60;
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - x * tan60;
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+
+ x0 = x + (gport->height - y) * tan60;
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x - y * tan60;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + (gport->width - x) / tan60;
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - x / tan60;
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+
+ x0 = x - (gport->height - y) / tan60;
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x + y / tan60;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + x * tan60;
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - (gport->width - x) * tan60;
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+
+ x0 = x - (gport->height - y) * tan60;
+ x0 = MAX(0, MIN (x0, gport->width));
+ x1 = x + y * tan60;
+ x1 = MAX(0, MIN (x1, gport->width));
+ y0 = y + x / tan60;
+ y0 = MAX(0, MIN (y0, gport->height));
+ y1 = y - (gport->width - x) / tan60;
+ y1 = MAX(0, MIN (y1, gport->height));
+ glVertex2i (x0, y0);
+ glVertex2i (x1, y1);
+}
+
+static void
+draw_crosshair (gint x, gint y)
+{
+ static enum crosshair_shape prev = Basic_Crosshair_Shape;
+
+ draw_right_cross (x, y);
+ if (prev == Union_Jack_Crosshair_Shape)
+ draw_slanted_cross (x, y);
+ if (prev == Dozen_Crosshair_Shape)
+ draw_dozen_cross (x, y);
+ prev = Crosshair.shape;
+}
+
+#define VCW 16
+#define VCD 8
+
+void
+ghid_show_crosshair (gboolean paint_new_location)
+{
+ gint x, y;
+ gboolean draw_markers;
+ static int done_once = 0;
+ static GdkColor cross_color;
+
+ if (!paint_new_location)
+ return;
+
+ if (!done_once)
+ {
+ done_once = 1;
+ /* FIXME: when CrossColor changed from config */
+ ghid_map_color_string (Settings.CrossColor, &cross_color);
+ }
+ x = DRAW_X (gport->x_crosshair);
+ y = DRAW_Y (gport->y_crosshair);
+
+ glEnable (GL_COLOR_LOGIC_OP);
+ glLogicOp (GL_XOR);
+
+ hidgl_flush_triangles (&buffer);
+
+ glColor3f (cross_color.red / 65535.,
+ cross_color.green / 65535.,
+ cross_color.blue / 65535.);
+
+ if (x >= 0 && paint_new_location)
+ {
+ glBegin (GL_LINES);
+ draw_crosshair (x, y);
+ glEnd ();
+ }
+
+ draw_markers = ghidgui->auto_pan_on && have_crosshair_attachments ();
+ if (x >= 0 && paint_new_location && draw_markers)
+ {
+ glBegin (GL_QUADS);
+ glVertex2i (0, y - VCD);
+ glVertex2i (0, y - VCD + VCW);
+ glVertex2i (VCD, y - VCD + VCW);
+ glVertex2i (VCD, y - VCD);
+ glVertex2i (gport->width, y - VCD);
+ glVertex2i (gport->width, y - VCD + VCW);
+ glVertex2i (gport->width - VCD, y - VCD + VCW);
+ glVertex2i (gport->width - VCD, y - VCD);
+ glVertex2i (x - VCD, 0);
+ glVertex2i (x - VCD, VCD);
+ glVertex2i (x - VCD + VCW, VCD);
+ glVertex2i (x - VCD + VCW, 0);
+ glVertex2i (x - VCD, gport->height - VCD);
+ glVertex2i (x - VCD, gport->height);
+ glVertex2i (x - VCD + VCW, gport->height);
+ glVertex2i (x - VCD + VCW, gport->height - VCD);
+ glEnd ();
+ }
+
+ glDisable (GL_COLOR_LOGIC_OP);
+}
+
+void
+ghid_init_renderer (int *argc, char ***argv, GHidPort *port)
+{
+ render_priv *priv;
+
+ port->render_priv = priv = g_new0 (render_priv, 1);
+
+ gtk_gl_init(argc, argv);
+
+ /* setup GL-context */
+ priv->glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGBA |
+ GDK_GL_MODE_STENCIL |
+ GDK_GL_MODE_DOUBLE);
+ if (!priv->glconfig)
+ {
+ printf ("Could not setup GL-context!\n");
+ return; /* Should we abort? */
+ }
+}
+
+void
+ghid_init_drawing_widget (GtkWidget *widget, GHidPort *port)
+{
+ render_priv *priv = port->render_priv;
+
+ gtk_widget_set_gl_capability (widget,
+ priv->glconfig,
+ NULL,
+ TRUE,
+ GDK_GL_RGBA_TYPE);
+}
+
+void
+ghid_drawing_area_configure_hook (GHidPort *port)
+{
+}
+
+gboolean
+ghid_start_drawing (GHidPort *port)
+{
+ GtkWidget *widget = port->drawing_area;
+ GdkGLContext *pGlContext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (widget);
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
+ return FALSE;
+
+ port->render_priv->in_context = true;
+
+ return TRUE;
+}
+
+void
+ghid_end_drawing (GHidPort *port)
+{
+ GtkWidget *widget = port->drawing_area;
+ GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (widget);
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+
+ port->render_priv->in_context = false;
+
+ /* end drawing to current GL-context */
+ gdk_gl_drawable_gl_end (pGlDrawable);
+}
+
+void
+ghid_screen_update (void)
+{
+}
+
+#define Z_NEAR 3.0
+gboolean
+ghid_drawing_area_expose_cb (GtkWidget *widget,
+ GdkEventExpose *ev,
+ GHidPort *port)
+{
+ BoxType region;
+
+ ghid_start_drawing (port);
+
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport (0, 0, widget->allocation.width, widget->allocation.height);
+
+ glEnable (GL_SCISSOR_TEST);
+ glScissor (ev->area.x,
+ widget->allocation.height - ev->area.height - ev->area.y,
+ ev->area.width, ev->area.height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, widget->allocation.width, widget->allocation.height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClearColor (port->offlimits_color.red / 65535.,
+ port->offlimits_color.green / 65535.,
+ port->offlimits_color.blue / 65535.,
+ 1.);
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ region.X1 = MIN (Px (ev->area.x), Px (ev->area.x + ev->area.width + 1));
+ region.X2 = MAX (Px (ev->area.x), Px (ev->area.x + ev->area.width + 1));
+ region.Y1 = MIN (Py (ev->area.y), Py (ev->area.y + ev->area.height + 1));
+ region.Y2 = MAX (Py (ev->area.y), Py (ev->area.y + ev->area.height + 1));
+
+ glColor3f (port->bg_color.red / 65535.,
+ port->bg_color.green / 65535.,
+ port->bg_color.blue / 65535.);
+
+ glPushMatrix ();
+ glScalef ((ghid_flip_x ? -1. : 1.) / port->zoom,
+ (ghid_flip_y ? -1. : 1.) / port->zoom,
+ (ghid_flip_x == ghid_flip_y) ? 1. : -1.);
+ glTranslatef (ghid_flip_x ? port->view_x0 - PCB->MaxWidth :
+ -port->view_x0,
+ ghid_flip_y ? port->view_y0 - PCB->MaxHeight :
+ -port->view_y0, 0);
+
+ glBegin (GL_QUADS);
+ glVertex3i (0, 0, 0);
+ glVertex3i (PCB->MaxWidth, 0, 0);
+ glVertex3i (PCB->MaxWidth, PCB->MaxHeight, 0);
+ glVertex3i (0, PCB->MaxHeight, 0);
+ glEnd ();
+
+ ghid_draw_bg_image ();
+
+ hidgl_init_triangle_array (&buffer);
+ ghid_invalidate_current_gc ();
+ hid_expose_callback (&ghid_hid, ®ion, 0);
+ hidgl_flush_triangles (&buffer);
+
+ ghid_draw_grid (®ion);
+
+ ghid_invalidate_current_gc ();
+
+ DrawAttached ();
+ DrawMark ();
+ hidgl_flush_triangles (&buffer);
+ glPopMatrix ();
+
+ ghid_show_crosshair (TRUE);
+
+ hidgl_flush_triangles (&buffer);
+
+ ghid_end_drawing (port);
+
+ return FALSE;
+}
+
+gboolean
+ghid_pinout_preview_expose (GtkWidget *widget,
+ GdkEventExpose *ev)
+{
+ GdkGLContext* pGlContext = gtk_widget_get_gl_context (widget);
+ GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (widget);
+ GhidPinoutPreview *pinout = GHID_PINOUT_PREVIEW (widget);
+ double save_zoom;
+ int da_w, da_h;
+ int save_left, save_top;
+ int save_width, save_height;
+ int save_view_width, save_view_height;
+ double xz, yz;
+
+ save_zoom = gport->zoom;
+ save_width = gport->width;
+ save_height = gport->height;
+ save_left = gport->view_x0;
+ save_top = gport->view_y0;
+ save_view_width = gport->view_width;
+ save_view_height = gport->view_height;
+
+ /* Setup zoom factor for drawing routines */
+
+ gdk_window_get_geometry (widget->window, 0, 0, &da_w, &da_h, 0);
+ xz = (double) pinout->x_max / da_w;
+ yz = (double) pinout->y_max / da_h;
+ if (xz > yz)
+ gport->zoom = xz;
+ else
+ gport->zoom = yz;
+
+ gport->width = da_w;
+ gport->height = da_h;
+ gport->view_width = da_w * gport->zoom;
+ gport->view_height = da_h * gport->zoom;
+ gport->view_x0 = (pinout->x_max - gport->view_width) / 2;
+ gport->view_y0 = (pinout->y_max - gport->view_height) / 2;
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext)) {
+ return FALSE;
+ }
+ gport->render_priv->in_context = true;
+
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport (0, 0, widget->allocation.width, widget->allocation.height);
+
+ glEnable (GL_SCISSOR_TEST);
+ glScissor (ev->area.x,
+ widget->allocation.height - ev->area.height - ev->area.y,
+ ev->area.width, ev->area.height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, widget->allocation.width, widget->allocation.height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClearColor (gport->bg_color.red / 65535.,
+ gport->bg_color.green / 65535.,
+ gport->bg_color.blue / 65535.,
+ 1.);
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ /* call the drawing routine */
+ hidgl_init_triangle_array (&buffer);
+ ghid_invalidate_current_gc ();
+ glPushMatrix ();
+ glScalef ((ghid_flip_x ? -1. : 1.) / gport->zoom,
+ (ghid_flip_y ? -1. : 1.) / gport->zoom, 1);
+ glTranslatef (ghid_flip_x ? gport->view_x0 - PCB->MaxWidth :
+ -gport->view_x0,
+ ghid_flip_y ? gport->view_y0 - PCB->MaxHeight :
+ -gport->view_y0, 0);
+ hid_expose_callback (&ghid_hid, NULL, &pinout->element);
+ hidgl_flush_triangles (&buffer);
+ glPopMatrix ();
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+
+ /* end drawing to current GL-context */
+ gport->render_priv->in_context = false;
+ gdk_gl_drawable_gl_end (pGlDrawable);
+
+ gport->zoom = save_zoom;
+ gport->width = save_width;
+ gport->height = save_height;
+ gport->view_x0 = save_left;
+ gport->view_y0 = save_top;
+ gport->view_width = save_view_width;
+ gport->view_height = save_view_height;
+
+ return FALSE;
+}
+
+
+GdkPixmap *
+ghid_render_pixmap (int cx, int cy, double zoom, int width, int height, int depth)
+{
+ GdkGLConfig *glconfig;
+ GdkPixmap *pixmap;
+ GdkGLPixmap *glpixmap;
+ GdkGLContext* glcontext;
+ GdkGLDrawable* gldrawable;
+ double save_zoom;
+ int save_left, save_top;
+ int save_width, save_height;
+ int save_view_width, save_view_height;
+ BoxType region;
+
+ save_zoom = gport->zoom;
+ save_width = gport->width;
+ save_height = gport->height;
+ save_left = gport->view_x0;
+ save_top = gport->view_y0;
+ save_view_width = gport->view_width;
+ save_view_height = gport->view_height;
+
+ /* Setup rendering context for drawing routines
+ */
+
+ glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
+ GDK_GL_MODE_STENCIL |
+ GDK_GL_MODE_SINGLE);
+
+ pixmap = gdk_pixmap_new (NULL, width, height, depth);
+ glpixmap = gdk_pixmap_set_gl_capability (pixmap, glconfig, NULL);
+ gldrawable = GDK_GL_DRAWABLE (glpixmap);
+ glcontext = gdk_gl_context_new (gldrawable, NULL, FALSE, GDK_GL_RGBA_TYPE);
+
+ /* Setup zoom factor for drawing routines */
+
+ gport->zoom = zoom;
+ gport->width = width;
+ gport->height = height;
+ gport->view_width = width * gport->zoom;
+ gport->view_height = height * gport->zoom;
+ gport->view_x0 = ghid_flip_x ? PCB->MaxWidth - cx : cx;
+ gport->view_x0 -= gport->view_height / 2;
+ gport->view_y0 = ghid_flip_y ? PCB->MaxHeight - cy : cy;
+ gport->view_y0 -= gport->view_width / 2;
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) {
+ return NULL;
+ }
+ gport->render_priv->in_context = true;
+
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport (0, 0, width, height);
+
+ glEnable (GL_SCISSOR_TEST);
+ glScissor (0, 0, width, height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, width, height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClearColor (gport->bg_color.red / 65535.,
+ gport->bg_color.green / 65535.,
+ gport->bg_color.blue / 65535.,
+ 1.);
+ glClearStencil (0);
+ glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ /* call the drawing routine */
+ hidgl_init_triangle_array (&buffer);
+ ghid_invalidate_current_gc ();
+ glPushMatrix ();
+ glScalef ((ghid_flip_x ? -1. : 1.) / gport->zoom,
+ (ghid_flip_y ? -1. : 1.) / gport->zoom, 1);
+ glTranslatef (ghid_flip_x ? gport->view_x0 - PCB->MaxWidth :
+ -gport->view_x0,
+ ghid_flip_y ? gport->view_y0 - PCB->MaxHeight :
+ -gport->view_y0, 0);
+ region.X1 = MIN(Px(0), Px(gport->width + 1));
+ region.Y1 = MIN(Py(0), Py(gport->height + 1));
+ region.X2 = MAX(Px(0), Px(gport->width + 1));
+ region.Y2 = MAX(Py(0), Py(gport->height + 1));
+ hid_expose_callback (&ghid_hid, ®ion, NULL);
+ hidgl_flush_triangles (&buffer);
+ glPopMatrix ();
+
+ glFlush ();
+
+ /* end drawing to current GL-context */
+ gport->render_priv->in_context = false;
+ gdk_gl_drawable_gl_end (gldrawable);
+
+ gdk_pixmap_unset_gl_capability (pixmap);
+
+ g_object_unref (glconfig);
+ g_object_unref (glcontext);
+
+ gport->zoom = save_zoom;
+ gport->width = save_width;
+ gport->height = save_height;
+ gport->view_x0 = save_left;
+ gport->view_y0 = save_top;
+ gport->view_width = save_view_width;
+ gport->view_height = save_view_height;
+
+ return pixmap;
+}
+
+HID *
+ghid_request_debug_draw (void)
+{
+ GHidPort *port = gport;
+ GtkWidget *widget = port->drawing_area;
+
+ ghid_start_drawing (port);
+
+ glViewport (0, 0, widget->allocation.width, widget->allocation.height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, widget->allocation.width, widget->allocation.height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ hidgl_init_triangle_array (&buffer);
+ ghid_invalidate_current_gc ();
+
+ glPushMatrix ();
+ glScalef ((ghid_flip_x ? -1. : 1.) / port->zoom,
+ (ghid_flip_y ? -1. : 1.) / port->zoom,
+ (ghid_flip_x == ghid_flip_y) ? 1. : -1.);
+ glTranslatef (ghid_flip_x ? port->view_x0 - PCB->MaxWidth :
+ -port->view_x0,
+ ghid_flip_y ? port->view_y0 - PCB->MaxHeight :
+ -port->view_y0, 0);
+
+ return &ghid_hid;
+}
+
+void
+ghid_flush_debug_draw (void)
+{
+ GtkWidget *widget = gport->drawing_area;
+ GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (widget);
+
+ hidgl_flush_triangles (&buffer);
+
+ if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
+ gdk_gl_drawable_swap_buffers (pGlDrawable);
+ else
+ glFlush ();
+}
+
+void
+ghid_finish_debug_draw (void)
+{
+ hidgl_flush_triangles (&buffer);
+ glPopMatrix ();
+
+ ghid_end_drawing (gport);
+}
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index d52d088..7a18906 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -470,7 +470,7 @@ void ghid_logv (const char *fmt, va_list args);
/* gui-pinout-window.c */
void ghid_pinout_window_show (GHidPort * out, ElementTypePtr Element);
-/* gtkhid-gdk.c */
+/* gtkhid-gdk.c AND gtkhid-gl.c */
int ghid_set_layer (const char *name, int group, int empty);
hidGC ghid_make_gc (void);
void ghid_destroy_gc (hidGC);
|
|
From: <gi...@gp...> - 2011-05-03 20:23:13
|
The branch, master has been updated
via 9acdd88e22717510ff5dde277ecbd6f1de60b69d (commit)
from 31b7309764f2e4bd40141038c30f1f38309efb4a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
src/hid/common/flags.c | 2 +-
src/hid/gtk/gtkhid-main.c | 40 +++++++-----------
src/hid/lesstif/main.c | 39 +++++++----------
src/main.c | 2 +-
src/misc.c | 102 +++++++++++++++++++++++++++++++++++----------
src/misc.h | 11 ++++-
src/parse_y.y | 4 +-
7 files changed, 125 insertions(+), 75 deletions(-)
=================
Commit Messages
=================
commit 9acdd88e22717510ff5dde277ecbd6f1de60b69d
Author: Andrew Poelstra <as...@sf...>
Commit: Peter Clifton <pc...@ca...>
Universal use of GetValue
This is a patch to make all numeric code use GetValue, to unify parsing
code and make sure everything uses the same units. Contained is almost
a complete rewrite of GetValue to simplify code that uses funny units.
Reviewed-by: Peter Clifton <pc...@ca...>
When committing the patch from Launchpad, I rebased it to apply with
strcasecmp and strncasecmp changed to strcmp and strncmp, as changed
by commit 31b7309764f2e4bd40141038c30f1f38309efb4a
Affects-bug: lp-772027
:100644 100644 23c7c57... 15e77ad... M src/hid/common/flags.c
:100644 100644 66a279b... fd092c6... M src/hid/gtk/gtkhid-main.c
:100644 100644 3a57ca5... b2c1098... M src/hid/lesstif/main.c
:100644 100644 b147a5c... 0e6852f... M src/main.c
:100644 100644 4f308ed... e505047... M src/misc.c
:100644 100644 cd7eb3d... fb303d6... M src/misc.h
:100644 100644 ad8cb44... 5290b53... M src/parse_y.y
=========
Changes
=========
commit 9acdd88e22717510ff5dde277ecbd6f1de60b69d
Author: Andrew Poelstra <as...@sf...>
Commit: Peter Clifton <pc...@ca...>
Universal use of GetValue
This is a patch to make all numeric code use GetValue, to unify parsing
code and make sure everything uses the same units. Contained is almost
a complete rewrite of GetValue to simplify code that uses funny units.
Reviewed-by: Peter Clifton <pc...@ca...>
When committing the patch from Launchpad, I rebased it to apply with
strcasecmp and strncasecmp changed to strcmp and strncmp, as changed
by commit 31b7309764f2e4bd40141038c30f1f38309efb4a
Affects-bug: lp-772027
diff --git a/src/hid/common/flags.c b/src/hid/common/flags.c
index 23c7c57..15e77ad 100644
--- a/src/hid/common/flags.c
+++ b/src/hid/common/flags.c
@@ -114,7 +114,7 @@ hid_get_flag (const char *name)
}
memcpy (buf, name, cp - name);
buf[cp - name] = 0;
- wv = strtol (cp + 1, 0, 0);
+ wv = GetValue (cp + 1, NULL, NULL);
f = hid_find_flag (buf);
if (!f)
return 0;
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index 66a279b..fd092c6 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -1626,9 +1626,20 @@ The values are percentages of the board size. Thus, a move of
static int
CursorAction(int argc, char **argv, int x, int y)
{
+ UnitList extra_units_x = {
+ { "grid", PCB->Grid, 0 },
+ { "view", gport->view_width, UNIT_PERCENT },
+ { "board", PCB->MaxWidth, UNIT_PERCENT },
+ { "", 0, 0 }
+ };
+ UnitList extra_units_y = {
+ { "grid", PCB->Grid, 0 },
+ { "view", gport->view_height, UNIT_PERCENT },
+ { "board", PCB->MaxHeight, UNIT_PERCENT },
+ { "", 0, 0 }
+ };
int pan_warp = HID_SC_DO_NOTHING;
double dx, dy;
- double xu = 0.0, yu = 0.0;
if (argc != 4)
AFAIL (cursor);
@@ -1640,35 +1651,14 @@ CursorAction(int argc, char **argv, int x, int y)
else
AFAIL (cursor);
- dx = strtod (argv[1], 0);
+ dx = GetValueEx (argv[1], argv[3], NULL, extra_units_x, "");
if (ghid_flip_x)
dx = -dx;
- dy = strtod (argv[2], 0);
+ dy = GetValueEx (argv[2], argv[3], NULL, extra_units_y, "");
if (!ghid_flip_y)
dy = -dy;
- /*
- * xu and yu are the scale factors that we multiply dx and dy by to
- * come up with PCB internal units.
- */
- if (strncmp (argv[3], "mm", 2) == 0)
- xu = yu = MM_TO_COORD(1);
- else if (strncmp (argv[3], "mil", 3) == 0)
- xu = yu = MIL_TO_COORD(1);
- else if (strncmp (argv[3], "grid", 4) == 0)
- xu = yu = PCB->Grid;
- else if (strncmp (argv[3], "view", 4) == 0)
- {
- xu = gport->view_width / 100.0;
- yu = gport->view_height / 100.0;
- }
- else if (strncmp (argv[3], "board", 4) == 0)
- {
- xu = PCB->MaxWidth / 100.0;
- yu = PCB->MaxHeight / 100.0;
- }
-
- EventMoveCrosshair (Crosshair.X+(int)(dx*xu), Crosshair.Y+(int)(dy*yu));
+ EventMoveCrosshair (Crosshair.X + dx, Crosshair.Y + dy);
gui->set_crosshair (Crosshair.X, Crosshair.Y, pan_warp);
return 0;
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 3a57ca5..b2c1098 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -869,8 +869,20 @@ The values are percentages of the board size. Thus, a move of
static int
CursorAction(int argc, char **argv, int x, int y)
{
+ UnitList extra_units_x = {
+ { "grid", PCB->Grid, 0 },
+ { "view", Pz(view_width), UNIT_PERCENT },
+ { "board", PCB->MaxWidth, UNIT_PERCENT },
+ { "", 0, 0 }
+ };
+ UnitList extra_units_y = {
+ { "grid", PCB->Grid, 0 },
+ { "view", Pz(view_height), UNIT_PERCENT },
+ { "board", PCB->MaxHeight, UNIT_PERCENT },
+ { "", 0, 0 }
+ };
int pan_warp = HID_SC_DO_NOTHING;
- double dx, dy, xu, yu;
+ double dx, dy;
if (argc != 4)
AFAIL(cursor);
@@ -882,33 +894,14 @@ CursorAction(int argc, char **argv, int x, int y)
else
AFAIL(cursor);
- dx = strtod (argv[1], 0);
+ dx = GetValueEx (argv[1], argv[3], NULL, extra_units_x, "mil");
if (flip_x)
dx = -dx;
- dy = strtod (argv[2], 0);
+ dy = GetValueEx (argv[2], argv[3], NULL, extra_units_y, "mil");
if (!flip_y)
dy = -dy;
- if (strncmp (argv[3], "mm", 2) == 0)
- xu = yu = MM_TO_COORD(1);
- else if (strncmp (argv[3], "mil", 3) == 0)
- xu = yu = MIL_TO_COORD(1);
- else if (strncmp (argv[3], "grid", 4) == 0)
- xu = yu = PCB->Grid;
- else if (strncmp (argv[3], "view", 4) == 0)
- {
- xu = Pz(view_width) / 100.0;
- yu = Pz(view_height) / 100.0;
- }
- else if (strncmp (argv[3], "board", 4) == 0)
- {
- xu = PCB->MaxWidth / 100.0;
- yu = PCB->MaxHeight / 100.0;
- }
- else
- xu = yu = MIL_TO_COORD(1);
-
- EventMoveCrosshair (Crosshair.X+(int)(dx*xu), Crosshair.Y+(int)(dy*yu));
+ EventMoveCrosshair (Crosshair.X + dx, Crosshair.Y + dy);
gui->set_crosshair (Crosshair.X, Crosshair.Y, pan_warp);
return 0;
diff --git a/src/main.c b/src/main.c
index b147a5c..0e6852f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -622,7 +622,7 @@ REGISTER_ATTRIBUTES (main_attribute_list)
Settings.MaxWidth = MIN (MAX_COORD, MAX (Settings.MaxWidth, MIN_SIZE));
Settings.MaxHeight = MIN (MAX_COORD, MAX (Settings.MaxHeight, MIN_SIZE));
- ParseRouteString (Settings.Routes, &Settings.RouteStyle[0], 1);
+ ParseRouteString (Settings.Routes, &Settings.RouteStyle[0], "cmil");
/*
* Make sure we have settings for some various programs we may wish
diff --git a/src/misc.c b/src/misc.c
index 4f308ed..e505047 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -110,8 +110,29 @@ static struct
double
GetValue (const char *val, const char *units, bool * absolute)
{
+ return GetValueEx(val, units, absolute, NULL, "cmil");
+}
+
+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;
+ bool dummy;
+
+ /* Allow NULL to be passed for absolute */
+ if(absolute == NULL)
+ absolute = &dummy;
/* if the first character is a sign we have to add the
* value to the current one
@@ -138,15 +159,52 @@ GetValue (const char *val, const char *units, bool * absolute)
if (units && *units)
{
- if (strncmp (units, "mm", 2) == 0)
- value = MM_TO_COORD(value);
- else if (strncmp (units, "cm", 2) == 0)
- value = 10 * MM_TO_COORD(value);
- else if (strncmp (units, "mil", 3) == 0)
- value = MIL_TO_COORD(value);
- else if (strncmp (units, "in", 3) == 0)
- value = INCH_TO_COORD(value);
+ int i;
+ for (i = 0; *default_units[i].suffix; ++i)
+ {
+ 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;
+ }
+ }
+ if (extra_units)
+ {
+ for (i = 0; *extra_units[i].suffix; ++i)
+ {
+ if (strncmp (units, extra_units[i].suffix, strlen(extra_units[i].suffix)) == 0)
+ {
+ value *= extra_units[i].scale;
+ if (extra_units[i].flags & UNIT_PERCENT)
+ value /= 100.0;
+ scaled = 1;
+ }
+ }
+ }
+ }
+ /* Apply default unit */
+ 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;
+ }
+ if (extra_units)
+ for (i = 0; *extra_units[i].suffix; ++i)
+ if (strcmp (extra_units[i].suffix, default_unit) == 0)
+ {
+ value *= extra_units[i].scale;
+ if (extra_units[i].flags & UNIT_PERCENT)
+ value /= 100.0;
+ }
}
+
return value;
}
@@ -785,12 +843,16 @@ SetFontInfo (FontTypePtr Ptr)
Ptr->DefaultSymbol.Y2 = Ptr->DefaultSymbol.Y1 + Ptr->MaxHeight;
}
-static void
-GetNum (char **s, BDimension * num)
+static BDimension
+GetNum (char **s, const char *default_unit)
{
- *num = atoi (*s);
- while (isdigit ((int) **s))
- (*s)++;
+ BDimension ret_val;
+ /* Read value */
+ ret_val = GetValueEx(*s, NULL, NULL, NULL, default_unit);
+ /* Advance pointer */
+ while(isalnum(**s) || **s == '.')
+ (*s)++;
+ return ret_val;
}
@@ -800,7 +862,7 @@ GetNum (char **s, BDimension * num)
* e.g. Signal,20,40,20,10:Power,40,60,28,10:...
*/
int
-ParseRouteString (char *s, RouteStyleTypePtr routeStyle, int scale)
+ParseRouteString (char *s, RouteStyleTypePtr routeStyle, const char *default_unit)
{
int i, style;
char Name[256];
@@ -816,8 +878,7 @@ ParseRouteString (char *s, RouteStyleTypePtr routeStyle, int scale)
routeStyle->Name = strdup (Name);
if (!isdigit ((int) *++s))
goto error;
- GetNum (&s, &routeStyle->Thick);
- routeStyle->Thick *= scale;
+ routeStyle->Thick = GetNum (&s, default_unit);
while (*s && isspace ((int) *s))
s++;
if (*s++ != ',')
@@ -826,8 +887,7 @@ ParseRouteString (char *s, RouteStyleTypePtr routeStyle, int scale)
s++;
if (!isdigit ((int) *s))
goto error;
- GetNum (&s, &routeStyle->Diameter);
- routeStyle->Diameter *= scale;
+ routeStyle->Diameter = GetNum (&s, default_unit);
while (*s && isspace ((int) *s))
s++;
if (*s++ != ',')
@@ -836,8 +896,7 @@ ParseRouteString (char *s, RouteStyleTypePtr routeStyle, int scale)
s++;
if (!isdigit ((int) *s))
goto error;
- GetNum (&s, &routeStyle->Hole);
- routeStyle->Hole *= scale;
+ routeStyle->Hole = GetNum (&s, default_unit);
/* for backwards-compatibility, we use a 10-mil default
* for styles which omit the keepaway specification. */
if (*s != ',')
@@ -849,8 +908,7 @@ ParseRouteString (char *s, RouteStyleTypePtr routeStyle, int scale)
s++;
if (!isdigit ((int) *s))
goto error;
- GetNum (&s, &routeStyle->Keepaway);
- routeStyle->Keepaway *= scale;
+ routeStyle->Keepaway = GetNum (&s, default_unit);
while (*s && isspace ((int) *s))
s++;
}
diff --git a/src/misc.h b/src/misc.h
index cd7eb3d..fb303d6 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -35,6 +35,14 @@
#include "global.h"
#include "mymem.h"
+enum unitflags { UNIT_PERCENT = 1 };
+
+typedef struct {
+ const char *suffix;
+ double scale;
+ enum unitflags flags;
+} UnitList[];
+
void r_delete_element (DataTypePtr, ElementTypePtr);
void SetLineBoundingBox (LineTypePtr);
void SetArcBoundingBox (ArcTypePtr);
@@ -52,7 +60,7 @@ BoxTypePtr GetDataBoundingBox (DataTypePtr);
void CenterDisplay (LocationType, LocationType, bool);
void SetFontInfo (FontTypePtr);
int ParseGroupString (char *, LayerGroupTypePtr, int /* LayerN */);
-int ParseRouteString (char *, RouteStyleTypePtr, int);
+int ParseRouteString (char *, RouteStyleTypePtr, const char *);
void QuitApplication (void);
char *EvaluateFilename (char *, char *, char *, char *);
char *ExpandFilename (char *, char *);
@@ -79,6 +87,7 @@ void ChangeArcAngles (LayerTypePtr, ArcTypePtr, long int, long int);
char *UniqueElementName (DataTypePtr, char *);
void AttachForCopy (LocationType, LocationType);
double GetValue (const char *, const char *, bool *);
+double GetValueEx (const char *, const char *, bool *, UnitList, const char *);
int FileExists (const char *);
char *Concat (const char *, ...); /* end with NULL */
diff --git a/src/parse_y.y b/src/parse_y.y
index ad8cb44..5290b53 100644
--- a/src/parse_y.y
+++ b/src/parse_y.y
@@ -647,7 +647,7 @@ is split across lines only to make it readable.
pcbstyles
: T_STYLES '(' STRING ')'
{
- if (ParseRouteString($3, &yyPCB->RouteStyle[0], 100))
+ if (ParseRouteString($3, &yyPCB->RouteStyle[0], "mil"))
{
Message("illegal route-style string\n");
YYABORT;
@@ -655,7 +655,7 @@ pcbstyles
}
| T_STYLES '[' STRING ']'
{
- if (ParseRouteString($3, &yyPCB->RouteStyle[0], 1))
+ if (ParseRouteString($3, &yyPCB->RouteStyle[0], "cmil"))
{
Message("illegal route-style string\n");
YYABORT;
|