[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: gaf.git: branch: master updated (1.6.1-20100214-124-g923116b)
The branch, master has been updated
via 923116bc968ff32ed2c997afa596af59ce9752ce (commit)
via 2c445565d558f079e54f2508b35f734c58abab32 (commit)
via 83530e16e28ebba72d7dc1f509d0005ea30c26f2 (commit)
from 3b76382b7624bd6f22c6e96353185d41053f5e15 (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
=========
gschem/src/o_net.c | 6 ++-
libgeda/include/libgeda/prototype.h | 3 +-
libgeda/include/prototype_priv.h | 2 +-
libgeda/src/g_rc.c | 87 +++++++++++++++++++++++++++-------
libgeda/src/o_box_basic.c | 28 +++++++++++
libgeda/src/s_page.c | 4 +-
libgeda/src/s_tile.c | 12 ++---
7 files changed, 111 insertions(+), 31 deletions(-)
=================
Commit Messages
=================
commit 923116bc968ff32ed2c997afa596af59ce9752ce
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Add PAGE argument to tile functions.
With this patch, the tile system no longer uses TOPLEVEL.page_current
anywhere.
:100644 100644 3a03118... 0ef1166... M gschem/src/o_net.c
:100644 100644 7b0f624... d177a61... M libgeda/include/libgeda/prototype.h
:100644 100644 9f6df1d... f02e9db... M libgeda/include/prototype_priv.h
:100644 100644 aa687d5... 7049e61... M libgeda/src/s_page.c
:100644 100644 b99f47c... ce49af5... M libgeda/src/s_tile.c
commit 2c445565d558f079e54f2508b35f734c58abab32
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Add o_box_modify_all().
o_box_modify() allows one corner of a box to be moved. Unfortunately,
it swaps the internal coordinates of the BOX structure around in a way
that could potentially cause unexpected behaviour. For instance,
suppose you wish to modify a box as shown below:
^ ^
| |
4| 4| +-----+
| | | |
3| 3| | |
| | | |
2| +--+ 2| +-----+
| | | |
1| | | 1|
| | | |
0| +--+ 0|
| |
+---------------> +--------------->
0 1 2 3 4 0 1 2 3 4
(A) Original box (B) Desired box
Calling o_box_modify() as follows will not work as expected:
o_box_modify (toplevel, box, 2, 4, BOX_UPPER_LEFT);
o_box_modify (toplevel, box, 4, 2, BOX_LOWER_RIGHT);
It will instead result in the transformations below:
^ ^
| |
4| +--+ 4| +--------+
| | | | | |
3| | | 3| | |
| | | | | |
2| | | 2| +--------+
| | | |
1| | | 1|
| | | |
0| +--+ 0|
| |
+---------------> +--------------->
0 1 2 3 4 0 1 2 3 4
(C) After first call (D) After second call
This is due to the fact o_box_modify() behaves as though the corner
specified by the whichone argument had been dragged.
This patch adds the o_box_modify_all() function, which allows all four
corners of the box to be modified at once, avoiding the problems
inherent in repeated o_box_modify() calls.
:100644 100644 1b60f7c... 7b0f624... M libgeda/include/libgeda/prototype.h
:100644 100644 0556d79... c99ccde... M libgeda/src/o_box_basic.c
commit 83530e16e28ebba72d7dc1f509d0005ea30c26f2
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Remove uses of deprecated SCM_STRING_CHARS.
:100644 100644 d901128... f40156e... M libgeda/src/g_rc.c
=========
Changes
=========
commit 923116bc968ff32ed2c997afa596af59ce9752ce
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Add PAGE argument to tile functions.
With this patch, the tile system no longer uses TOPLEVEL.page_current
anywhere.
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 3a03118..0ef1166 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -195,7 +195,8 @@ void o_net_guess_direction(GSCHEM_TOPLEVEL *w_current,
const int bus_rules[] = {90, 0, 40};
const int net_rules[] = {80, 30, 0};
- objectlists = s_tile_get_objectlists(toplevel, wx, wy, wx, wy);
+ objectlists = s_tile_get_objectlists(toplevel, toplevel->page_current,
+ wx, wy, wx, wy);
for (iter1 = objectlists; iter1 != NULL; iter1 = g_list_next(iter1)) {
for (iter2 = (GList*) iter1->data; iter2 != NULL; iter2 = g_list_next(iter2)) {
@@ -325,7 +326,8 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
y1 = w_y - w_magnetic_reach;
x2 = w_x + w_magnetic_reach;
y2 = w_y + w_magnetic_reach;
- objectlists = s_tile_get_objectlists(toplevel, x1, y1, x2, y2);
+ objectlists = s_tile_get_objectlists(toplevel, toplevel->page_current,
+ x1, y1, x2, y2);
for (iter1 = objectlists; iter1 != NULL; iter1 = g_list_next(iter1)) {
for (iter2 = (GList*) iter1->data; iter2 != NULL; iter2 = g_list_next(iter2)) {
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 7b0f624..d177a61 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -422,7 +422,7 @@ void s_slot_update_object(TOPLEVEL *toplevel, OBJECT *object);
/* s_tile.c */
void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
-GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
+GList *s_tile_get_objectlists(TOPLEVEL *toplevel, PAGE *p_current, int world_x1, int world_y1, int world_x2, int world_y2);
/* s_undo.c */
UNDO *s_undo_return_tail(UNDO *head);
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index 9f6df1d..f02e9db 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -258,7 +258,7 @@ gchar *s_textbuffer_next_line (TextBuffer *tb);
void s_tile_init(TOPLEVEL *toplevel, PAGE *p_current);
void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object);
void s_tile_remove_object(OBJECT *object);
-void s_tile_print(TOPLEVEL *toplevel);
+void s_tile_print(TOPLEVEL *toplevel, PAGE *page);
void s_tile_free_all(PAGE *p_current);
/* s_weakref.c */
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index aa687d5..7049e61 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -241,7 +241,7 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
#if DEBUG
printf("Freeing page: %s\n", page->page_filename);
- s_tile_print(toplevel);
+ s_tile_print(toplevel, page);
#endif
s_tile_free_all (page);
@@ -255,7 +255,7 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
geda_list_remove( toplevel->pages, page );
#if DEBUG
- s_tile_print (toplevel);
+ s_tile_print (toplevel, page);
#endif
s_weakref_notify (page, page->weak_refs);
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index b99f47c..ce49af5 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -380,17 +380,15 @@ void s_tile_update_object(TOPLEVEL * toplevel, OBJECT * object)
* by the given rectangle (x1,y1), (x2,y2).
* \note The caller has to g_list_free() the returned list.
*/
-GList* s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1,
- int world_x2, int world_y2)
+GList* s_tile_get_objectlists(TOPLEVEL *toplevel, PAGE *p_current,
+ int world_x1, int world_y1,
+ int world_x2, int world_y2)
{
TILE *t_current;
- PAGE *p_current;
int x1, x2, y1, y2, x, y;
double x_size, y_size;
GList *objectlists = NULL;
- p_current = toplevel->page_current;
-
x_size = (double) toplevel->init_right / (double) MAX_TILES_X;
y_size = (double) toplevel->init_bottom / (double) MAX_TILES_Y;
@@ -431,7 +429,7 @@ GList* s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1,
* Debugging function to print all object names that are inside
* the tiles.
*/
-void s_tile_print(TOPLEVEL * toplevel)
+void s_tile_print(TOPLEVEL * toplevel, PAGE *page)
{
TILE *t_current;
GList *temp;
@@ -442,7 +440,7 @@ void s_tile_print(TOPLEVEL * toplevel)
for (i = 0; i < MAX_TILES_X; i++) {
printf("\nTile %d %d\n", i, j);
- t_current = &toplevel->page_current->world_tiles[i][j];
+ t_current = &page->world_tiles[i][j];
temp = t_current->objects;
while (temp) {
commit 2c445565d558f079e54f2508b35f734c58abab32
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Add o_box_modify_all().
o_box_modify() allows one corner of a box to be moved. Unfortunately,
it swaps the internal coordinates of the BOX structure around in a way
that could potentially cause unexpected behaviour. For instance,
suppose you wish to modify a box as shown below:
^ ^
| |
4| 4| +-----+
| | | |
3| 3| | |
| | | |
2| +--+ 2| +-----+
| | | |
1| | | 1|
| | | |
0| +--+ 0|
| |
+---------------> +--------------->
0 1 2 3 4 0 1 2 3 4
(A) Original box (B) Desired box
Calling o_box_modify() as follows will not work as expected:
o_box_modify (toplevel, box, 2, 4, BOX_UPPER_LEFT);
o_box_modify (toplevel, box, 4, 2, BOX_LOWER_RIGHT);
It will instead result in the transformations below:
^ ^
| |
4| +--+ 4| +--------+
| | | | | |
3| | | 3| | |
| | | | | |
2| | | 2| +--------+
| | | |
1| | | 1|
| | | |
0| +--+ 0|
| |
+---------------> +--------------->
0 1 2 3 4 0 1 2 3 4
(C) After first call (D) After second call
This is due to the fact o_box_modify() behaves as though the corner
specified by the whichone argument had been dragged.
This patch adds the o_box_modify_all() function, which allows all four
corners of the box to be modified at once, avoiding the problems
inherent in repeated o_box_modify() calls.
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 1b60f7c..7b0f624 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -125,6 +125,7 @@ void o_set_change_notify_funcs(TOPLEVEL *toplevel, ChangeNotifyFunc pre_change_f
/* o_box_basic.c */
OBJECT *o_box_new(TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2);
OBJECT *o_box_copy(TOPLEVEL *toplevel, OBJECT *o_current);
+void o_box_modify_all (TOPLEVEL *toplevel, OBJECT *object, int x1, int y1, int x2, int y2);
void o_box_modify(TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone);
void o_box_translate_world(TOPLEVEL *toplevel, int dx, int dy, OBJECT *object);
void o_box_rotate_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, int angle, OBJECT *object);
diff --git a/libgeda/src/o_box_basic.c b/libgeda/src/o_box_basic.c
index 0556d79..c99ccde 100644
--- a/libgeda/src/o_box_basic.c
+++ b/libgeda/src/o_box_basic.c
@@ -141,6 +141,34 @@ OBJECT *o_box_copy(TOPLEVEL *toplevel, OBJECT *o_current)
}
/*! \brief Modify a BOX OBJECT's coordinates.
+ * \par Function Description
+ * Modifies the coordinates of all four corners of \a box, by setting
+ * the box to the rectangle enclosed by the points (\a x1, \a y1) and
+ * (\a x2, \a y2).
+ *
+ * \param [in] toplevel current #TOPLEVEL.
+ * \param [in,out] object box #OBJECT to be modified.
+ * \param [in] x1 x coordinate of first corner of box.
+ * \param [in] y1 y coordinate of first corner of box.
+ * \param [in] x2 x coordinate of second corner of box.
+ * \param [in] y2 y coordinate of second corner of box,
+ */
+void
+o_box_modify_all (TOPLEVEL *toplevel, OBJECT *object,
+ int x1, int y1, int x2, int y2)
+{
+ object->box->lower_x = (x1 > x2) ? x1 : x2;
+ object->box->lower_y = (y1 > y2) ? y2 : y1;
+
+ object->box->upper_x = (x1 > x2) ? x2 : x1;
+ object->box->upper_y = (y1 > y2) ? y1 : y2;
+
+ /* recalculate the world coords and bounds */
+ o_box_recalc(toplevel, object);
+ o_emit_change_notify (toplevel, object);
+}
+
+/*! \brief Modify a BOX OBJECT's coordinates.
* \par Function Description
* This function modifies the coordinates of one of the four corner of
* the box. The new coordinates of the corner identified by <B>whichone</B>
commit 83530e16e28ebba72d7dc1f509d0005ea30c26f2
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Remove uses of deprecated SCM_STRING_CHARS.
diff --git a/libgeda/src/g_rc.c b/libgeda/src/g_rc.c
index d901128..f40156e 100644
--- a/libgeda/src/g_rc.c
+++ b/libgeda/src/g_rc.c
@@ -84,7 +84,7 @@ SCM g_rc_mode_general(SCM scmmode,
SCM_ASSERT (scm_is_string (scmmode), scmmode,
SCM_ARG1, rc_name);
- mode = SCM_STRING_CHARS (scmmode);
+ mode = scm_to_locale_string (scmmode);
index = vstbl_lookup_str(table, table_size, mode);
/* no match? */
@@ -98,7 +98,9 @@ SCM g_rc_mode_general(SCM scmmode,
*mode_var = vstbl_get_val(table, index);
ret = SCM_BOOL_T;
}
-
+
+ free (mode);
+
return ret;
}
@@ -346,6 +348,7 @@ void g_rc_parse(TOPLEVEL *toplevel,
SCM g_rc_component_library(SCM path, SCM name)
{
gchar *string;
+ char *temp;
char *namestr = NULL;
SCM_ASSERT (scm_is_string (path), path,
@@ -354,17 +357,22 @@ SCM g_rc_component_library(SCM path, SCM name)
if (name != SCM_UNDEFINED) {
SCM_ASSERT (scm_is_string (name), name,
SCM_ARG2, "component-library");
- namestr = SCM_STRING_CHARS (name);
+ namestr = scm_to_locale_string (name);
}
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
fprintf(stderr,
"Invalid path [%s] passed to component-library\n",
string);
+ if (namestr != NULL) {
+ free (namestr);
+ }
g_free(string);
return SCM_BOOL_F;
}
@@ -380,6 +388,9 @@ SCM g_rc_component_library(SCM path, SCM name)
g_free(cwd);
}
+ if (namestr != NULL) {
+ free (namestr);
+ }
g_free(string);
return SCM_BOOL_T;
@@ -453,6 +464,9 @@ SCM g_rc_component_library_command (SCM listcmd, SCM getcmd,
*/
SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
{
+ char *namestr;
+ SCM result = SCM_BOOL_F;
+
SCM_ASSERT (scm_is_true (scm_procedure_p (listfunc)), listfunc, SCM_ARG1,
"component-library-funcs");
SCM_ASSERT (scm_is_true (scm_procedure_p (getfunc)), getfunc, SCM_ARG2,
@@ -460,11 +474,14 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
SCM_ASSERT (scm_is_string (name), name, SCM_ARG1,
"component-library-funcs");
- if (s_clib_add_scm (listfunc, getfunc, SCM_STRING_CHARS (name)) != NULL) {
- return SCM_BOOL_T;
- } else {
- return SCM_BOOL_F;
+ namestr = scm_to_locale_string (name);
+
+ if (s_clib_add_scm (listfunc, getfunc, namestr) != NULL) {
+ result = SCM_BOOL_T;
}
+
+ free (namestr);
+ return result;
}
/*! \todo Finish function description!!!
@@ -477,6 +494,7 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
SCM g_rc_component_library_search(SCM path)
{
gchar *string;
+ char *temp;
GDir *dir;
const gchar *entry;
@@ -484,7 +502,9 @@ SCM g_rc_component_library_search(SCM path)
SCM_ARG1, "component-library-search");
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -543,12 +563,15 @@ SCM g_rc_component_library_search(SCM path)
SCM g_rc_source_library(SCM path)
{
gchar *string;
+ char *temp;
SCM_ASSERT (scm_is_string (path), path,
SCM_ARG1, "source-library");
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -585,6 +608,7 @@ SCM g_rc_source_library(SCM path)
SCM g_rc_source_library_search(SCM path)
{
gchar *string;
+ char *temp;
GDir *dir;
const gchar *entry;
@@ -592,7 +616,9 @@ SCM g_rc_source_library_search(SCM path)
SCM_ARG1, "source-library-search");
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -694,12 +720,15 @@ SCM g_rc_world_size(SCM width, SCM height, SCM border)
*/
SCM g_rc_untitled_name(SCM name)
{
+ char *temp;
SCM_ASSERT (scm_is_string (name), name,
SCM_ARG1, "untitled-name");
g_free(default_untitled_name);
- default_untitled_name = g_strdup (SCM_STRING_CHARS (name));
+ temp = scm_to_locale_string (name);
+ default_untitled_name = g_strdup (temp);
+ free (temp);
return SCM_BOOL_T;
}
@@ -715,12 +744,15 @@ SCM g_rc_untitled_name(SCM name)
SCM g_rc_scheme_directory(SCM path)
{
gchar *string;
+ char *temp;
SCM_ASSERT (scm_is_string (path), path,
SCM_ARG1, "scheme-directory");
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -747,12 +779,15 @@ SCM g_rc_scheme_directory(SCM path)
SCM g_rc_bitmap_directory(SCM path)
{
gchar *string;
+ char *temp;
SCM_ASSERT (scm_is_string (path), path,
SCM_ARG1, "bitmap-directory");
/* take care of any shell variables */
- string = s_expand_env_variables (SCM_STRING_CHARS (path));
+ temp = scm_to_locale_string (path);
+ string = s_expand_env_variables (temp);
+ free (temp);
/* invalid path? */
if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -778,11 +813,16 @@ SCM g_rc_bitmap_directory(SCM path)
*/
SCM g_rc_bus_ripper_symname(SCM scmsymname)
{
+ char *temp;
+
SCM_ASSERT (scm_is_string (scmsymname), scmsymname,
SCM_ARG1, "bus-ripper-symname");
g_free(default_bus_ripper_symname);
- default_bus_ripper_symname = g_strdup (SCM_STRING_CHARS (scmsymname));
+
+ temp = scm_to_locale_string (scmsymname);
+ default_bus_ripper_symname = g_strdup (temp);
+ free (temp);
return SCM_BOOL_T;
}
@@ -796,14 +836,18 @@ SCM g_rc_bus_ripper_symname(SCM scmsymname)
*/
SCM g_rc_postscript_prolog(SCM scmsymname)
{
+ char *temp;
+
SCM_ASSERT (scm_is_string (scmsymname), scmsymname,
SCM_ARG1, "postsript-prolog");
g_free(default_postscript_prolog);
/* take care of any shell variables */
+ temp = scm_to_locale_string (scmsymname);
default_postscript_prolog =
- s_expand_env_variables (SCM_STRING_CHARS (scmsymname));
+ s_expand_env_variables (temp);
+ free (temp);
return SCM_BOOL_T;
}
@@ -905,11 +949,15 @@ SCM g_rc_always_promote_attributes(SCM attrlist)
g_list_free(default_always_promote_attributes);
if (scm_is_string (attrlist)) {
+ char *temp;
s_log_message(_("WARNING: using a string for 'always-promote-attributes'"
" is deprecated. Use a list of strings instead\n"));
/* convert the space separated strings into a GList */
- attr2 = g_strsplit(SCM_STRING_CHARS (attrlist)," ", 0);
+ temp = scm_to_locale_string (attrlist);
+ attr2 = g_strsplit(temp," ", 0);
+ free (temp);
+
for (i=0; attr2[i] != NULL; i++) {
if (strlen(attr2[i]) > 0) {
list = g_list_prepend(list, g_strdup(attr2[i]));
@@ -921,10 +969,13 @@ SCM g_rc_always_promote_attributes(SCM attrlist)
length = scm_ilength(attrlist);
/* convert the scm list into a GList */
for (i=0; i < length; i++) {
+ char *temp;
SCM_ASSERT(scm_is_string(scm_list_ref(attrlist, scm_from_int(i))),
scm_list_ref(attrlist, scm_from_int(i)), SCM_ARG1,
"always-promote-attribute: list element is not a string");
- attr = g_strdup(SCM_STRING_CHARS(scm_list_ref(attrlist, scm_from_int(i))));
+ temp = scm_to_locale_string (scm_list_ref (attrlist, scm_from_int (i)));
+ attr = g_strdup(temp);
+ free (temp);
list = g_list_prepend(list, attr);
}
}
_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs