new find_inst_to_be_redrawn() implementation to recalculate area to be redrawn with/without show net names on symbol pins, simplified new_window() call in callback `x` command, code formatting in globals.c, added xschem get [xy]origin commands

This commit is contained in:
Stefan Frederik 2021-12-03 19:15:07 +01:00
parent 02173373cb
commit 629917cfcd
14 changed files with 2204 additions and 2246 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -270,6 +270,9 @@
<Component Id="cmpE33D206A79E72DCC203BF9219CECA21A" Guid="{A6E45888-2F91-47BF-B5E7-08769D0CB10C}"> <Component Id="cmpE33D206A79E72DCC203BF9219CECA21A" Guid="{A6E45888-2F91-47BF-B5E7-08769D0CB10C}">
<File Id="filE312160BD0F93495CC1CA4BF0D72A38E" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\rgb_led.sym" /> <File Id="filE312160BD0F93495CC1CA4BF0D72A38E" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\rgb_led.sym" />
</Component> </Component>
<Component Id="cmpD97AE943007C3AC19332BBE4DD1231CC" Guid="{9E87B48E-7BAC-4BA7-ADB9-AF663E891C8F}">
<File Id="fil15C79DAD681B86515BAC306AF0B7612A" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\rnmos4.sym" />
</Component>
<Component Id="cmpC0CDD9987356F9D8308F1F96CAA35403" Guid="{1AE154F8-0F7C-4E22-86F5-93F626D48901}"> <Component Id="cmpC0CDD9987356F9D8308F1F96CAA35403" Guid="{1AE154F8-0F7C-4E22-86F5-93F626D48901}">
<File Id="filEFB8AA2EEFBD6AE16A045E4F3A3EFD2B" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\spice_probe.sym" /> <File Id="filEFB8AA2EEFBD6AE16A045E4F3A3EFD2B" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\spice_probe.sym" />
</Component> </Component>
@ -5321,6 +5324,7 @@
<ComponentRef Id="cmpD523FFEB5C4A5B2C9B32756959301696" /> <ComponentRef Id="cmpD523FFEB5C4A5B2C9B32756959301696" />
<ComponentRef Id="cmpA6D9B275607613A4C61E8980D499B751" /> <ComponentRef Id="cmpA6D9B275607613A4C61E8980D499B751" />
<ComponentRef Id="cmpE33D206A79E72DCC203BF9219CECA21A" /> <ComponentRef Id="cmpE33D206A79E72DCC203BF9219CECA21A" />
<ComponentRef Id="cmpD97AE943007C3AC19332BBE4DD1231CC" />
<ComponentRef Id="cmpC0CDD9987356F9D8308F1F96CAA35403" /> <ComponentRef Id="cmpC0CDD9987356F9D8308F1F96CAA35403" />
<ComponentRef Id="cmp530072B273A8627AFC7F2E628B5116CE" /> <ComponentRef Id="cmp530072B273A8627AFC7F2E628B5116CE" />
<ComponentRef Id="cmpC76DA8327344C4B4AB04EF665B72B736" /> <ComponentRef Id="cmpC76DA8327344C4B4AB04EF665B72B736" />

View File

