/*! \brief read a net object from a char buffer * \par Function Description * This function reads a net object from the buffer \a buf. * If the netobject was read successfully, a new net object is * allocated and appended to the \a object_list. * * \param [in] toplevel The TOPLEVEL object * \param [in] buf a text buffer (usually a line of a schematic file) * \param [in] release_ver The release number gEDA * \param [in] fileformat_ver a integer value of the file format * \return The object list, or NULL on error. * */ OBJECT *o_net_read (TOPLEVEL *toplevel, const char buf[], unsigned int release_ver, unsigned int fileformat_ver, GError **err) { OBJECT *new_obj; char type; int x1, y1; int x2, y2; int color; if (sscanf (buf, "%c %d %d %d %d %d\n", &type, &x1, &y1, &x2, &y2, &color) != 6) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse net object")); return NULL; } if (x1 == x2 && y1 == y2) { s_log_message (_("Found a zero length net [ %c %d %d %d %d %d ]\n"), type, x1, y1, x2, y2, color); } if (toplevel->override_net_color != -1) { color = toplevel->override_net_color; } if (color < 0 || color > MAX_COLORS) { s_log_message (_("Found an invalid color [ %s ]\n"), buf); s_log_message (_("Setting color to default color\n")); color = DEFAULT_COLOR; } new_obj = o_net_new (toplevel, type, color, x1, y1, x2, y2); return new_obj; }
/*! \brief create a copy of a net object * \par Function Description * This function creates a copy of the net object \a o_current. * * \param [in] toplevel The TOPLEVEL object * \param [in] o_current The object that is copied * \return a new net object */ OBJECT *o_net_copy(TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *new_obj; /* make sure you fix this in pin and bus as well */ /* still doesn't work... you need to pass in the new values */ /* or don't update and update later */ /* I think for now I'll disable the update and manually update */ new_obj = o_net_new (toplevel, OBJ_NET, o_current->color, o_current->line->x[0], o_current->line->y[0], o_current->line->x[1], o_current->line->y[1]); return new_obj; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ int o_net_add_busrippers(GschemToplevel *w_current, OBJECT *net_obj, GList *prev_conn_objects) { OBJECT *new_obj; GList *cl_current = NULL; OBJECT *bus_object = NULL; CONN *found_conn = NULL; int done; int otherone; BUS_RIPPER rippers[2]; int ripper_count = 0; int i; double length; int sign; double distance1, distance2; int first, second; int made_changes = FALSE; const int ripper_size = w_current->bus_ripper_size; int complex_angle = 0; const CLibSymbol *rippersym = NULL; GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_val_if_fail (page_view != NULL, FALSE); PAGE *page = gschem_page_view_get_page (page_view); g_return_val_if_fail (page != NULL, FALSE); length = o_line_length(net_obj); if (!prev_conn_objects) { return(FALSE); } if (length <= ripper_size) { return(FALSE); } /* check for a bus connection and draw rippers if so */ cl_current = prev_conn_objects; while (cl_current != NULL) { bus_object = (OBJECT *) cl_current->data; if (bus_object && bus_object->type == OBJ_BUS) { /* yes, using the net routine is okay */ int bus_orientation = o_net_orientation(bus_object); int net_orientation = o_net_orientation(net_obj); /* find the CONN structure which is associated with this object */ GList *cl_current2 = net_obj->conn_list; done = FALSE; while (cl_current2 != NULL && !done) { CONN *tmp_conn = (CONN *) cl_current2->data; if (tmp_conn && tmp_conn->other_object && tmp_conn->other_object == bus_object) { found_conn = tmp_conn; done = TRUE; } cl_current2 = g_list_next(cl_current2); } if (!found_conn) { return(FALSE); } otherone = !found_conn->whichone; /* now deal with the found connection */ if (bus_orientation == HORIZONTAL && net_orientation == VERTICAL) { /* printf("found horiz bus %s %d!\n", bus_object->name, found_conn->whichone);*/ sign = bus_object->bus_ripper_direction; if (!sign) { if (bus_object->line->x[0] < bus_object->line->x[1]) { first = 0; second = 1; } else { first = 1; second = 0; } distance1 = abs(bus_object->line->x[first] - net_obj->line->x[found_conn->whichone]); distance2 = abs(bus_object->line->x[second] - net_obj->line->x[found_conn->whichone]); if (distance1 <= distance2) { sign = 1; } else { sign = -1; } bus_object->bus_ripper_direction = sign; } /* printf("hor sign: %d\n", sign); */ if (net_obj->line->y[otherone] < bus_object->line->y[0]) { /* new net is below bus */ /*printf("below\n");*/ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 0; } else { complex_angle = 90; } } else { /* symmetric */ complex_angle = 0; } net_obj->line->y[found_conn->whichone] -= ripper_size; net_obj->w_bounds_valid_for = NULL; rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + sign*ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + ripper_size; ripper_count++; /* printf("done\n"); */ made_changes++; } else { /* new net is above bus */ /* printf("above\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 270; } else { complex_angle = 180; } } else { /* symmetric */ complex_angle = 180; } net_obj->line->y[found_conn->whichone] += ripper_size; net_obj->w_bounds_valid_for = NULL; rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + sign*ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] - ripper_size; ripper_count++; /* printf("done\n"); */ made_changes++; } } else if (bus_orientation == VERTICAL && net_orientation == HORIZONTAL) { /* printf("found vert bus %s %d!\n", bus_object->name, found_conn->whichone); */ sign = bus_object->bus_ripper_direction; if (!sign) { if (bus_object->line->y[0] < bus_object->line->y[1]) { first = 0; second = 1; } else { first = 1; second = 0; } distance1 = abs(bus_object->line->y[first] - net_obj->line->y[found_conn->whichone]); distance2 = abs(bus_object->line->y[second] - net_obj->line->y[found_conn->whichone]); if (distance1 <= distance2) { sign = 1; } else { sign = -1; } bus_object->bus_ripper_direction = sign; } /* printf("ver sign: %d\n", sign); */ if (net_obj->line->x[otherone] < bus_object->line->x[0]) { /* new net is to the left of the bus */ /* printf("left\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 0; } else { complex_angle = 270; } } else { /* symmetric */ complex_angle = 270; } net_obj->line->x[found_conn->whichone] -= ripper_size; net_obj->w_bounds_valid_for = NULL; rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + sign*ripper_size; ripper_count++; made_changes++; } else { /* new net is to the right of the bus */ /* printf("right\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 90; } else { complex_angle = 180; } } else { /* symmetric */ complex_angle = 90; } net_obj->line->x[found_conn->whichone] += ripper_size; net_obj->w_bounds_valid_for = NULL; rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] - ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + sign*ripper_size; ripper_count++; made_changes++; } } } cl_current = g_list_next(cl_current); } if (made_changes) { s_conn_remove_object_connections (page->toplevel, net_obj); if (w_current->bus_ripper_type == COMP_BUS_RIPPER) { GList *symlist = s_clib_search (page->toplevel->bus_ripper_symname, CLIB_EXACT); if (symlist != NULL) { rippersym = (CLibSymbol *) symlist->data; } g_list_free (symlist); } for (i = 0; i < ripper_count; i++) { if (w_current->bus_ripper_type == NET_BUS_RIPPER) { new_obj = o_net_new(page->toplevel, OBJ_NET, NET_COLOR, rippers[i].x[0], rippers[i].y[0], rippers[i].x[1], rippers[i].y[1]); s_page_append (page->toplevel, page, new_obj); } else { if (rippersym != NULL) { new_obj = o_complex_new (page->toplevel, OBJ_COMPLEX, DEFAULT_COLOR, rippers[i].x[0], rippers[i].y[0], complex_angle, 0, rippersym, page->toplevel->bus_ripper_symname, 1); s_page_append_list (page->toplevel, page, o_complex_promote_attribs (page->toplevel, new_obj)); s_page_append (page->toplevel, page, new_obj); } else { s_log_message(_("Bus ripper symbol [%s] was not found in any component library\n"), page->toplevel->bus_ripper_symname); } } } s_conn_update_object (page, net_obj); return(TRUE); } return(FALSE); }
/*! \brief finish a net drawing action * \par Function Description * This function finishes the drawing of a net. If we have a visible * magnetic marker, we use that instead of the current cursor * position. * * The rubber nets are removed, the nets and cues are drawn and the * net is added to the TOPLEVEL structure. * * The function returns TRUE if it has drawn a net, FALSE otherwise. */ void o_net_end(GschemToplevel *w_current, int w_x, int w_y) { int primary_zero_length, secondary_zero_length; int found_primary_connection = FALSE; int save_wx, save_wy; GList *prev_conn_objects; OBJECT *new_net = NULL; /* Save a list of added objects to run the %add-objects-hook later */ GList *added_objects = NULL; g_assert( w_current->inside_action != 0 ); GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); o_net_invalidate_rubber (w_current); if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) o_net_finishmagnetic(w_current); w_current->rubber_visible = 0; /* See if either of the nets are zero length. We'll only add */ /* the non-zero ones */ primary_zero_length = (w_current->first_wx == w_current->second_wx) && (w_current->first_wy == w_current->second_wy); secondary_zero_length = (w_current->second_wx == w_current->third_wx) && (w_current->second_wy == w_current->third_wy); /* If both nets are zero length... */ /* this ends the net drawing behavior */ if ( primary_zero_length && secondary_zero_length ) { o_net_reset(w_current); return; } save_wx = w_current->third_wx; save_wy = w_current->third_wy; if (w_current->third_wx != snap_grid (w_current, w_current->third_wx) || w_current->third_wy != snap_grid (w_current, w_current->third_wy)) s_log_message(_("Warning: Ending net at off grid coordinate\n")); if (!primary_zero_length ) { /* create primary net */ new_net = o_net_new(page->toplevel, OBJ_NET, NET_COLOR, w_current->first_wx, w_current->first_wy, w_current->second_wx, w_current->second_wy); s_page_append (page->toplevel, page, new_net); added_objects = g_list_prepend (added_objects, new_net); /* conn stuff */ /* LEAK CHECK 1 */ prev_conn_objects = s_conn_return_others (NULL, new_net); o_net_add_busrippers (w_current, new_net, prev_conn_objects); g_list_free (prev_conn_objects); #if DEBUG printf("primary:\n"); s_conn_print(new_net->conn_list); #endif /* Go off and search for valid connection on this newly created net */ found_primary_connection = s_conn_net_search(new_net, 1, new_net->conn_list); if (found_primary_connection) { /* if a net connection is found, reset start point of next net */ save_wx = w_current->second_wx; save_wy = w_current->second_wy; } } /* If the second net is not zero length, add it as well */ /* Also, a valid net connection from the primary net was not found */ if (!secondary_zero_length && !found_primary_connection) { /* Add secondary net */ new_net = o_net_new(page->toplevel, OBJ_NET, NET_COLOR, w_current->second_wx, w_current->second_wy, w_current->third_wx, w_current->third_wy); s_page_append (page->toplevel, page, new_net); added_objects = g_list_prepend (added_objects, new_net); /* conn stuff */ /* LEAK CHECK 2 */ prev_conn_objects = s_conn_return_others (NULL, new_net); o_net_add_busrippers (w_current, new_net, prev_conn_objects); g_list_free (prev_conn_objects); #if DEBUG s_conn_print(new_net->conn_list); #endif } /* Call add-objects-hook */ if (added_objects != NULL) { g_run_hook_object_list (w_current, "%add-objects-hook", added_objects); g_list_free (added_objects); } w_current->first_wx = save_wx; w_current->first_wy = save_wy; gschem_toplevel_page_content_changed (w_current, page); o_undo_savestate_old(w_current, UNDO_ALL); /* Continue net drawing */ o_net_start(w_current, w_current->first_wx, w_current->first_wy); }
/*! \brief finish a net drawing action * \par Function Description * This function finishes the drawing of a net. If we have a visible * magnetic marker, we use that instead of the current cursor * position. * * The rubber nets are removed, the nets and cues are drawn and the * net is added to the TOPLEVEL structure. * * The function returns TRUE if it has drawn a net, FALSE otherwise. */ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) { TOPLEVEL *toplevel = w_current->toplevel; int color; int primary_zero_length, secondary_zero_length; int found_primary_connection = FALSE; int save_wx, save_wy; GList *prev_conn_objects = NULL; OBJECT *new_net = NULL; g_assert( w_current->inside_action != 0 ); o_net_invalidate_rubber (w_current); if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) o_net_finishmagnetic(w_current); w_current->rubber_visible = 0; /* See if either of the nets are zero length. We'll only add */ /* the non-zero ones */ primary_zero_length = (w_current->first_wx == w_current->second_wx) && (w_current->first_wy == w_current->second_wy); secondary_zero_length = (w_current->second_wx == w_current->third_wx) && (w_current->second_wy == w_current->third_wy); /* If both nets are zero length... */ /* this ends the net drawing behavior */ if ( primary_zero_length && secondary_zero_length ) { return FALSE; } save_wx = w_current->third_wx; save_wy = w_current->third_wy; if (toplevel->override_net_color == -1) { color = NET_COLOR; } else { color = toplevel->override_net_color; } if (w_current->third_wx != snap_grid (w_current, w_current->third_wx) || w_current->third_wy != snap_grid (w_current, w_current->third_wy)) s_log_message(_("Warning: Ending net at off grid coordinate\n")); if (!primary_zero_length ) { /* create primary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->first_wx, w_current->first_wy, w_current->second_wx, w_current->second_wy); s_page_append (toplevel->page_current, new_net); /* conn stuff */ /* LEAK CHECK 1 */ prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) { g_list_free (prev_conn_objects); prev_conn_objects = NULL; prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); } #if DEBUG printf("primary:\n"); s_conn_print(new_net->conn_list); #endif o_invalidate (w_current, new_net); o_invalidate_glist (w_current, prev_conn_objects); g_list_free (prev_conn_objects); prev_conn_objects = NULL; /* Go off and search for valid connection on this newly created net */ found_primary_connection = s_conn_net_search(new_net, 1, new_net->conn_list); if (found_primary_connection) { /* if a net connection is found, reset start point of next net */ save_wx = w_current->second_wx; save_wy = w_current->second_wy; } /* you don't want to consolidate nets which are drawn non-ortho */ if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) { /* CAUTION: Object list will change when nets are consolidated, don't * keep pointers to other objects than new_net after this. */ o_net_consolidate_segments(toplevel, new_net); } } /* If the second net is not zero length, add it as well */ /* Also, a valid net connection from the primary net was not found */ if (!secondary_zero_length && !found_primary_connection) { /* Add secondary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->second_wx, w_current->second_wy, w_current->third_wx, w_current->third_wy); s_page_append (toplevel->page_current, new_net); /* conn stuff */ /* LEAK CHECK 2 */ prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) { g_list_free (prev_conn_objects); prev_conn_objects = NULL; prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); } #if DEBUG s_conn_print(new_net->conn_list); #endif o_invalidate (w_current, new_net); o_invalidate_glist (w_current, prev_conn_objects); g_list_free (prev_conn_objects); prev_conn_objects = NULL; /* you don't want to consolidate nets which are drawn non-ortho */ if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) { /* CAUTION: Object list will change when nets are consolidated, don't * keep pointers to other objects than new_net after this. */ o_net_consolidate_segments(toplevel, new_net); } } toplevel->page_current->CHANGED = 1; w_current->first_wx = save_wx; w_current->first_wy = save_wy; o_undo_savestate(w_current, UNDO_ALL); return (TRUE); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_move_check_endpoint(GschemToplevel *w_current, OBJECT * object) { GList *cl_current; CONN *c_current; OBJECT *other; int whichone; GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); if (!object) return; if (object->type != OBJ_NET && object->type != OBJ_PIN && object->type != OBJ_BUS) { fprintf(stderr, _("Got a non line object in o_move_check_endpoint\n")); return; } for (cl_current = object->conn_list; cl_current != NULL; cl_current = g_list_next(cl_current)) { c_current = (CONN *) cl_current->data; other = c_current->other_object; if (other == NULL) continue; /* really make sure that the object is not selected */ if (other->selected) continue; /* Catch pins, whos parent object is selected. */ if (other->parent != NULL && other->parent->selected) continue; if (c_current->type != CONN_ENDPOINT && (c_current->type != CONN_MIDPOINT || c_current->other_whichone == -1)) continue; if (/* (net)pin to (net)pin contact */ (object->type == OBJ_PIN && object->pin_type == PIN_TYPE_NET && other->type == OBJ_PIN && other->pin_type == PIN_TYPE_NET)) { /* net to (net)pin contact */ /* (object->type == OBJ_NET && other->type == OBJ_PIN && other->pin_type == PIN_TYPE_NET) */ OBJECT *new_net; /* other object is a pin, insert a net */ new_net = o_net_new (page->toplevel, OBJ_NET, NET_COLOR, c_current->x, c_current->y, c_current->x, c_current->y); s_page_append (page->toplevel, page, new_net); /* This new net object is only picked up for stretching later, * somewhat of a kludge. If the move operation is cancelled, these * new 0 length nets are removed by the "undo" operation invoked. */ } /* Only attempt to stretch nets and buses */ if (other->type != OBJ_NET && other->type != OBJ_BUS) continue; whichone = o_move_return_whichone (other, c_current->x, c_current->y); #if DEBUG printf ("FOUND: %s type: %d, whichone: %d, x,y: %d %d\n", other->name, c_current->type, whichone, c_current->x, c_current->y); printf("other x,y: %d %d\n", c_current->x, c_current->y); printf("type: %d return: %d real: [ %d %d ]\n", c_current->type, whichone, c_current->whichone, c_current->other_whichone); #endif if (whichone >= 0 && whichone <= 1) { w_current->stretch_list = s_stretch_add (w_current->stretch_list, other, whichone); } } }
/*! \brief finish a net drawing action * \par Function Description * This function finishes the drawing of a net. If we have a visible * magnetic marker, we use that instead of the current cursor * position. * * The rubber nets are removed, the nets and cues are drawn and the * net is added to the TOPLEVEL structure. * * The function returns TRUE if it has drawn a net, FALSE otherwise. */ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) { TOPLEVEL *toplevel = w_current->toplevel; int color; int primary_zero_length, secondary_zero_length; int found_primary_connection = FALSE; int save_wx, save_wy; GList *prev_conn_objects; OBJECT *new_net = NULL; /* Save a list of added objects to run the %add-objects-hook later */ GList *added_objects = NULL; g_assert( w_current->inside_action != 0 ); o_net_invalidate_rubber (w_current); if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) o_net_finishmagnetic(w_current); w_current->rubber_visible = 0; /* See if either of the nets are zero length. We'll only add */ /* the non-zero ones */ primary_zero_length = (w_current->first_wx == w_current->second_wx) && (w_current->first_wy == w_current->second_wy); secondary_zero_length = (w_current->second_wx == w_current->third_wx) && (w_current->second_wy == w_current->third_wy); /* If both nets are zero length... */ /* this ends the net drawing behavior */ if ( primary_zero_length && secondary_zero_length ) { return FALSE; } save_wx = w_current->third_wx; save_wy = w_current->third_wy; if (toplevel->override_net_color == -1) { color = NET_COLOR; } else { color = toplevel->override_net_color; } if (w_current->third_wx != snap_grid (w_current, w_current->third_wx) || w_current->third_wy != snap_grid (w_current, w_current->third_wy)) s_log_message(_("Warning: Ending net at off grid coordinate\n")); if (!primary_zero_length ) { /* create primary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->first_wx, w_current->first_wy, w_current->second_wx, w_current->second_wy); s_page_append (toplevel, toplevel->page_current, new_net); added_objects = g_list_prepend (added_objects, new_net); /* conn stuff */ /* LEAK CHECK 1 */ prev_conn_objects = s_conn_return_others (NULL, new_net); o_net_add_busrippers (w_current, new_net, prev_conn_objects); g_list_free (prev_conn_objects); #if DEBUG printf("primary:\n"); s_conn_print(new_net->conn_list); #endif /* Go off and search for valid connection on this newly created net */ found_primary_connection = s_conn_net_search(new_net, 1, new_net->conn_list); if (found_primary_connection) { /* if a net connection is found, reset start point of next net */ save_wx = w_current->second_wx; save_wy = w_current->second_wy; } } /* If the second net is not zero length, add it as well */ /* Also, a valid net connection from the primary net was not found */ if (!secondary_zero_length && !found_primary_connection) { /* Add secondary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->second_wx, w_current->second_wy, w_current->third_wx, w_current->third_wy); s_page_append (toplevel, toplevel->page_current, new_net); added_objects = g_list_prepend (added_objects, new_net); /* conn stuff */ /* LEAK CHECK 2 */ prev_conn_objects = s_conn_return_others (NULL, new_net); o_net_add_busrippers (w_current, new_net, prev_conn_objects); g_list_free (prev_conn_objects); #if DEBUG s_conn_print(new_net->conn_list); #endif } /* Call add-objects-hook */ if (added_objects != NULL) { g_run_hook_object_list ("%add-objects-hook", added_objects); g_list_free (added_objects); } toplevel->page_current->CHANGED = 1; w_current->first_wx = save_wx; w_current->first_wy = save_wy; o_undo_savestate(w_current, UNDO_ALL); return (TRUE); }