Merge branch 'StefanSchippers:master' into master
This commit is contained in:
commit
eee26c9f3e
|
|
@ -642,8 +642,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> copy_hierarchy to from</kbd></li><pre>
|
||||
Copy hierarchy info from tab/window "from" to tab/window "to"
|
||||
Example: xschem copy_hierarchy .drw .x1.drw </pre>
|
||||
<li><kbd> copy_objects [deltax deltay [rot flip]]</kbd></li><pre>
|
||||
if deltax and deltay (and optionally rot and flip) are given copy selection
|
||||
<li><kbd> copy_objects [dx dy] [kissing] [stretch]</kbd></li><pre>
|
||||
if kissing is given add nets to pins that touch other instances or nets
|
||||
if stretch is given stretch connected nets to follow instace pins
|
||||
if dx and dy are given copy selection
|
||||
to specified offset, otherwise start a GUI copy operation </pre>
|
||||
<li><kbd> count_items string separator quoting_chars</kbd></li><pre>
|
||||
Debug command </pre>
|
||||
|
|
|
|||
147
src/callback.c
147
src/callback.c
|
|
@ -1347,20 +1347,20 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* del == 0 : delete and draw
|
||||
* del == 1 : delete
|
||||
* del == 2 : draw */
|
||||
void draw_crosshair(int del)
|
||||
/* what == 0 : delete and draw
|
||||
* what == 1 : delete
|
||||
* what == 2 : draw */
|
||||
void draw_crosshair(int what)
|
||||
{
|
||||
int sdw, sdp;
|
||||
dbg(1, "draw_crosshair(): del=%d\n", del);
|
||||
dbg(1, "draw_crosshair(): what=%d\n", what);
|
||||
sdw = xctx->draw_window;
|
||||
sdp = xctx->draw_pixmap;
|
||||
|
||||
if(!xctx->mouse_inside) return;
|
||||
xctx->draw_pixmap = 0;
|
||||
xctx->draw_window = 1;
|
||||
if(del != 2) {
|
||||
if(what != 2) {
|
||||
if(fix_broken_tiled_fill || !_unix) {
|
||||
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
|
||||
0, (int)Y_TO_SCREEN(xctx->prev_crossy) - 2 * INT_WIDTH(xctx->lw),
|
||||
|
|
@ -1378,7 +1378,7 @@ void draw_crosshair(int del)
|
|||
xctx->prev_crossx, Y_TO_XSCHEM(xctx->areay2));
|
||||
}
|
||||
}
|
||||
if(del != 1) {
|
||||
if(what != 1) {
|
||||
drawline(xctx->crosshair_layer, NOW,X_TO_XSCHEM( xctx->areax1), xctx->mousey_snap,
|
||||
X_TO_XSCHEM(xctx->areax2), xctx->mousey_snap, 3, NULL);
|
||||
drawline(xctx->crosshair_layer, NOW, xctx->mousex_snap, Y_TO_XSCHEM(xctx->areay1),
|
||||
|
|
@ -1475,7 +1475,7 @@ static int end_place_move_copy_zoom()
|
|||
|
||||
static int check_menu_start_commands(double c_snap)
|
||||
{
|
||||
dbg(1, "check_menu_start_commands(): ui_state=%d, ui_state2=%d last_command=%d\n",
|
||||
dbg(1, "check_menu_start_commands(): ui_state=%x, ui_state2=%x last_command=%d\n",
|
||||
xctx->ui_state, xctx->ui_state2, xctx->last_command);
|
||||
|
||||
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) {
|
||||
|
|
@ -1497,6 +1497,13 @@ static int check_menu_start_commands(double c_snap)
|
|||
xctx->ui_state &=~MENUSTART;
|
||||
return 1;
|
||||
}
|
||||
else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTCOPY)) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
copy_objects(START);
|
||||
xctx->ui_state &=~MENUSTART;
|
||||
return 1;
|
||||
}
|
||||
else if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRE)) {
|
||||
int prev_state = xctx->ui_state;
|
||||
if(xctx->semaphore >= 2) return 0;
|
||||
|
|
@ -2184,6 +2191,24 @@ static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key
|
|||
}
|
||||
#endif
|
||||
|
||||
static void snapped_wire(double c_snap)
|
||||
{
|
||||
double x, y;
|
||||
if(!(xctx->ui_state & STARTWIRE)){
|
||||
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
||||
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
|
||||
xctx->my_double_save = my_round(y / c_snap) * c_snap;
|
||||
new_wire(PLACE, x, y);
|
||||
new_wire(RUBBER, xctx->mousex_snap,xctx->mousey_snap);
|
||||
}
|
||||
else {
|
||||
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
||||
new_wire(RUBBER, x, y);
|
||||
new_wire(PLACE|END, x, y);
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
}
|
||||
}
|
||||
|
||||
/* main window callback */
|
||||
/* mx and my are set to the mouse coord. relative to window */
|
||||
|
|
@ -2728,21 +2753,8 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
break;
|
||||
}
|
||||
if(key== 'W' /* && !xctx->ui_state */ && rstate == 0) { /* create wire snapping to closest instance pin */
|
||||
double x, y;
|
||||
if(xctx->semaphore >= 2) break;
|
||||
if(!(xctx->ui_state & STARTWIRE)){
|
||||
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
||||
xctx->mx_double_save = my_round(x / c_snap) * c_snap;
|
||||
xctx->my_double_save = my_round(y / c_snap) * c_snap;
|
||||
new_wire(PLACE, x, y);
|
||||
}
|
||||
else {
|
||||
find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y);
|
||||
new_wire(RUBBER, x, y);
|
||||
new_wire(PLACE|END, x, y);
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
}
|
||||
snapped_wire(c_snap);
|
||||
break;
|
||||
}
|
||||
if(key == 'w' /* && !xctx->ui_state */ && rstate==0) /* place wire. */
|
||||
|
|
@ -3625,64 +3637,93 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
}
|
||||
break;
|
||||
}
|
||||
if(key=='m' && rstate==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
||||
/* Move selection */
|
||||
if(key=='m' && rstate==0 && !(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
if(waves_selected(event, key, state, button)) {
|
||||
waves_callback(event, mx, my, key, button, aux, state);
|
||||
break;
|
||||
}
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
if(tclgetboolvar("enable_stretch"))
|
||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
move_objects(START,0,0,0);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTMOVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Move selection adding wires to moved pins */
|
||||
if(((key == 'M' && rstate == 0) || (key == 'm' && EQUAL_MODMASK)) &&
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
xctx->connect_by_kissing = 2; /* 2 will be used to reset var to 0 at end of move */
|
||||
/* select_attached_nets(); */ /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
/* select_attached_nets(); */ /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTMOVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* move selection stretching attached nets */
|
||||
if(key=='m' && rstate == ControlMask &&
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
if(waves_selected(event, key, state, button)) {
|
||||
waves_callback(event, mx, my, key, button, aux, state);
|
||||
break;
|
||||
}
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
if(!tclgetboolvar("enable_stretch"))
|
||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||
move_objects(START,0,0,0);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
move_objects(START,0,0,0);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTMOVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* move selection, stretch attached nets, create new wires on pin-to-moved-pin connections */
|
||||
if(key=='M' && state == (ControlMask | ShiftMask) &&
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY))) /* move selection */
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
if(!tclgetboolvar("enable_stretch"))
|
||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||
xctx->connect_by_kissing = 2; /* 2 will be used to reset var to 0 at end of move */
|
||||
move_objects(START,0,0,0);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
move_objects(START,0,0,0);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTMOVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(key=='c' && EQUAL_MODMASK && /* duplicate selection */
|
||||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
if(xctx->semaphore >= 2) break;
|
||||
xctx->connect_by_kissing = 2; /* 2 will be used to reset var to 0 at end of move */
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
copy_objects(START);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
copy_objects(START);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTCOPY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -3690,9 +3731,14 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
!(xctx->ui_state & (STARTMOVE | STARTCOPY)))
|
||||
{
|
||||
if(xctx->semaphore >= 2) break;
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
copy_objects(START);
|
||||
if(infix_interface) {
|
||||
xctx->mx_double_save=xctx->mousex_snap;
|
||||
xctx->my_double_save=xctx->mousey_snap;
|
||||
copy_objects(START);
|
||||
} else {
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTCOPY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(key=='n' && rstate == ControlMask) /* clear schematic */
|
||||
|
|
@ -4000,6 +4046,11 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
|
||||
/* Mouse wheel events */
|
||||
else if(handle_mouse_wheel(event, mx, my, key, button, aux, state)) break;
|
||||
|
||||
/* terminate wire placement in snap mode */
|
||||
else if(button==Button1 && (state & ShiftMask) && (xctx->ui_state & STARTWIRE) ) {
|
||||
snapped_wire(c_snap);
|
||||
}
|
||||
/* Alt - Button1 click to unselect */
|
||||
else if(button==Button1 && (SET_MODMASK) ) {
|
||||
xctx->last_command = 0;
|
||||
|
|
@ -4039,7 +4090,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
if(xctx->last_command == STARTWIRE) start_wire(xctx->mousex_snap, xctx->mousey_snap);
|
||||
break;
|
||||
}
|
||||
/* handle all object insertions started from Tools menu */
|
||||
/* handle all object insertions started from Tools/Edit menu */
|
||||
if(check_menu_start_commands(c_snap)) break;
|
||||
/* complete the STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
|
||||
if(end_place_move_copy_zoom()) break;
|
||||
|
|
|
|||
|
|
@ -683,29 +683,37 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
/* copy_objects [deltax deltay [rot flip]]
|
||||
* if deltax and deltay (and optionally rot and flip) are given copy selection
|
||||
/* copy_objects [dx dy] [kissing] [stretch]
|
||||
* if kissing is given add nets to pins that touch other instances or nets
|
||||
* if stretch is given stretch connected nets to follow instace pins
|
||||
* if dx and dy are given copy selection
|
||||
* to specified offset, otherwise start a GUI copy operation */
|
||||
else if(!strcmp(argv[1], "copy_objects"))
|
||||
{
|
||||
int nparam = 0;
|
||||
int kissing= 0;
|
||||
int stretch = 0;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
if(argc > 3) {
|
||||
if(argc > 2) {
|
||||
int i;
|
||||
for(i = 2; i < argc; i++) {
|
||||
if(!strcmp(argv[i], "kissing")) {kissing = 1; nparam++;}
|
||||
if(!strcmp(argv[i], "stretch")) {stretch = 1; nparam++;}
|
||||
}
|
||||
}
|
||||
if(stretch) select_attached_nets();
|
||||
if(kissing) xctx->connect_by_kissing = 2;
|
||||
if(argc > 3 + nparam) {
|
||||
copy_objects(START);
|
||||
xctx->deltax = atof(argv[2]);
|
||||
xctx->deltay = atof(argv[3]);
|
||||
if(argc > 4) {
|
||||
xctx->move_rot = (short int)atoi(argv[4]);
|
||||
}
|
||||
if(argc > 5) {
|
||||
xctx->move_flip = (short int)atoi(argv[5]);
|
||||
}
|
||||
copy_objects(END);
|
||||
} else {
|
||||
copy_objects(START);
|
||||
xctx->ui_state |= MENUSTART;
|
||||
xctx->ui_state2 = MENUSTARTCOPY;
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* count_items string separator quoting_chars
|
||||
Debug command */
|
||||
else if(!strcmp(argv[1], "count_items"))
|
||||
|
|
|
|||
19
src/token.c
19
src/token.c
|
|
@ -3633,6 +3633,7 @@ static char *get_pin_attr(const char *token, int inst, int engineering)
|
|||
const char *str_ptr=NULL;
|
||||
int multip;
|
||||
size_t tmp;
|
||||
prepare_netlist_structs(0);
|
||||
str_ptr = net_name(inst,n, &multip, 0, 1);
|
||||
tmp = strlen(str_ptr) +100 ; /* always make room for some extra chars
|
||||
* so 1-char writes to result do not need reallocs */
|
||||
|
|
@ -4295,13 +4296,14 @@ const char *translate(int inst, const char* s)
|
|||
if(!error) {
|
||||
char *iprefix = modelparam == 0 ? "i(" : modelparam == 1 ? "" : "v(";
|
||||
char *ipostfix = modelparam == 1 ? "" : ")";
|
||||
int prefix;
|
||||
my_strdup2(_ALLOC_ID_, &dev, instname);
|
||||
strtolower(dev);
|
||||
prefix=dev[0];
|
||||
len = strlen(path) + strlen(dev) + 40; /* some extra chars for i(..) wrapper */
|
||||
dbg(1, "token=%s, dev=%s param=%s\n", token, dev, param ? param : "<NULL>");
|
||||
fqdev = my_malloc(_ALLOC_ID_, len);
|
||||
if(!sim_is_xyce) {
|
||||
int prefix=dev[0];
|
||||
int vsource = (prefix == 'v') || (prefix == 'e');
|
||||
if(path[0]) {
|
||||
if(vsource) {
|
||||
|
|
@ -4340,6 +4342,21 @@ const char *translate(int inst, const char* s)
|
|||
if(idx >= 0) {
|
||||
val = xctx->raw->cursor_b_val[idx];
|
||||
}
|
||||
/* special handling for resistors that are converted to b sources:
|
||||
* i(@r.x4.r1[i]) --> i(@b.x4.br1[i])
|
||||
*/
|
||||
if(idx < 0 && !strncmp(fqdev, "i(@r", 4)) {
|
||||
if(path[0]) {
|
||||
my_snprintf(fqdev, len, "i(@b.%sb%s[i])", path, dev);
|
||||
} else {
|
||||
my_snprintf(fqdev, len, "i(@b%s[i])", dev);
|
||||
}
|
||||
dbg(1, "fqdev=%s\n", fqdev);
|
||||
idx = get_raw_index(fqdev, NULL);
|
||||
if(idx >= 0) {
|
||||
val = xctx->raw->cursor_b_val[idx];
|
||||
}
|
||||
}
|
||||
if(idx < 0) {
|
||||
valstr = "-";
|
||||
xctx->tok_size = 1;
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ extern char win_temp_dir[PATH_MAX];
|
|||
#define MENUSTARTMOVE 256U
|
||||
#define MENUSTARTWIRECUT 512U
|
||||
#define MENUSTARTWIRECUT2 1024U /* do not align cut point to snap */
|
||||
#define MENUSTARTCOPY 2048U
|
||||
|
||||
#define WIRE 1 /* types of defined objects */
|
||||
#define xRECT 2
|
||||
|
|
@ -1394,7 +1395,7 @@ extern int select_dangling_nets(void);
|
|||
extern void tclmainloop(void);
|
||||
extern int Tcl_AppInit(Tcl_Interp *interp);
|
||||
extern void abort_operation(void);
|
||||
extern void draw_crosshair(int del);
|
||||
extern void draw_crosshair(int what);
|
||||
extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
|
||||
extern int callback(const char *winpath, int event, int mx, int my, KeySym key,
|
||||
int button, int aux, int state);
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ L 4 -15 -25 -15 -15 {}
|
|||
B 5 -2.5 -32.5 2.5 -27.5 {name=p dir=inout}
|
||||
B 5 -2.5 27.5 2.5 32.5 {name=m dir=inout}
|
||||
A 4 0 0 15 270 360 {}
|
||||
T {@name} 20 -17.5 0 0 0.2 0.2 {}
|
||||
T {@VAR
|
||||
@FUNC} 20 0 0 0 0.2 0.2 {}
|
||||
T {@#0:net_name} 5 -42.5 0 0 0.15 0.15 {layer=15 hide=instance}
|
||||
T {@#1:net_name} 5 32.5 0 0 0.15 0.15 {layer=15 hide=instance}
|
||||
T {@spice_get_current} -12.5 7.5 0 1 0.2 0.2 {layer=17}
|
||||
T {@name} 20 -27.5 0 0 0.2 0.2 {}
|
||||
T {@VAR = @FUNC
|
||||
m=@m} 20 -10 0 0 0.2 0.2 {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
v {xschem version=3.4.6 file_version=1.2}
|
||||
G {}
|
||||
K {type=stop
|
||||
format="
|
||||
.control
|
||||
stop when time @timecond when @@node @nodecond
|
||||
.endc"
|
||||
template="name=s1 timecond=\\"> 1u\\" nodecond=\\"< 3\\""}
|
||||
V {}
|
||||
S {}
|
||||
E {}
|
||||
L 4 -80 0 -60 0 {}
|
||||
L 4 -60 -20 -60 20 {}
|
||||
L 4 -60 -20 60 -20 {}
|
||||
L 4 60 -20 60 20 {}
|
||||
L 4 -60 20 60 20 {}
|
||||
B 5 -82.5 -2.5 -77.5 2.5 {name=node
|
||||
dir=in}
|
||||
T {STOP} -60 -35 0 0 0.2 0.2 {}
|
||||
T {@@node @nodecond} -57.5 -15 0 0 0.2 0.2 {}
|
||||
T {time @timecond} -47.5 5 0 0 0.2 0.2 {}
|
||||
T {@name} 60 -35 0 1 0.2 0.2 {}
|
||||
Loading…
Reference in New Issue