@ -267,13 +267,49 @@ void new_window(const char *cell, int symbol)
void new_window(const char* cell, int symbol) void new_window(const char* cell, int symbol)
{ {
char cmd_line[2 * PATH_MAX + 100];
struct stat buf; struct stat buf;
dbg(1, "new_window(): executable: %s, cell=%s, symbol=%d\n", xschem_executable, cell, symbol); dbg(1, "new_window(): executable: %s, cell=%s, symbol=%d\n", xschem_executable, cell, symbol);
if (stat(xschem_executable, &buf)) { if (stat(xschem_executable, &buf)) {
fprintf(errfp, "new_window(): executable not found\n"); fprintf(errfp, "new_window(): executable not found\n");
return; return;
} }
fprintf(errfp, "new_window(): feature doesn't exist\n"); /* According to Stackoverflow, system should be avoided because it's resource heavy
* and not secure.
* Furthermore, system doesn't spawn a TCL shell with XSchem
*/
/* int result = system(xschem_executable); */
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!cell || !cell[0]) {
if (!symbol)
my_snprintf(cmd_line, S(cmd_line), "%s -b -s", xschem_executable);
else
my_snprintf(cmd_line, S(cmd_line), "%s -b -y", xschem_executable);
}
else if (!symbol) {
my_snprintf(cmd_line, S(cmd_line), "%s -b -s \"%s\"", xschem_executable, cell);
}
else {
my_snprintf(cmd_line, S(cmd_line), "%s -b -y \"%s\"", xschem_executable, cell);
}
CreateProcessA
(
NULL, /* the path */
cmd_line, /* Command line */
NULL, /* Process handle not inheritable */
NULL, /* Thread handle not inheritable */
FALSE, /* Set handle inheritance to FALSE */
CREATE_NEW_CONSOLE, /* Opens file in a separate console */
NULL, /* Use parent's environment block */
NULL, /* Use parent's starting directory */
&si, /* Pointer to STARTUPINFO structure */
&pi /* Pointer to PROCESS_INFORMATION structure */
);
} }
#endif #endif
const char *get_file_path(char *f) const char *get_file_path(char *f)
@ -1579,8 +1615,8 @@ void new_wire(int what, double mx_snap, double my_snap)
{ {
int big = xctx->wires> 2000 || xctx->instances > 2000 ; int big = xctx->wires> 2000 || xctx->instances > 2000 ;
int s_pnetname; int s_pnetname;
s_pnetname = tclgetboolvar("show_pin_net_names");
if( (what & PLACE) ) { if( (what & PLACE) ) {
s_pnetname = tclgetboolvar("show_pin_net_names");
if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) { if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) {
xctx->push_undo(); xctx->push_undo();
if(xctx->manhattan_lines==1) { if(xctx->manhattan_lines==1) {
@ -1633,7 +1669,10 @@ void new_wire(int what, double mx_snap, double my_snap)
if(!big) { if(!big) {
bbox(START , 0.0 , 0.0 , 0.0 , 0.0); bbox(START , 0.0 , 0.0 , 0.0 , 0.0);
int_hash_lookup(xctx->node_redraw_table, xctx->wire[xctx->wires-1].node, 0, XINSERT_NOREPLACE); int_hash_lookup(xctx->node_redraw_table, xctx->wire[xctx->wires-1].node, 0, XINSERT_NOREPLACE);
find_inst_to_be_redrawn(1); }
if(!big) {
find_inst_to_be_redrawn(1 + 4 + 8); /* add bboxes before and after symbol_bbox, don't use selection */
find_inst_to_be_redrawn(16); /* delete hash and arrays */
bbox(SET , 0.0 , 0.0 , 0.0 , 0.0); bbox(SET , 0.0 , 0.0 , 0.0 , 0.0);
} }
draw(); draw();

View File

@ -1396,10 +1396,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
} }
if(key=='x' && state == 0 ) /* new cad session */ if(key=='x' && state == 0 ) /* new cad session */
{ {
char * tmp; new_window(NULL ,0);
tmp = (char *) tclgetvar("XSCHEM_START_WINDOW");
if(tmp && tmp[0]) new_window(abs_sym_path(tmp, "") ,0);
else new_window(NULL, 0);
break; break;
} }
if((key=='#') && !(state & ControlMask) ) if((key=='#') && !(state & ControlMask) )

View File

@ -388,7 +388,7 @@ void break_wires_at_pins(void)
int changed=0; int changed=0;
hash_wires(); hash_wires();
xctx->need_reb_sel_arr=1; xctx->need_reb_sel_arr=1; /* <<<< needed ? */
rebuild_selected_array(); rebuild_selected_array();
/* for(k=0;k<xctx->instances;k++) */ /* for(k=0;k<xctx->instances;k++) */

View File

@ -915,11 +915,9 @@ void update_symbol(const char *result, int x)
char *type; char *type;
int cond; int cond;
int pushed=0; int pushed=0;
int s_pnetname;
int *ii = &xctx->edit_sym_i; /* static var */ int *ii = &xctx->edit_sym_i; /* static var */
int *netl_com = &xctx->netlist_commands; /* static var */ int *netl_com = &xctx->netlist_commands; /* static var */
s_pnetname = tclgetboolvar("show_pin_net_names");
dbg(1, "update_symbol(): entering\n"); dbg(1, "update_symbol(): entering\n");
*ii=xctx->sel_array[0].n; *ii=xctx->sel_array[0].n;
if(!result) { if(!result) {
@ -968,22 +966,9 @@ void update_symbol(const char *result, int x)
dbg(1, "update_symbol(): for k loop: k=%d\n", k); dbg(1, "update_symbol(): for k loop: k=%d\n", k);
if(xctx->sel_array[k].type!=ELEMENT) continue; if(xctx->sel_array[k].type!=ELEMENT) continue;
*ii=xctx->sel_array[k].n; *ii=xctx->sel_array[k].n;
if(s_pnetname || xctx->hilight_nets) {
int j;
prepare_netlist_structs(0);
for(j = 0; j < (xctx->inst[*ii].ptr + xctx->sym)->rects[PINLAYER]; j++) {
if( xctx->inst[*ii].node && xctx->inst[*ii].node[j]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[*ii].node[j], 0, XINSERT_NOREPLACE);
}
}
find_inst_to_be_redrawn();
}
/* 20171220 calculate bbox before changes to correctly redraw areas */ /* 20171220 calculate bbox before changes to correctly redraw areas */
/* must be recalculated as cairo text extents vary with zoom factor. */ /* must be recalculated as cairo text extents vary with zoom factor. */
symbol_bbox(*ii, &xctx->inst[*ii].x1, &xctx->inst[*ii].y1, symbol_bbox(*ii, &xctx->inst[*ii].x1, &xctx->inst[*ii].y1, &xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
&xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
if(sym_number>=0) /* changing symbol ! */ if(sym_number>=0) /* changing symbol ! */
{ {
if(!pushed) { xctx->push_undo(); pushed=1;} if(!pushed) { xctx->push_undo(); pushed=1;}
@ -1058,31 +1043,14 @@ void update_symbol(const char *result, int x)
} /* end for(k=0;k<xctx->lastsel;k++) */ } /* end for(k=0;k<xctx->lastsel;k++) */
/* new symbol bbox after prop changes (may change due to text length) */ /* new symbol bbox after prop changes (may change due to text length) */
if(xctx->modified) { if(xctx->modified) {
int j;
xctx->prep_hash_inst=0; xctx->prep_hash_inst=0;
xctx->prep_net_structs=0; xctx->prep_net_structs=0;
xctx->prep_hi_structs=0; xctx->prep_hi_structs=0;
if(s_pnetname || xctx->hilight_nets) prepare_netlist_structs(0); find_inst_to_be_redrawn(1 + 4 + 32); /* 32: call prepare_netlist_structs(0) */
for(k=0;k<xctx->lastsel;k++) { find_inst_to_be_redrawn(16); /* clear data */
if(xctx->sel_array[k].type!=ELEMENT) continue;
*ii=xctx->sel_array[k].n;
type=xctx->sym[xctx->inst[*ii].ptr].type;
symbol_bbox(*ii, &xctx->inst[*ii].x1, &xctx->inst[*ii].y1,
&xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
bbox(ADD, xctx->inst[*ii].x1, xctx->inst[*ii].y1,
xctx->inst[*ii].x2, xctx->inst[*ii].y2);
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type)) {
for(j = 0; j < (xctx->inst[*ii].ptr + xctx->sym)->rects[PINLAYER]; j++) {
if( xctx->inst[*ii].node && xctx->inst[*ii].node[j]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[*ii].node[j], 0, XINSERT_NOREPLACE);
}
}
}
}
if(xctx->hilight_nets) { if(xctx->hilight_nets) {
propagate_hilights(1, 1, XINSERT_NOREPLACE); propagate_hilights(1, 1, XINSERT_NOREPLACE);
} }
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn();
} }
/* redraw symbol with new props */ /* redraw symbol with new props */
bbox(SET,0.0,0.0,0.0,0.0); bbox(SET,0.0,0.0,0.0,0.0);

View File

@ -468,52 +468,124 @@ void draw_selection(GC g, int interruptable)
xctx->movelastsel = i; xctx->movelastsel = i;
} }
/* A list of electrical nodes that could potentially have been changed is previously hashed /*
* into xctx->node_redraw_table, find all connected instances/wires and set bbox of areas * build list of nodes attached to objects (wires, pins, wire labels) about to be moved/copied/deleted,
* that potentially need to be redraw (show net names on symbol pins) * first time call with find_inst_to_be_redrawn(1), before doing the move/copy/delete,
* then call with find_inst_to_be_redrawn(6) (2 | 4) after move/copy/delete is done.
* what (bits can be ORed together):
* 1: collect list of instances to be redrawn, add bboxes
* 2: use previously collected list, add bboxes with updated node names, do this call after moving/deleting
* objects and after a prepare_netlist_structs()
* 4: call symbol_bbox before bbox(ADD, ...)
* 8: do NOT build xctx->node_redraw_table using selected instances/wires
* 16: clear hash and arrays
* 32: call prepare_netlist_structs(0) if hilights or show net name on pins
*/ */
void find_inst_to_be_redrawn() void find_inst_to_be_redrawn(int what)
{ {
struct int_hashentry *ientry; struct int_hashentry *nentry;
int i, p, rects; int i, n, p, rects;
xSymbol * sym; xSymbol * sym;
xInstance * const inst = xctx->inst;
int s_pnetname = tclgetboolvar("show_pin_net_names");
dbg(1,"find_inst_to_be_redrawn(): what=%d\n", what);
if(what & 16) {
memset(xctx->inst_redraw_table, 0, HASHSIZE * sizeof(unsigned char));
int_hash_free(xctx->node_redraw_table);
return;
}
if((s_pnetname || xctx->hilight_nets)) {
if(what & 32) prepare_netlist_structs(0);
if(!(what & 8)) {
for(i=0;i<xctx->lastsel;i++)
{
n = xctx->sel_array[i].n;
if( xctx->sel_array[i].type == ELEMENT) {
int p;
char *type=xctx->sym[xctx->inst[n].ptr].type;
/* collect all nodes connected to instances that set node names */
if(type && IS_LABEL_OR_PIN(type)) {
for(p = 0; p < (inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( inst[n].node && inst[n].node[p]) {
dbg(1,"find_inst_to_be_redrawn(): hashing inst %s, node %s\n", inst[n].instname, inst[n].node[p]);
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
/* collect all nodes connected to selected wires (node names will change if wire deleted/moved) */
if(xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
} /* if(!(what & 8)) */
for(i=0; i < xctx->instances; i++) { for(i=0; i < xctx->instances; i++) {
sym = xctx->inst[i].ptr + xctx->sym; sym = xctx->inst[i].ptr + xctx->sym;
rects = sym->rects[PINLAYER]; rects = sym->rects[PINLAYER];
if(what & 2 && xctx->inst_redraw_table[i]) {
dbg(1, "find_inst_to_be_redrawn(): 1 bboxing inst %s\n", xctx->inst[i].instname);
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2 );
if(what & 4) {
symbol_bbox(i, &inst[i].x1, &inst[i].y1, &inst[i].x2, &inst[i].y2 );
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2 );
}
continue;
}
for(p = 0; p < rects; p++) { for(p = 0; p < rects; p++) {
if(xctx->inst[i].node && xctx->inst[i].node[p]) { if(xctx->inst[i].node && xctx->inst[i].node[p]) {
ientry = int_hash_lookup(xctx->node_redraw_table, xctx->inst[i].node[p], 0, XLOOKUP); nentry = int_hash_lookup(xctx->node_redraw_table, xctx->inst[i].node[p], 0, XLOOKUP);
if(ientry) { if(nentry) {
/* dbg(0, "find_inst_to_be_redrawn(): inst to be redrawn: %d\n", i); */ dbg(1, "find_inst_to_be_redrawn(): 2 bboxing inst %s\n", xctx->inst[i].instname);
symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2 );
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2); bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
if(what & 4) {
symbol_bbox(i, &inst[i].x1, &inst[i].y1, &inst[i].x2, &inst[i].y2);
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
}
xctx->inst_redraw_table[i] = 1;
break; break;
} }
} }
} }
} }
for(i=0;i < xctx->wires; i++) { for(i=0;i < xctx->wires; i++) {
if(xctx->wire[i].node) { if(xctx->wire[i].node) {
ientry = int_hash_lookup(xctx->node_redraw_table, xctx->wire[i].node, 0, XLOOKUP); nentry = int_hash_lookup(xctx->node_redraw_table, xctx->wire[i].node, 0, XLOOKUP);
if(ientry) { if(nentry) {
if(xctx->wire[i].bus){ if(xctx->wire[i].bus){
int ov, y1, y2; int ov, y1, y2;
ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE; ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE;
if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; } if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; } else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
dbg(1, "find_inst_to_be_redrawn(): 3 bboxing wire %d\n", i);
bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 ); bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
} else { } else {
int ov, y1, y2; int ov, y1, y2;
ov = cadhalfdotsize; ov = cadhalfdotsize;
if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; } if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; } else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
dbg(1, "find_inst_to_be_redrawn(): 4 bboxing wire %d\n", i);
bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 ); bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
} }
} }
} }
} }
int_hash_free(xctx->node_redraw_table); } /* if((s_pnetname || xctx->hilight_nets)) */
if(!(what & 8) ) {
for(i=0;i<xctx->lastsel;i++) { /* add bboxes of selected objects */
n = xctx->sel_array[i].n;
if( xctx->sel_array[i].type == ELEMENT) {
dbg(1, "find_inst_to_be_redrawn(): 5 bboxing inst %s\n", xctx->inst[n].instname);
bbox(ADD, inst[n].x1, inst[n].y1, inst[n].x2, inst[n].y2 );
if(what & 4) {
symbol_bbox(n, &inst[n].x1, &inst[n].y1, &inst[n].x2, &inst[n].y2);
bbox(ADD, inst[n].x1, inst[n].y1, inst[n].x2, inst[n].y2);
}
}
}
}
} }
void copy_objects(int what) void copy_objects(int what)
@ -528,10 +600,7 @@ void copy_objects(int what)
#if HAS_CAIRO==1 #if HAS_CAIRO==1
int customfont; int customfont;
#endif #endif
xInstance * const inst = xctx->inst;
int s_pnetname;
s_pnetname = tclgetboolvar("show_pin_net_names");
if(what & START) if(what & START)
{ {
xctx->rotatelocal=0; xctx->rotatelocal=0;
@ -586,32 +655,8 @@ void copy_objects(int what)
firstw = firsti = 1; firstw = firsti = 1;
/* calculate moving symbols bboxes before actually doing the copy */
/* this is necessary for some objects that change their dimension when copied */
/* (example: annotator ngspice_probe components) */
for(i=0;i<xctx->lastsel;i++)
{
n = xctx->sel_array[i].n;
if( xctx->sel_array[i].type == ELEMENT) {
int p;
char *type=xctx->sym[xctx->inst[n].ptr].type;
symbol_bbox(n, &inst[n].x1, &inst[n].y1, &inst[n].x2, &inst[n].y2 );
bbox(ADD, inst[n].x1, inst[n].y1, inst[n].x2, inst[n].y2 );
/* hash all nodes of copied objects before the copy, they might need update if net_name=true */
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type)) {
for(p = 0; p < (inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( inst[n].node && inst[n].node[p]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
if((s_pnetname || xctx->hilight_nets) && xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
draw_selection(xctx->gctiled,0); draw_selection(xctx->gctiled,0);
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn(); find_inst_to_be_redrawn(1); /* build list before copying and recalculating prepare_netlist_structs() */
for(i=0;i<xctx->lastsel;i++) for(i=0;i<xctx->lastsel;i++)
{ {
@ -940,38 +985,15 @@ void copy_objects(int what)
xctx->instances++; xctx->instances++;
} /* if(xctx->sel_array[i].type == ELEMENT) */ } /* if(xctx->sel_array[i].type == ELEMENT) */
} /* for(i = 0; i < xctx->lastsel; i++) */ } /* for(i = 0; i < xctx->lastsel; i++) */
xctx->need_reb_sel_arr=1; xctx->need_reb_sel_arr=1;
rebuild_selected_array(); rebuild_selected_array();
/* force these vars to 0 to trigger a prepare_netlist_structs(0) needed by symbol_bbox->translate
* to translate @#n:net_name texts */
if(!firsti || !firstw) { if(!firsti || !firstw) {
xctx->prep_net_structs=0; xctx->prep_net_structs=0;
xctx->prep_hi_structs=0; xctx->prep_hi_structs=0;
} }
if(s_pnetname || xctx->hilight_nets) { /* build after copying and after recalculating prepare_netlist_structs() */
prepare_netlist_structs(0); find_inst_to_be_redrawn(2 + 4 + 32); /* 32: call prepare_netlist_structs(0) */
} find_inst_to_be_redrawn(16); /* clear data */
for(i = 0; i < xctx->lastsel; i++) {
n = xctx->sel_array[i].n;
if(xctx->sel_array[i].type == ELEMENT) {
int p;
char *type=xctx->sym[xctx->inst[n].ptr].type;
symbol_bbox(n, &xctx->inst[n].x1, &xctx->inst[n].y1, &xctx->inst[n].x2, &xctx->inst[n].y2 );
bbox(ADD, xctx->inst[n].x1, xctx->inst[n].y1, xctx->inst[n].x2, xctx->inst[n].y2 );
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type)) {
for(p = 0; p < (xctx->inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( xctx->inst[n].node && xctx->inst[n].node[p]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
if((s_pnetname || xctx->hilight_nets) && xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
} /* for(i = 0; i < xctx->lastsel; i++) */
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn();
check_collapsing_objects(); check_collapsing_objects();
if(tclgetboolvar("autotrim_wires")) trim_wires(); if(tclgetboolvar("autotrim_wires")) trim_wires();
/* update_conn_cues(1, 1); */ /* update_conn_cues(1, 1); */
@ -996,12 +1018,9 @@ void move_objects(int what, int merge, double dx, double dy)
#if HAS_CAIRO==1 #if HAS_CAIRO==1
int customfont; int customfont;
#endif #endif
xInstance * const inst = xctx->inst;
xLine ** const line = xctx->line; xLine ** const line = xctx->line;
xWire * const wire = xctx->wire; xWire * const wire = xctx->wire;
int s_pnetname;
s_pnetname = tclgetboolvar("show_pin_net_names");
if(what & START) if(what & START)
{ {
xctx->rotatelocal=0; xctx->rotatelocal=0;
@ -1051,7 +1070,8 @@ void move_objects(int what, int merge, double dx, double dy)
bbox(START, 0.0 , 0.0 , 0.0 , 0.0); bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
set_modify(1); set_modify(1);
if( !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) { /* no undo push for MERGE ad PLACE, already done before */ /* no undo push for MERGE ad PLACE, already done before */
if( !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) {
dbg(1, "move_objects(): push undo state\n"); dbg(1, "move_objects(): push undo state\n");
xctx->push_undo(); xctx->push_undo();
} }
@ -1064,30 +1084,8 @@ void move_objects(int what, int merge, double dx, double dy)
/* calculate moving symbols bboxes before actually doing the move */ /* calculate moving symbols bboxes before actually doing the move */
firsti = firstw = 1; firsti = firstw = 1;
for(i=0;i<xctx->lastsel;i++)
{
n = xctx->sel_array[i].n;
if( xctx->sel_array[i].type == ELEMENT) {
int p;
char *type=xctx->sym[xctx->inst[n].ptr].type;
symbol_bbox(n, &inst[n].x1, &inst[n].y1, &inst[n].x2, &inst[n].y2 );
bbox(ADD, inst[n].x1, inst[n].y1, inst[n].x2, inst[n].y2 );
/* hash all nodes of copied objects before the copy, they might need update if net_name=true */
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type)) {
for(p = 0; p < (inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( inst[n].node && inst[n].node[p]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
if((s_pnetname || xctx->hilight_nets) && xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
draw_selection(xctx->gctiled,0); draw_selection(xctx->gctiled,0);
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn(); find_inst_to_be_redrawn(1); /* build list before moving and recalculating prepare_netlist_structs() */
for(k=0;k<cadlayers;k++) for(k=0;k<cadlayers;k++)
{ {
for(i=0;i<xctx->lastsel;i++) for(i=0;i<xctx->lastsel;i++)
@ -1472,46 +1470,26 @@ void move_objects(int what, int merge, double dx, double dy)
xctx->prep_hash_inst=0; xctx->prep_hash_inst=0;
firsti = 0; firsti = 0;
if(xctx->rotatelocal) { if(xctx->rotatelocal) {
ROTATION(xctx->move_rot, xctx->move_flip, inst[n].x0, inst[n].y0, ROTATION(xctx->move_rot, xctx->move_flip, xctx->inst[n].x0, xctx->inst[n].y0,
inst[n].x0, inst[n].y0, xctx->rx1,xctx->ry1); xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1);
} else { } else {
ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1,
inst[n].x0, inst[n].y0, xctx->rx1,xctx->ry1); xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1);
} }
inst[n].x0 = xctx->rx1+xctx->deltax; xctx->inst[n].x0 = xctx->rx1+xctx->deltax;
inst[n].y0 = xctx->ry1+xctx->deltay; xctx->inst[n].y0 = xctx->ry1+xctx->deltay;
inst[n].rot = (inst[n].rot + xctx->inst[n].rot = (xctx->inst[n].rot +
( (xctx->move_flip && (inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3; ( (xctx->move_flip && (xctx->inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3;
inst[n].flip = xctx->move_flip ^ inst[n].flip; xctx->inst[n].flip = xctx->move_flip ^ xctx->inst[n].flip;
} }
} }
if(!firsti || !firstw) { if(!firsti || !firstw) {
xctx->prep_net_structs=0; xctx->prep_net_structs=0;
xctx->prep_hi_structs=0; xctx->prep_hi_structs=0;
} }
if(s_pnetname || xctx->hilight_nets) { /* build after copying and after recalculating prepare_netlist_structs() */
prepare_netlist_structs(0); find_inst_to_be_redrawn(2 + 4 + 32); /* 32: call prepare_netlist_structs(0) */
} find_inst_to_be_redrawn(16); /* clear data */
for(i = 0; i < xctx->lastsel; i++) {
n = xctx->sel_array[i].n;
if(xctx->sel_array[i].type == ELEMENT) {
int p;
char *type=xctx->sym[xctx->inst[n].ptr].type;
symbol_bbox(n, &inst[n].x1, &inst[n].y1, &inst[n].x2, &inst[n].y2 );
bbox(ADD, inst[n].x1, inst[n].y1, inst[n].x2, inst[n].y2 );
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type)) {
for(p = 0; p < (inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( inst[n].node && inst[n].node[p]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
if((s_pnetname || xctx->hilight_nets) && xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn();
check_collapsing_objects(); check_collapsing_objects();
if(tclgetboolvar("autotrim_wires")) trim_wires(); if(tclgetboolvar("autotrim_wires")) trim_wires();
/* update_conn_cues(1, 1); */ /* update_conn_cues(1, 1); */

View File

@ -1345,12 +1345,12 @@ void pop_undo(int redo, int set_modify_status)
fclose(fd); fclose(fd);
#endif #endif
dbg(2, "pop_undo(): loaded file:wire=%d inst=%d\n",xctx->wires , xctx->instances); dbg(2, "pop_undo(): loaded file:wire=%d inst=%d\n",xctx->wires , xctx->instances);
link_symbols_to_instances(-1);
if(set_modify_status) set_modify(1); if(set_modify_status) set_modify(1);
xctx->prep_hash_inst=0; xctx->prep_hash_inst=0;
xctx->prep_hash_wires=0; xctx->prep_hash_wires=0;
xctx->prep_net_structs=0; xctx->prep_net_structs=0;
xctx->prep_hi_structs=0; xctx->prep_hi_structs=0;
link_symbols_to_instances(-1);
update_conn_cues(0, 0); update_conn_cues(0, 0);
dbg(2, "pop_undo(): returning\n"); dbg(2, "pop_undo(): returning\n");
} }

View File

@ -1466,7 +1466,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_snprintf(fullname, S(fullname),"%s", tclresult()); my_snprintf(fullname, S(fullname),"%s", tclresult());
} }
if( fullname[0] ) { if( fullname[0] ) {
Tcl_VarEval(interp, "new_window create ", fullname, NULL); Tcl_VarEval(interp, "new_window create {", fullname, "}", NULL);
Tcl_VarEval(interp, "update_recent_file {", fullname, "}", NULL); Tcl_VarEval(interp, "update_recent_file {", fullname, "}", NULL);
} }
} }

View File

@ -173,7 +173,7 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
xctx->inst[i].yy1 = *y1; /* for easier select */ xctx->inst[i].yy1 = *y1; /* for easier select */
xctx->inst[i].xx2 = *x2; xctx->inst[i].xx2 = *x2;
xctx->inst[i].yy2 = *y2; xctx->inst[i].yy2 = *y2;
dbg(2, "symbol_bbox(): instance=%d %.16g %.16g %.16g %.16g\n",i,*x1, *y1, *x2, *y2); dbg(2, "symbol_bbox(): instance=%s %.16g %.16g %.16g %.16g\n",xctx->inst[i].instname,*x1, *y1, *x2, *y2);
/* strings bbox */ /* strings bbox */
for(j=0;j< (xctx->inst[i].ptr+ xctx->sym)->texts;j++) for(j=0;j< (xctx->inst[i].ptr+ xctx->sym)->texts;j++)
{ {
@ -198,8 +198,8 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
if(yy1<*y1) *y1=yy1; if(yy1<*y1) *y1=yy1;
if(xx2>*x2) *x2=xx2; if(xx2>*x2) *x2=xx2;
if(yy2>*y2) *y2=yy2; if(yy2>*y2) *y2=yy2;
/* dbg(2, "symbol_bbox(): instance=%d text=%d %.16g %.16g %.16g %.16g\n",i,j, *x1, *y1, *x2, *y2); */
} }
dbg(1, "symbol_bbox(): instance=%s %.16g %.16g %.16g %.16g\n", xctx->inst[i].instname, *x1, *y1, *x2, *y2);
} }
@ -315,15 +315,13 @@ static void del_rect_line_arc_poly(void)
void delete(int to_push_undo) void delete(int to_push_undo)
{ {
int i, j, n, tmp; int i, j, tmp;
int select_rot = 0, select_flip = 0; int select_rot = 0, select_flip = 0;
#if HAS_CAIRO==1 #if HAS_CAIRO==1
int customfont; int customfont;
#endif #endif
int s_pnetname;
double xx1,yy1,xx2,yy2; double xx1,yy1,xx2,yy2;
s_pnetname = tclgetboolvar("show_pin_net_names");
dbg(3, "delete(): start\n"); dbg(3, "delete(): start\n");
j = 0; j = 0;
bbox(START, 0.0 , 0.0 , 0.0 , 0.0); bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
@ -331,45 +329,7 @@ void delete(int to_push_undo)
if(to_push_undo && xctx->lastsel) xctx->push_undo(); if(to_push_undo && xctx->lastsel) xctx->push_undo();
/* first calculate bbox, because symbol_bbox() needs translate (@#0:net_name) which /* first calculate bbox, because symbol_bbox() needs translate (@#0:net_name) which
* needs prepare_netlist_structs which needs a consistent xctx->inst[] data structure */ * needs prepare_netlist_structs which needs a consistent xctx->inst[] data structure */
find_inst_to_be_redrawn(1 + 32); /* 32: call prepare_netlist_structs(0) */
/* does not seem to be needed
* xctx->prep_net_structs=0;
* xctx->prep_hi_structs=0;
*/
if((s_pnetname || xctx->hilight_nets)) prepare_netlist_structs(0);
for(i = 0; i < xctx->lastsel; i++) {
n = xctx->sel_array[i].n;
if(xctx->sel_array[i].type == ELEMENT) {
int p;
char *type = (xctx->inst[n].ptr + xctx->sym)->type;
symbol_bbox(n, &xctx->inst[n].x1, &xctx->inst[n].y1, &xctx->inst[n].x2, &xctx->inst[n].y2 );
bbox(ADD, xctx->inst[n].x1, xctx->inst[n].y1, xctx->inst[n].x2, xctx->inst[n].y2 );
if((s_pnetname || xctx->hilight_nets) && type && IS_LABEL_OR_PIN(type) ) {
for(p = 0; p < (xctx->inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) { /* only .node[0] ? */
if( xctx->inst[n].node && xctx->inst[n].node[p]) {
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
if((s_pnetname || xctx->hilight_nets) && xctx->sel_array[i].type == WIRE && xctx->wire[n].node) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
if(s_pnetname || xctx->hilight_nets) find_inst_to_be_redrawn();
/* already done above
for(i=0;i<xctx->instances;i++)
{
if(xctx->inst[i].sel == SELECTED)
{
symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2);
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
}
}
*/
for(i=0;i<xctx->texts;i++) for(i=0;i<xctx->texts;i++)
{ {
if(xctx->text[i].sel == SELECTED) if(xctx->text[i].sel == SELECTED)
@ -474,6 +434,9 @@ void delete(int to_push_undo)
propagate_hilights(1, 1, XINSERT_NOREPLACE); propagate_hilights(1, 1, XINSERT_NOREPLACE);
} }
prepare_netlist_structs(0);
find_inst_to_be_redrawn(2 + 4 + 8);
find_inst_to_be_redrawn(16); /* clear data */
xctx->lastsel = 0; xctx->lastsel = 0;
bbox(SET , 0.0 , 0.0 , 0.0 , 0.0); bbox(SET , 0.0 , 0.0 , 0.0 , 0.0);
draw(); draw();
@ -521,6 +484,7 @@ void bbox(int what,double x1,double y1, double x2, double y2)
fprintf(errfp, "ERROR: bbox(ADD) call before bbox(START)\n"); fprintf(errfp, "ERROR: bbox(ADD) call before bbox(START)\n");
tcleval("alert_ {ERROR: bbox(ADD) call before bbox(START)} {}"); tcleval("alert_ {ERROR: bbox(ADD) call before bbox(START)} {}");
} }
dbg(1, " bbox(ADD,...): %.16g %.16g %.16g %.16g\n", x1, y1, x2, y2);
x1=X_TO_SCREEN(x1); x1=X_TO_SCREEN(x1);
y1=Y_TO_SCREEN(y1); y1=Y_TO_SCREEN(y1);
x2=X_TO_SCREEN(x2); x2=X_TO_SCREEN(x2);

View File

@ -452,12 +452,11 @@ void alloc_xschem_data(const char *top_path)
xctx->inst_spatial_table[i][j] = NULL; xctx->inst_spatial_table[i][j] = NULL;
} }
} }
for(i = 0 ; i < HASHSIZE; i++) { memset(xctx->inst_table, 0, HASHSIZE * sizeof(struct inst_hashentry *));
xctx->inst_table[i] = NULL; memset(xctx->node_table, 0, HASHSIZE * sizeof(struct node_hashentry *));
xctx->node_table[i] = NULL; memset(xctx->hilight_table, 0, HASHSIZE *sizeof(struct hilight_hashentry *));
xctx->hilight_table[i] = NULL; memset(xctx->node_redraw_table, 0, HASHSIZE * sizeof(struct int_hashentry *));
xctx->node_redraw_table[i] = NULL; /* move.c */ memset(xctx->inst_redraw_table, 0, HASHSIZE * sizeof(unsigned char));
}
xctx->window = xctx->save_pixmap = 0; xctx->window = xctx->save_pixmap = 0;
xctx->xrect[0].width = xctx->xrect[0].height = xctx->xrect[0].x = xctx->xrect[0].y = 0; xctx->xrect[0].width = xctx->xrect[0].height = xctx->xrect[0].x = xctx->xrect[0].y = 0;
xctx->xschem_w = xctx->xschem_h = 0; xctx->xschem_w = xctx->xschem_h = 0;

View File

@ -634,7 +634,10 @@ typedef struct {
char sel_or_clip[PATH_MAX]; char sel_or_clip[PATH_MAX];
int onetime; int onetime;
/* move.c */ /* move.c */
/* list of nodes, instances attached to these need redraw */
struct int_hashentry *node_redraw_table[HASHSIZE]; struct int_hashentry *node_redraw_table[HASHSIZE];
/* list of instances, collected using previous table, that need redraw */
unsigned char inst_redraw_table[HASHSIZE];
double rx1, rx2, ry1, ry2; double rx1, rx2, ry1, ry2;
short move_rot; short move_rot;
short move_flip; short move_flip;
@ -1084,7 +1087,7 @@ extern void arc_3_points(double x1, double y1, double x2, double y2, double x3,
extern void move_objects(int what,int merge, double dx, double dy); extern void move_objects(int what,int merge, double dx, double dy);
extern void redraw_w_a_l_r_p_rubbers(void); /* redraw wire, arcs, line, polygon rubbers */ extern void redraw_w_a_l_r_p_rubbers(void); /* redraw wire, arcs, line, polygon rubbers */
extern void copy_objects(int what); extern void copy_objects(int what);
extern void find_inst_to_be_redrawn(); extern void find_inst_to_be_redrawn(int what);
extern void pan(int what); extern void pan(int what);
extern void pan2(int what, int mx, int my); extern void pan2(int what, int mx, int my);
extern void zoom_rectangle(int what); extern void zoom_rectangle(int what);

View File

@ -1,4 +1,4 @@
v {xschem version=2.9.9 file_version=1.2 } v {xschem version=3.0.0 file_version=1.2 }
G {} G {}
K {type=subcircuit K {type=subcircuit
function0="1 ~" function0="1 ~"
@ -6,7 +6,7 @@ format="@name @pinlist @symname WN=@WN WP=@WP LLN=@LLN LLP=@LLP m=@m"
verilog_primitive=true verilog_primitive=true
verilog_format="assign #80 @@Z = ~ @@A ;" verilog_format="assign #80 @@Z = ~ @@A ;"
template="name=X1 WN=15u WP=45u LLN=3u LLP=3u m=1" template="name=X1 WN=15u WP=45u LLN=3u LLP=3u m=1"
} net_name=true}
V {} V {}
S {} S {}
E {} E {}
@ -22,3 +22,5 @@ T {@name} -26.25 -5 0 0 0.2 0.2 {}
T {@symname} -26.25 35 0 0 0.2 0.2 {} T {@symname} -26.25 35 0 0 0.2 0.2 {}
T {@WP\\/@LLP\\/@m} -16.25 -25 0 0 0.2 0.2 {} T {@WP\\/@LLP\\/@m} -16.25 -25 0 0 0.2 0.2 {}
T {@WN\\/@LLN\\/@m} -16.25 15 0 0 0.2 0.2 {} T {@WN\\/@LLN\\/@m} -16.25 15 0 0 0.2 0.2 {}
T {@#Z:net_name} 25 7.5 0 0 0.15 0.15 {layer=15}
T {@#A:net_name} -35 7.5 0 1 0.15 0.15 {layer=15}