Merge pull request #11 from TheSUPERCD/upstream-un-refactored

Merge commits made before callback.c refactor
This commit is contained in:
Chayan Deb 2025-02-19 15:49:16 +05:30 committed by GitHub
commit 7cd980cf42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 1642 additions and 1216 deletions

View File

@ -156,7 +156,9 @@ ctrl 'c' Save to clipboard
shift 'C' Start arc placement
shift+ctrl 'C' Start circle placement
alt 'C' Toggle dim/brite background with rest of layers
shift 'D' Delete files
ctrl 'd' Delete files
- 'd' Unselect selected object under the mouse pointer
shift 'D' Unselect selected objects by area
ctrl 'e' Back to parent schematic
- 'e' Descend to schematic
alt 'e' Edit selected schematic in a new window

View File

@ -5,7 +5,7 @@ put /local/src {
select.c font.c editprop.c save.c paste.c token.c psprint.c node_hash.c
hilight.c options.c vhdl_netlist.c svgdraw.c spice_netlist.c
tedax_netlist.c verilog_netlist.c parselabel.c expandlabel.c
in_memory_undo.c cairo_jpg.c
eval_expr.c in_memory_undo.c cairo_jpg.c
}
# list all files that need to be installed in "$(XSHAREDIR)"
@ -49,12 +49,15 @@ parselabel.c: parselabel.l expandlabel.h
expandlabel.c expandlabel.h: expandlabel.y
bison -d -o expandlabel.c expandlabel.y
eval_expr.c: eval_expr.y
bison -o eval_expr.c eval_expr.y
parselabel.o: expandlabel.h
$(OBJ): xschem.h ../config.h Makefile
clean: FORCE
rm -rf rawtovcd xschem *.o expandlabel.[ch] parselabel.c
rm -rf rawtovcd xschem *.o eval_expr.c expandlabel.[ch] parselabel.c
# Explicit rule for each object:
@]

View File

@ -1482,7 +1482,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR");
my_strncpy(name1, tclresult(), S(name1));
} else {
my_strncpy(name1, symbol_name, S(name1));
my_strncpy(name1, trim_chars(symbol_name, " \t\n"), S(name1));
}
dbg(1, "place_symbol(): 1: name1=%s first_call=%d\n",name1, first_call);
@ -1495,7 +1495,9 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
tclvareval("is_xschem_file {", name1, "}", NULL);
if(!strcmp(tclresult(), "GENERATOR")) {
my_snprintf(name, S(name), "%s()", name1);
size_t len = strlen(name1);
if( name1[len - 1] != ')') my_snprintf(name, S(name), "%s()", name1);
else my_strncpy(name, name1, S(name));
} else {
my_strncpy(name, name1, S(name));
}
@ -1983,34 +1985,34 @@ void get_additional_symbols(int what)
char *default_schematic = NULL;
char *sch = NULL;
char symbol_base_sch[PATH_MAX] = "";
size_t schematic_token_found = 0;
if(xctx->inst[i].ptr < 0) continue;
dbg(1, "get_additional_symbols(): inst=%d (%s) sch=%s\n",i, xctx->inst[i].name, sch);
/* copy instance based *_sym_def attributes to symbol */
my_strdup(_ALLOC_ID_, &spice_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"spice_sym_def",6));
my_strdup(_ALLOC_ID_, &verilog_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"verilog_sym_def",4));
my_strdup(_ALLOC_ID_, &vhdl_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"vhdl_sym_def",4));
dbg(1, "schematic=%s\n", get_tok_value(xctx->inst[i].prop_ptr,"schematic",6));
dbg(1, "get_additional_symbols(): schematic=%s\n", get_tok_value(xctx->inst[i].prop_ptr,"schematic",6));
/* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */
my_strdup2(_ALLOC_ID_, &sch,
translate3(get_tok_value(xctx->inst[i].prop_ptr,"schematic", 6), 1,
xctx->inst[i].prop_ptr, NULL, NULL));
dbg(1, "sch=%s\n", sch);
my_strdup2(_ALLOC_ID_, &sch, get_tok_value(xctx->inst[i].prop_ptr,"schematic", 6));
schematic_token_found = xctx->tok_size;
my_strdup2(_ALLOC_ID_, &sch, translate3(sch, 1, xctx->inst[i].prop_ptr, NULL, NULL, NULL));
dbg(1, "get_additional_symbols(): sch=%s tok_size= %ld\n", sch, xctx->tok_size);
my_strdup2(_ALLOC_ID_, &sch, tcl_hook2(
str_replace(sch, "@symname", get_cell(xctx->inst[i].name, 0), '\\', -1)));
dbg(1, "get_additional_symbols(): inst=%d sch=%s\n",i, sch);
/* schematic does not exist */
if(sch[0] && stat(abs_sym_path(sch, ""), &buf)) {
my_snprintf(symbol_base_sch, PATH_MAX, "%s.sch", get_cell(xctx->sym[xctx->inst[i].ptr].name, 9999));
dbg(1, "get_additional_symbols(): schematic not existing\n");
dbg(1, "using: %s\n", symbol_base_sch);
}
if(xctx->tok_size && sch[0]) { /* "schematic" token exists and a schematic is specified */
if(schematic_token_found && sch[0]) { /* "schematic" token exists and a schematic is specified */
int j;
char *sym = NULL;
char *templ = NULL;
char *symname_attr = NULL;
int ignore_schematic = 0;
xSymbol *symptr = xctx->inst[i].ptr + xctx->sym;
@ -2030,15 +2032,13 @@ void get_additional_symbols(int what)
my_strdup2(_ALLOC_ID_, &sym, add_ext(rel_sym_path(sch), ".sym"));
}
my_strdup2(_ALLOC_ID_, &templ, get_tok_value(symptr->prop_ptr, "template", 0));
my_mstrcat(_ALLOC_ID_, &symname_attr, "symname=", get_cell(sym, 0), NULL);
my_mstrcat(_ALLOC_ID_, &symname_attr, " symref=", get_sym_name(i, 9999, 1, 1), NULL);
my_strdup(_ALLOC_ID_, &spice_sym_def,
translate3(spice_sym_def, 1, xctx->inst[i].prop_ptr,
templ,
symname_attr));
symptr->templ,
symname_attr, NULL));
dbg(1, "get_additional_symbols(): spice_sym_def=%s\n", spice_sym_def);
my_free(_ALLOC_ID_, &templ);
my_free(_ALLOC_ID_, &symname_attr);
/* if instance symbol has default_schematic set to ignore copy the symbol anyway, since
* the base symbol will not be netlisted by *_block_netlist() */
@ -2131,7 +2131,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback)
/* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */
if(inst >=0 ) {
my_strdup(_ALLOC_ID_, &str_tmp, translate3(get_tok_value(xctx->inst[inst].prop_ptr,"schematic", 6),
1, xctx->inst[inst].prop_ptr, NULL, NULL));
1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL));
}
if(!str_tmp) my_strdup2(_ALLOC_ID_, &str_tmp, get_tok_value(sym->prop_ptr, "schematic", 6));
if(str_tmp[0]) { /* schematic attribute in symbol or instance was given */
@ -2395,8 +2395,7 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title)
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].prop_ptr,
xctx->inst[n].prop_ptr);
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ,
get_tok_value(xctx->sym[xctx->inst[n].ptr].prop_ptr, "template", 0));
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ, xctx->sym[xctx->inst[n].ptr].templ);
dbg(1,"descend_schematic(): inst_number=%d\n", inst_number);
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], find_nth(str, ",", "", 0, inst_number));
@ -2593,6 +2592,7 @@ void calc_drawing_bbox(xRect *boundbox, int selected)
#endif
char *estr = NULL;
xctx->show_hidden_texts = tclgetboolvar("show_hidden_texts");
boundbox->x1=-100;
boundbox->x2=100;
boundbox->y1=-100;
@ -2689,6 +2689,8 @@ void calc_drawing_bbox(xRect *boundbox, int selected)
int no_of_lines;
double longest_line;
if(selected == 1 && !xctx->text[i].sel) continue;
if(!xctx->show_hidden_texts && xctx->text[i].flags & (HIDE_TEXT | HIDE_TEXT_INSTANTIATED)) continue;
#if HAS_CAIRO==1
customfont = set_text_custom_font(&xctx->text[i]);
#endif
@ -2843,6 +2845,7 @@ void set_viewport_size(int w, int h, double lw)
void save_restore_zoom(int save, Zoom_info *zi)
{
if(save) {
dbg(1, "save_restore_zoom: save width= %d, height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
zi->savew = xctx->xrect[0].width;
zi->saveh = xctx->xrect[0].height;
zi->savelw = xctx->lw;
@ -2854,6 +2857,7 @@ void save_restore_zoom(int save, Zoom_info *zi)
xctx->xrect[0].y = 0;
xctx->xrect[0].width = (unsigned short)zi->savew;
xctx->xrect[0].height = (unsigned short)zi->saveh;
dbg(1, "save_restore_zoom: restore width= %d, height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
xctx->areax2 = zi->savew+2*INT_WIDTH(zi->savelw);
xctx->areay2 = zi->saveh+2*INT_WIDTH(zi->savelw);
xctx->areax1 = -2*INT_WIDTH(zi->savelw);

View File

@ -441,10 +441,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
/* determine if mouse pointer is below xaxis or left of yaxis in some graph */
setup_graph_data(i, 0, gr);
/* check if user clicked on a wave label -> draw wave in bold */
if(event == ButtonPress && button == Button3 &&
edit_wave_attributes(2, i, gr)) {
@ -908,7 +904,10 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
/* loop: after having operated on the master graph do the others */
for(i=0; i< xctx->rects[GRIDLAYER]; ++i) {
int same_sim_type = 0;
char *curr_sim_type = NULL;
r = &xctx->rect[GRIDLAYER][i];
my_strdup2(_ALLOC_ID_, &curr_sim_type, get_tok_value(r->prop_ptr, "sim_type", 0));
need_redraw = 0;
if( !(r->flags & 1) ) continue; /* 1: graph; 3: graph_unlocked */
gr->gx1 = gr->master_gx1;
@ -918,6 +917,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(gr->dataset >= 0 /* && gr->dataset < xctx->raw->datasets */) dataset =gr->dataset;
else dataset = -1;
if(!strcmp(curr_sim_type,
get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr, "sim_type", 0))) {
same_sim_type = 1;
}
my_free(_ALLOC_ID_, &curr_sim_type);
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom &&
!(xctx->graph_flags & (16 | 32 | 512 | 1024))) {
double delta;
@ -955,7 +960,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
delta = gr->gw;
delta_threshold = 0.01;
/* selected or locked or master */
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if( r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
dbg(1, "moving waves: %d\n", i);
if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(gr->cx * delta) * delta_threshold) {
xx1 = gr->gx1 + (xctx->mx_double_save - xctx->mousex_snap) / gr->cx;
@ -994,7 +999,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
/* horizontal move of waveforms with mouse wheel */
else {
/* selected or locked or master */
if( r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if( r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 - delta * delta_threshold;
@ -1031,7 +1036,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
/* horizontal move of waveforms with mouse wheel */
else {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 + delta * delta_threshold;
@ -1072,7 +1077,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
} else {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
double var = 0.2 * gr->gw;
xx2 = gr->gx2 + var * (1 - zoom_m);
xx1 = gr->gx1 - var * zoom_m;
@ -1111,7 +1116,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
}
} else {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
double var = 0.2 * gr->gw;
xx2 = gr->gx2 - var * (1 - zoom_m);
xx1 = gr->gx1 + var * zoom_m;
@ -1190,13 +1195,15 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
need_redraw = 1;
}
} else {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 - delta * delta_threshold;
xx2 = gr->gx2 - delta * delta_threshold;
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x1", dtoa(xx1)));
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x2", dtoa(xx2)));
need_redraw = 1;
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 - delta * delta_threshold;
xx2 = gr->gx2 - delta * delta_threshold;
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x1", dtoa(xx1)));
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x2", dtoa(xx2)));
need_redraw = 1;
}
}
}
else if(event == KeyPress && key == XK_Right) {
@ -1215,13 +1222,15 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
need_redraw = 1;
}
} else {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 + delta * delta_threshold;
xx2 = gr->gx2 + delta * delta_threshold;
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x1", dtoa(xx1)));
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x2", dtoa(xx2)));
need_redraw = 1;
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
delta = gr->gw;
delta_threshold = 0.05;
xx1 = gr->gx1 + delta * delta_threshold;
xx2 = gr->gx2 + delta * delta_threshold;
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x1", dtoa(xx1)));
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x2", dtoa(xx2)));
need_redraw = 1;
}
}
}
else if(event == KeyPress && key == XK_Down) {
@ -1258,7 +1267,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
} /* graph_master */
} else { /* not graph_left, full X zoom*/
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
need_redraw = graph_fullxzoom(i, gr, dataset);
}
}
@ -1268,7 +1277,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
else if(event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
if(xctx->raw && xctx->raw->values) {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
/* xx1 and xx2 calculated for master graph above */
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "x1", dtoa(xx1)));
@ -1288,7 +1297,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
else if(button == Button3 && (xctx->ui_state & GRAPHPAN) &&
!xctx->graph_left && !xctx->graph_top) {
/* selected or locked or master */
if(r->sel || !(r->flags & 2) || i == xctx->graph_master) {
if(r->sel || (same_sim_type && !(r->flags & 2)) || i == xctx->graph_master) {
if(xctx->mx_double_save != xctx->mousex_snap) {
clear_graphpan_at_end = 1;
@ -1686,6 +1695,16 @@ static int end_place_move_copy_zoom()
return 0;
}
static void unselect_at_mouse_pos(int mx, int my)
{
xctx->last_command = 0;
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
select_object(xctx->mousex, xctx->mousey, 0, 0, NULL);
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
}
void snapped_wire(double c_snap)
{
double x, y;
@ -1706,11 +1725,22 @@ void snapped_wire(double c_snap)
}
}
static int check_menu_start_commands(double c_snap)
static int check_menu_start_commands(double c_snap, int mx, int my)
{
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 & MENUSTARTDESEL) ) {
if(xctx->ui_state & DESEL_CLICK) {
unselect_at_mouse_pos(mx, my);
} else { /* unselect by area */
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex;
xctx->my_double_save=xctx->mousey;
xctx->ui_state |= DESEL_AREA;
}
return 1;
}
if((xctx->ui_state & MENUSTART) && (xctx->ui_state2 & MENUSTARTWIRECUT)) {
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1);
return 1;
@ -2274,7 +2304,7 @@ static void end_shape_point_edit(double c_snap)
}
#if defined(__unix__) && HAS_CAIRO==1
static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key,
static int grabscreen(const char *win_path, int event, int mx, int my, KeySym key,
int button, int aux, int state)
{
static int grab_state = 0;
@ -2401,8 +2431,8 @@ static int grabscreen(const char *winpath, int event, int mx, int my, KeySym key
/* main window callback */
/* mx and my are set to the mouse coord. relative to window */
/* winpath: set to .drw or sub windows .x1.drw, .x2.drw, ... */
int callback(const char *winpath, int event, int mx, int my, KeySym key,
/* win_path: set to .drw or sub windows .x1.drw, .x2.drw, ... */
int callback(const char *win_path, int event, int mx, int my, KeySym key,
int button, int aux, int state)
{
char str[PATH_MAX + 100];
@ -2431,9 +2461,9 @@ int rstate; /* (reduced state, without ShiftMask) */
* on such events */
if(fix_mouse_coord) {
if(event == KeyPress || event == KeyRelease) {
tclvareval("getmousex ", winpath, NULL);
tclvareval("getmousex ", win_path, NULL);
mx = atoi(tclresult());
tclvareval("getmousey ", winpath, NULL);
tclvareval("getmousey ", win_path, NULL);
my = atoi(tclresult());
dbg(1, "mx = %d my=%d\n", mx, my);
}
@ -2474,21 +2504,21 @@ int rstate; /* (reduced state, without ShiftMask) */
#if 0
/* exclude Motion and Expose events */
if(event!=6 /* && event!=12 */) {
dbg(0, "callback(): state=%d event=%d, winpath=%s, old_winpath=%s, semaphore=%d\n",
state, event, winpath, old_winpath, xctx->semaphore+1);
dbg(0, "callback(): state=%d event=%d, win_path=%s, old_win_path=%s, semaphore=%d\n",
state, event, win_path, old_win_path, xctx->semaphore+1);
}
#endif
/* Schematic window context switch */
redraw_only =0;
if(strcmp(old_winpath, winpath) ) {
if(strcmp(old_win_path, win_path) ) {
if( xctx->semaphore >= 1 || event == Expose) {
dbg(1, "callback(): semaphore >=2 (or Expose) switching window context: %s --> %s\n", old_winpath, winpath);
dbg(1, "callback(): semaphore >=2 (or Expose) switching window context: %s --> %s\n", old_win_path, win_path);
redraw_only = 1;
new_schematic("switch_no_tcl_ctx", winpath, "", 1);
new_schematic("switch_no_tcl_ctx", win_path, "", 1);
} else {
dbg(1, "callback(): switching window context: %s --> %s, semaphore=%d\n", old_winpath, winpath, xctx->semaphore);
new_schematic("switch", winpath, "", 1);
dbg(1, "callback(): switching window context: %s --> %s, semaphore=%d\n", old_win_path, win_path, xctx->semaphore);
new_schematic("switch", win_path, "", 1);
}
tclvareval("housekeeping_ctx", NULL);
}
@ -2533,7 +2563,7 @@ int rstate; /* (reduced state, without ShiftMask) */
#if defined(__unix__) && HAS_CAIRO==1
if(xctx->ui_state & GRABSCREEN) {
grabscreen(winpath, event, mx, my, key, button, aux, state);
grabscreen(win_path, event, mx, my, key, button, aux, state);
} else
#endif
switch(event)
@ -2577,7 +2607,7 @@ int rstate; /* (reduced state, without ShiftMask) */
break;
case Expose:
dbg(1, "callback: Expose, winpath=%s, %dx%d+%d+%d\n", winpath, button, aux, mx, my);
dbg(1, "callback: Expose, win_path=%s, %dx%d+%d+%d\n", win_path, button, aux, mx, my);
MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], mx,my,button,aux,mx,my);
{
XRectangle xr[1];
@ -2639,7 +2669,7 @@ int rstate; /* (reduced state, without ShiftMask) */
/* determine direction of a rectangle selection (or unselection with ALT key) */
if(xctx->ui_state & STARTSELECT && !(xctx->ui_state & (PLACE_SYMBOL | STARTPAN | PLACE_TEXT)) ) {
/* Unselect by area : determine direction */
if( (state & Button1Mask) && SET_MODMASK) {
if( ((state & Button1Mask) && SET_MODMASK) || (xctx->ui_state & DESEL_AREA)) {
if(mx >= xctx->mx_save) xctx->nl_dir = 0;
else xctx->nl_dir = 1;
select_rect(enable_stretch, RUBBER,0);
@ -2692,12 +2722,13 @@ int rstate; /* (reduced state, without ShiftMask) */
}
}
/* Unselect by area */
if((state & Button1Mask) && (SET_MODMASK) && !(state & ShiftMask) &&
!(xctx->ui_state & STARTPAN) && !xctx->shape_point_selected &&
if( (((state & Button1Mask) && SET_MODMASK) || (xctx->ui_state & DESEL_AREA)) &&
!(state & ShiftMask) &&
!(xctx->ui_state & STARTPAN) &&
!xctx->shape_point_selected &&
!(xctx->ui_state & STARTSELECT) &&
!(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT))) { /* unselect area */
if( !(xctx->ui_state & STARTSELECT)) {
select_rect(enable_stretch, START,0);
}
select_rect(enable_stretch, START,0);
}
/* Select by area. Shift pressed */
else if((state&Button1Mask) && (state & ShiftMask) && !(xctx->ui_state & STARTWIRE) &&
@ -3081,10 +3112,10 @@ int rstate; /* (reduced state, without ShiftMask) */
tclvareval("xschem set rectcolor ", n, NULL);
if(has_x) {
if(!strcmp(winpath, ".drw")) {
if(!strcmp(win_path, ".drw")) {
tclvareval("reconfigure_layers_button {}", NULL);
} else {
tclvareval("reconfigure_layers_button [winfo parent ", winpath, "]", NULL);
tclvareval("reconfigure_layers_button [winfo parent ", win_path, "]", NULL);
}
}
dbg(1, "callback(): new color: %d\n",xctx->color_index[xctx->rectcolor]);
@ -3826,8 +3857,8 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='\\' && state==0) /* fullscreen */
{
dbg(1, "callback(): toggle fullscreen, winpath=%s\n", winpath);
toggle_fullscreen(winpath);
dbg(1, "callback(): toggle fullscreen, win_path=%s\n", win_path);
toggle_fullscreen(win_path);
break;
}
if(key=='f' && EQUAL_MODMASK) /* flip objects around their anchor points 20171208 */
@ -3988,43 +4019,8 @@ int rstate; /* (reduced state, without ShiftMask) */
}
if(key=='n' && rstate==0) /* hierarchical netlist */
{
int err = 0;
yyparse_error = 0;
if(xctx->semaphore >= 2) break;
unselect_all(1);
if(set_netlist_dir(0, NULL)) {
dbg(1, "callback(): -------------\n");
if(xctx->netlist_type == CAD_SPICE_NETLIST)
err = global_spice_netlist(1, 1);
else if(xctx->netlist_type == CAD_VHDL_NETLIST)
err = global_vhdl_netlist(1, 1);
else if(xctx->netlist_type == CAD_VERILOG_NETLIST)
err = global_verilog_netlist(1, 1);
else if(xctx->netlist_type == CAD_TEDAX_NETLIST)
err = global_tedax_netlist(1, 1);
else
tcleval("tk_messageBox -type ok -parent [xschem get topwindow] "
"-message {Please Set netlisting mode (Options menu)}");
dbg(1, "callback(): -------------\n");
}
else {
if(has_x) tcleval("alert_ {Can not write into the netlist directory. Please check} {}");
else dbg(0, "Can not write into the netlist directory. Please check");
err = 1;
}
if(err) {
if(has_x) {
tclvareval(xctx->top_path, ".menubar entryconfigure Netlist -background red", NULL);
tclvareval("set tctx::", xctx->current_win_path, "_netlist red", NULL);
}
} else {
if(has_x) {
tclvareval(xctx->top_path, ".menubar entryconfigure Netlist -background Green", NULL);
tclvareval("set tctx::", xctx->current_win_path, "_netlist Green", NULL);
}
}
tcleval("xschem netlist -erc");
break;
}
if(key=='N' && rstate == 0) /* current level only netlist */
@ -4153,7 +4149,33 @@ int rstate; /* (reduced state, without ShiftMask) */
draw();
break;
}
if(key=='D' && rstate == 0) /* delete files */
if(key=='d' && rstate == 0) /* unselect object under the mouse */
{
if(infix_interface) {
unselect_at_mouse_pos(mx, my);
} else {
xctx->ui_state |= (MENUSTART | DESEL_CLICK);
xctx->ui_state2 = MENUSTARTDESEL;
}
break;
}
if(key=='D' && rstate == 0) /* unselect by area */
{
if( !(xctx->ui_state & STARTPAN) && !xctx->shape_point_selected &&
!(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT)) && !(xctx->ui_state & STARTSELECT)) {
if(infix_interface) {
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex;
xctx->my_double_save=xctx->mousey;
xctx->ui_state |= DESEL_AREA;
} else {
xctx->ui_state |= MENUSTART;
xctx->ui_state2 = MENUSTARTDESEL;
}
}
break;
}
if(key=='d' && rstate == ControlMask) /* delete files */
{
if(xctx->semaphore >= 2) break;
delete_files();
@ -4294,12 +4316,7 @@ int rstate; /* (reduced state, without ShiftMask) */
}
/* Alt - Button1 click to unselect */
else if(button==Button1 && (SET_MODMASK) ) {
xctx->last_command = 0;
xctx->mx_save = mx; xctx->my_save = my;
xctx->mx_double_save=xctx->mousex_snap;
xctx->my_double_save=xctx->mousey_snap;
select_object(xctx->mousex, xctx->mousey, 0, 0, NULL);
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
unselect_at_mouse_pos(mx, my);
}
/* Middle button press (Button2) will pan the schematic. */
@ -4350,7 +4367,7 @@ int rstate; /* (reduced state, without ShiftMask) */
break;
}
/* handle all object insertions started from Tools/Edit menu */
if(check_menu_start_commands(c_snap)) break;
if(check_menu_start_commands(c_snap, mx, my)) break;
/* complete the pending STARTWIRE, STARTRECT, STARTZOOM, STARTCOPY ... operations */
if(end_place_move_copy_zoom()) break;
@ -4488,6 +4505,7 @@ int rstate; /* (reduced state, without ShiftMask) */
waves_callback(event, mx, my, key, button, aux, state);
break;
}
xctx->ui_state &= ~DESEL_CLICK;
dbg(1, "release: shape_point_selected=%d\n", xctx->shape_point_selected);
/* bring up context menu if no pending operation */
if(state == Button3Mask && xctx->semaphore <2) {
@ -4563,6 +4581,7 @@ int rstate; /* (reduced state, without ShiftMask) */
select_rect(enable_stretch, END,-1);
}
}
xctx->ui_state &= ~DESEL_AREA;
rebuild_selected_array();
my_snprintf(str, S(str), "mouse = %.16g %.16g - selected: %d path: %s",
xctx->mousex_snap, xctx->mousey_snap, xctx->lastsel, xctx->sch_path[xctx->currsch] );
@ -4621,13 +4640,13 @@ int rstate; /* (reduced state, without ShiftMask) */
if(xctx->semaphore > 0) xctx->semaphore--;
if(redraw_only) {
xctx->semaphore--; /* decrement articially incremented semaphore (see above) */
dbg(1, "callback(): semaphore >=2 restoring window context: %s <-- %s\n", old_winpath, winpath);
if(old_winpath[0]) new_schematic("switch_no_tcl_ctx", old_winpath, "", 1);
dbg(1, "callback(): semaphore >=2 restoring window context: %s <-- %s\n", old_win_path, win_path);
if(old_win_path[0]) new_schematic("switch_no_tcl_ctx", old_win_path, "", 1);
}
else
if(strcmp(old_winpath, winpath)) {
if(old_winpath[0]) dbg(1, "callback(): reset old_winpath: %s <- %s\n", old_winpath, winpath);
my_strncpy(old_winpath, winpath, S(old_winpath));
if(strcmp(old_win_path, win_path)) {
if(old_win_path[0]) dbg(1, "callback(): reset old_win_path: %s <- %s\n", old_win_path, win_path);
my_strncpy(old_win_path, win_path, S(old_win_path));
}
return 0;
}

View File

@ -736,7 +736,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot,
dbg(1, "draw_symbol(): drawing string: str=%s prop=%s\n",
txtptr, text.prop_ptr ? text.prop_ptr : "<NULL>");
my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 1, xctx->inst[n].prop_ptr,
xctx->sym[xctx->inst[n].ptr].templ, NULL ));
xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL));
dbg(1, "draw_symbol(): after translate3: str=%s\n", txtptr);
draw_string(textlayer, what, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
@ -906,7 +906,7 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot
my_strdup2(_ALLOC_ID_, &txtptr, translate(n, text.txt_ptr));
/* do another round of substitutions if some @var are found, but if not found leave @var as is */
my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 1, xctx->inst[n].prop_ptr,
xctx->sym[xctx->inst[n].ptr].templ, NULL ));
xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL));
dbg(1, "draw_temp_symbol(): after translate3: str=%s\n", txtptr);
if(txtptr[0]) draw_temp_string(gc, what, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
@ -2543,7 +2543,7 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int graph_dataset)
if(gr->logx) xx = mylog10(gv[p]);
else xx = gv[p];
if(p == ofs) xx0 = gv0[p];
wrap = (cnt > 1 && gv0[p] == xx0);
wrap = !strcmp(xctx->raw->sim_type, "dc") && cnt > 1 && gv0[p] == xx0;
if(wrap) {
sweepvar_wrap++;
cnt = 0;
@ -3568,7 +3568,7 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr)
xx = gv[p];
if(p == ofs) xx0 = gv0[p];
wrap = ( cnt > 1 && gv0[p] == xx0);
wrap = !strcmp(xctx->raw->sim_type, "dc") && cnt > 1 && gv0[p] == xx0;
if(first != -1) { /* there is something to plot ... */
if(xx > end || xx < start || /* ... and we ran out of graph area ... */
wrap) { /* ... or sweep variable changed direction */
@ -3713,7 +3713,7 @@ int find_closest_wave(int i, Graph_ctx *gr)
if(gr->logy) yy = mylog10(gvy[p]);
else yy = gvy[p];
if(p == ofs) xx0 = gv0[p];
wrap = (cnt > 1 && gv0[p] == xx0);
wrap = !strcmp(xctx->raw->sim_type, "dc") && cnt > 1 && gv0[p] == xx0;
if(first != -1) {
if(xx > end || xx < start || wrap) {
dbg(1, "find_closest_wave(): last=%d\n", last);
@ -4026,7 +4026,6 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
/* optimization: skip unwanted datasets, if no dc no need to detect sweep variable wraps */
if(dataset >= 0 && strcmp(xctx->raw->sim_type, "dc") && dataset != sweepvar_wrap) goto done;
for(p = ofs ; p < ofs_end; p++) {
double xxprevious, xxfollowing;
@ -4038,7 +4037,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
* are simulated and thos no equality test can be done, and any "approx equal" test si going
* to do unexpected things (liek in simulations with very dense steps) */
if(p == ofs) xx0 = gv0[p]; /* gv[p];*/
wrap = cnt > 1 && gv0[p] == xx0;
wrap = !strcmp(xctx->raw->sim_type, "dc") && cnt > 1 && gv0[p] == xx0;
#if 1 /* plot one point before start and one point after end so
* waves will extend to whole graph area even if there are few points
* but NOT if we are about to wrap (missing 1st/last point in 2-var dc sweeps) */
@ -4778,7 +4777,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
cairo_surface_t *png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi;
size_t olength;
const double max_size = 3000.0;
const double max_size = 2500.0;
if(!has_x) return;
@ -4793,9 +4792,9 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
rw = fabs(rx2 -rx1);
rh = fabs(ry2 - ry1);
scale = 3.0;
if(rw > rh && rw > max_size) {
if(rw > rh && rw * scale > max_size) {
scale = max_size / rw;
} else if(rh > max_size) {
} else if(rh * scale > max_size) {
scale = max_size / rh;
}
rwi = (int) (rw * scale + 1.0);
@ -4851,7 +4850,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
xctx->do_copy_area=save;
tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, xctx->xrect[0].width, xctx->xrect[0].height);
resetwin(1, 1, 1, 0, 0);
h = fabs(y2 - y1);
w = fabs(x2 - x1);
@ -4883,7 +4882,6 @@ void draw(void)
#endif
dbg(1, "draw()\n");
if(!xctx || xctx->no_draw) return;
cs = tclgetdoublevar("cadsnap");

View File

@ -1475,7 +1475,7 @@ int drc_check(int i)
my_strdup(_ALLOC_ID_, &drc, get_tok_value(xctx->sym[xctx->inst[j].ptr].prop_ptr, "drc", 2));
if(drc) {
my_strdup(_ALLOC_ID_, &res, translate3(drc, 1,
xctx->inst[j].prop_ptr, xctx->sym[xctx->inst[j].ptr].templ, NULL));
xctx->inst[j].prop_ptr, xctx->sym[xctx->inst[j].ptr].templ, NULL, NULL));
dbg(1, "drc_check(): res = |%s|, drc=|%s|\n", res, drc);
if(res) {
const char *result;

277
src/eval_expr.y Normal file
View File

@ -0,0 +1,277 @@
%{
#include <stdio.h>
#include <math.h> /* For math functions, cos(), sin(), etc. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "xschem.h"
static const char *str, *strptr;
static char *ret = NULL;
static int dbglev = 1;
/* Data type for links in the chain of functions. */
struct symrec
{
char *name; /* name of symbol */
double (*fnctptr)(); /* value of a FNCT */
struct symrec *next; /* link field */
};
typedef struct symrec symrec;
/* The symbol table: a chain of `struct symrec'. */
symrec *sym_table = (symrec *)0;
static symrec *getsym(char *sym_name);
static symrec *putsym(char *sym_name);
static int kklex();
static void kkerror(char *s);
static double toint(double x);
static void get_expr(double x);
static void get_char(int c);
struct fn
{
char *fname;
double (*fnct)();
};
static int lex_state = 0;
struct fn fn_array[]
= {
{"int" , toint},
{"sin" , sin},
{"cos" , cos},
{"asin", asin},
{"acos", acos},
{"atan", atan},
{"log" , log10},
{"ln" , log},
{"exp" , exp},
{"sqrt", sqrt},
{0 , 0}
};
%}
%define api.prefix {kk}
%union {
int c;
double val; /* For returning numbers. */
symrec *tptr; /* For returning symbol-table pointers */
}
%token STREND 0
%token <c> CHAR
%token EXPR /* expr( */
%token <val> NUM /* Simple double precision number */
%token <tptr> FNCT /* Variable and Function */
%type <val> exp
%right '='
%left '-' '+'
%left '*' '/' '%'
%left NEG /* Negation--unary minus */
%right '^' /* Exponentiation */
/* Grammar follows */
%%
input:
| input line
;
line:
CHAR {get_char($1);}
| EXPR exp ')' {get_expr($2);lex_state = 0;}
| EXPR '\'' exp '\'' ')' {get_expr($3);lex_state = 0;}
| EXPR exp error
;
exp: NUM {$$ = $1;}
| FNCT '(' exp ')' {$$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
| exp '+' exp {$$ = $1 + $3; }
| exp '-' exp {$$ = $1 - $3;}
| exp '*' exp {$$ = $1 * $3;}
| exp '%' exp {$$ = (int)$1 % (int)$3;}
| exp '/' exp {$$ = $1 / $3;}
| '-' exp %prec NEG {$$ = -$2;}
| exp '^' exp {$$ = pow ($1, $3);}
| '(' exp ')' {$$ = $2;}
;
/* End of grammar */
%%
static void get_char(int c)
{
char s[2];
dbg(dbglev, "get_char: %c |%s|\n", c, str);
s[0] = (char)c;
s[1] = '\0';
my_mstrcat(_ALLOC_ID_, &ret, s, NULL);
strptr = str;
}
static void get_expr(double x)
{
char xx[100];
dbg(dbglev,"get_expr(): x=%g\n", x);
my_snprintf(xx, S(xx), "%.15g", x);
my_mstrcat(_ALLOC_ID_, &ret, xx, NULL);
strptr = str;
}
static double toint(double x)
{
if(x < 0.0) return ceil(x);
return floor(x);
}
/* ad=expr(3*xa) pd=expr(2*(3+xa)) --> ad=3*xa pd=2*(3+xa) */
static void remove_expr(char *s)
{
char *ptr = s;
int plev = 0;
while(*ptr) {
if(strstr(ptr, "expr(") == ptr) {
ptr += 5;
plev++;
}
if(*ptr == '(') plev++;
if(*ptr == ')') {
plev--;
if(plev == 0) ptr++;
if(!ptr) break;
}
*s = *ptr;
ptr++;
s++;
}
*s = *ptr;
}
static void kkerror(char *s) /* Called by kkparse on error */
{
char *ss = NULL;
dbg(dbglev, "error: |%s|\n\n |%s|\n", s, str ? str : "<NULL>");
my_strdup2(_ALLOC_ID_, &ss, strptr);
remove_expr(ss);
my_mstrcat(_ALLOC_ID_, &ret, ss, NULL);
my_free(_ALLOC_ID_, &ss);
lex_state = 0;
}
static symrec *getsym(char *sym_name)
{
symrec *ptr;
for (ptr = sym_table; ptr; ptr = ptr->next)
if (strcmp (ptr->name,sym_name) == 0) return ptr;
return NULL;
}
symrec * putsym (char *sym_name)
{
symrec *ptr;
ptr = (symrec *) my_malloc(_ALLOC_ID_, sizeof (symrec));
ptr->name = (char *) my_malloc(_ALLOC_ID_, strlen (sym_name) + 1);
strcpy (ptr->name,sym_name);
ptr->next = (struct symrec *)sym_table;
sym_table = ptr;
return ptr;
}
void eval_expr_init_table(void) /* puts arithmetic functions in table. */
{
int i;
symrec *ptr;
for (i = 0; fn_array[i].fname != 0; i++)
{
ptr = putsym (fn_array[i].fname);
ptr->fnctptr = fn_array[i].fnct;
}
}
void eval_expr_clear_table(void)
{
symrec *ptr;
for (ptr = sym_table; ptr; ptr = ptr->next) {
symrec *tmp = ptr;
my_free(_ALLOC_ID_, &(tmp->name));
my_free(_ALLOC_ID_, &tmp);
}
}
static int kklex()
{
int c;
if(!str) { return 0; }
if(strstr(str, "expr(") == str) {
lex_state = 1;
str += 5;
dbg(dbglev, "lex(): EXPR\n");
return EXPR;
}
if(!lex_state) {
c = *str++;
if(c) {
kklval.c = c;
dbg(dbglev, "lex(): CHAR; %c\n", c);
return CHAR;
} else {
dbg(dbglev, "lex(): STREND\n");
return STREND;
}
}
/* Ignore whitespace, get first nonwhite character. */
while ((c = *str++) == ' ' || c == '\t' || c == '\n');
if (c == 0) {
str = NULL;
return 0;
}
/* Char starts a number => parse the number. */
if (c == '.' || isdigit (c))
{
char s[100] ="";
int rd = 0;
str--;
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
kklval.val = atof_spice(s);
str += rd;
dbg(dbglev, "lex(): NUM: %s\n", s);
return NUM;
}
/* Char starts an identifier => read the name. */
if(isalpha(c)) {
symrec *s;
int length = 40; /* max length of function names */
char symbuf[41];
int i = 0;
/* Initially make the buffer int enough
* for a 40-character symbol name. */
do
{
symbuf[i++] = (char) c; /* Add this character to the buffer.*/
c = *str++; /* Get another character.*/
}
while (c != 0 && isalnum(c) && i < length);
str--;
symbuf[i] = '\0';
s = getsym (symbuf);
kklval.tptr = s;
dbg(dbglev, "ylex: FNCT=%s\n", symbuf);
return FNCT;
}
/* Any other character is a token by itself. */
return c;
}
char *eval_expr(const char *s)
{
lex_state = 0;
if(ret) my_free(_ALLOC_ID_, &ret);
strptr = str = s;
kkparse();
return ret;
}

View File

@ -186,7 +186,7 @@ int yyparse_error = 0;
char *xschem_executable=NULL;
Tcl_Interp *interp = NULL;
double *character[256]; /* array or per-char coordinates of xschem internal vector font */
char old_winpath[PATH_MAX] = ".drw"; /* previously switched window, used in callback() */
char old_win_path[PATH_MAX] = ".drw"; /* previously switched window, used in callback() */
#ifndef __unix__
char win_temp_dir[PATH_MAX]="";
const char fopen_read_mode[] = "rb";

View File

@ -96,7 +96,9 @@ ctrl 'c' Save to clipboard
shift 'C' Start arc placement
shift+ctrl 'C' Start circle placement
alt 'C' Toggle dim/brite background with rest of layers
shift 'D' Delete files
ctrl 'd' Delete files
- 'd' Unselect selected object under the mouse pointer
shift 'D' Unselect selected objects by area
ctrl 'e' Back to parent schematic
- 'e' Descend to schematic
alt 'e' Edit selected schematic in a new window

View File

@ -257,7 +257,7 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
double rw, rh, scale;
cairo_surface_t* png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi;
const double max_size = 3000.0;
const double max_size = 2500.0;
int d_c;
unsigned char* jpgData = NULL;
size_t fileSize = 0;
@ -292,15 +292,16 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
rw = fabs(rx2 - rx1);
rh = fabs(ry2 - ry1);
scale = 3.0;
if (rw > rh && rw > max_size) {
if (rw > rh && rw * scale > max_size) {
scale = max_size / rw;
}
else if (rh > max_size) {
else if (rh * scale > max_size) {
scale = max_size / rh;
}
rwi = (int)(rw * scale + 1.0);
rhi = (int)(rh * scale + 1.0);
dbg(1, "graph size: %dx%d\n", rwi, rhi);
dbg(1, "ps_embedded_graph: saving zoom\n");
save_restore_zoom(1, &zi);
set_viewport_size(rwi, rhi, xctx->lw);
@ -353,8 +354,9 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
cairo_surface_destroy(png_sfc);
xctx->draw_pixmap = 1;
tclsetboolvar("draw_grid", save_draw_grid);
dbg(1, "ps_embedded_graph: restoring zoom\n");
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, xctx->xrect[0].width, xctx->xrect[0].height);
resetwin(1, 1, 1, 0, 0);
change_linewidth(xctx->lw);
tclsetboolvar("dark_colorscheme", d_c);
build_colors(0, 0);
@ -1178,8 +1180,8 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
fprintf(errfp, "ps_draw(): can not create tmpfile %s\n", *psfile);
return;
}
setbuf(fd, NULL); /*To prevent buffer errors, still investigating cause. */
}
setbuf(fd, NULL); /*To prevent buffer errors, still investigating cause. */
ps_colors=my_calloc(_ALLOC_ID_, cadlayers, sizeof(Ps_color));
if(ps_colors==NULL){
fprintf(errfp, "create_ps(): calloc error\n");
@ -1190,78 +1192,83 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
old_grid=tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0");
/* xschem window aspect ratio decides if portrait or landscape */
boundbox.x1 = xctx->areax1;
boundbox.x2 = xctx->areax2;
boundbox.y1 = xctx->areay1;
boundbox.y2 = xctx->areay2;
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
/* xschem drawing bbox decides if portrait or landscape */
if(fullzoom == 1) {
calc_drawing_bbox(&boundbox, 0);
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
}
if(dx >= dy) {
landscape = 1;
} else {
landscape = 0;
}
dbg(1, "dx=%g, dy=%g\n", dx, dy);
if(fullzoom == 1) {
/* save size and zoom factor */
save_restore_zoom(1, &zi);
/* this zoom only done to reset lw */
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
/* adjust aspect ratio to paper size */
if(landscape)
xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
else
xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
xctx->areax1 = -2*INT_WIDTH(xctx->lw);
xctx->areay1 = -2*INT_WIDTH(xctx->lw);
xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2 - xctx->areay1;
dbg(1, "dx=%g, dy=%g\n", dx, dy);
/* fit schematic into adjusted size */
zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
if(!(what & 4)) {
/* xschem window aspect ratio decides if portrait or landscape */
boundbox.x1 = xctx->areax1;
boundbox.x2 = xctx->areax2;
boundbox.y1 = xctx->areay1;
boundbox.y2 = xctx->areay2;
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
}
if(!landscape) { /* decide paper orientation for best schematic fit */
double tmp;
tmp = pagex;
pagex = pagey;
pagey = tmp;
}
if(fullzoom == 2) { /* set media size to bbox */
double sc;
my_strncpy(papername, "bbox", S(papername));
pagex = xctx->xrect[0].width;
pagey = xctx->xrect[0].height;
if(pagex > pagey) {
sc = 842. / pagex;
pagex = my_round(pagex * sc);
pagey = my_round(pagey * sc);
} else {
sc = 842. / pagey;
pagex = my_round(pagex * sc);
pagey = my_round(pagey * sc);
/* xschem drawing bbox decides if portrait or landscape */
if(fullzoom == 1) {
calc_drawing_bbox(&boundbox, 0);
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
}
margin = 0.0;
}
if(dx >= dy) {
landscape = 1;
} else {
landscape = 0;
}
dbg(1, "dx=%g, dy=%g\n", dx, dy);
if(fullzoom == 1) {
/* save size and zoom factor */
dbg(1, "create_ps: saving zoom\n");
save_restore_zoom(1, &zi);
/* this zoom only done to reset lw */
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
/* adjust aspect ratio to paper size */
if(landscape)
xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
else
xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
xctx->areax1 = -2*INT_WIDTH(xctx->lw);
xctx->areay1 = -2*INT_WIDTH(xctx->lw);
xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2 - xctx->areay1;
dbg(1, "dx=%g, dy=%g\n", dx, dy);
/* fit schematic into adjusted size */
zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
boundbox.x1 = xctx->areax1;
boundbox.x2 = xctx->areax2;
boundbox.y1 = xctx->areay1;
boundbox.y2 = xctx->areay2;
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
}
if(!landscape) { /* decide paper orientation for best schematic fit */
double tmp;
tmp = pagex;
pagex = pagey;
pagey = tmp;
}
if(fullzoom == 2) { /* set media size to bbox */
double sc;
my_strncpy(papername, "bbox", S(papername));
pagex = xctx->xrect[0].width;
pagey = xctx->xrect[0].height;
if(pagex > pagey) {
sc = 842. / pagex;
pagex = my_round(pagex * sc);
pagey = my_round(pagey * sc);
} else {
sc = 842. / pagey;
pagex = my_round(pagex * sc);
pagey = my_round(pagey * sc);
}
margin = 0.0;
}
} /* if(!(what & 4)) */
if(what & 1) {/* prolog */
dbg(1, "ps_draw(): bbox: x1=%g y1=%g x2=%g y2=%g\n", boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
@ -1334,7 +1341,6 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
fprintf(fd, "%%%%EndProlog\n");
}
if(what & 2) { /* page */
++numpages;
@ -1491,7 +1497,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
dbg(1, "ps_draw(): INT_WIDTH(lw)=%d plotfile=%s\n",INT_WIDTH(xctx->lw), xctx->plotfile);
fprintf(fd, "showpage\n\n");
}
} /* if(what & 2) */
if(what & 4) { /* trailer */
fprintf(fd, "%%%%trailer\n");
fprintf(fd, "%%%%Pages: %d\n", numpages);
@ -1509,10 +1515,10 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
/* restore original size and zoom factor */
if(fullzoom == 1) {
if(!(what & 4) && fullzoom == 1) {
dbg(1, "create_ps: restoring zoom\n");
save_restore_zoom(0, &zi);
}
}
int ps_draw(int what, int fullzoom, int eps)

View File

@ -3446,6 +3446,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
{
FILE *fd;
char name[PATH_MAX];
char *ffname = NULL; /*copy of fname so I can change it */
char msg[PATH_MAX+100];
struct stat buf;
int i, ret = 1; /* success */
@ -3454,24 +3455,31 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
xctx->prep_net_structs=0;
xctx->prep_hash_inst=0;
xctx->prep_hash_wires=0;
my_strdup2(_ALLOC_ID_, &ffname, trim_chars(fname, " \t\n"));
if(reset_undo) {
xctx->clear_undo();
xctx->prev_set_modify = -1; /* will force set_modify(0) to set window title */
}
else xctx->prev_set_modify = 0; /* will prevent set_modify(0) from setting window title */
if(fname && fname[0]) {
if(ffname && ffname[0]) {
int generator = 0;
if(is_generator(fname)) generator = 1;
my_strncpy(name, fname, S(name));
dbg(1, "load_schematic(): fname=%s\n", fname);
/* if ffname is a generator add () at end of filename if not already present */
tclvareval("is_xschem_file {", ffname, "}", NULL);
if(!strcmp(tclresult(), "GENERATOR")) {
size_t len = strlen(ffname);
if( ffname[len - 1] != ')') my_strcat(_ALLOC_ID_, &ffname, "()");
}
if(is_generator(ffname)) generator = 1;
my_strncpy(name, ffname, S(name));
dbg(1, "load_schematic(): name=%s generator=%d\n", name, generator);
/* remote web object specified */
if(is_from_web(fname) && xschem_web_dirname[0]) {
if(is_from_web(ffname) && xschem_web_dirname[0]) {
/* download into ${XSCHEM_TMP_DIR}/xschem_web */
tclvareval("download_url {", fname, "}", NULL);
tclvareval("download_url {", ffname, "}", NULL);
/* build local file name of downloaded object */
my_snprintf(name, S(name), "%s/%s", xschem_web_dirname, get_cell_w_ext(fname, 0));
my_snprintf(name, S(name), "%s/%s", xschem_web_dirname, get_cell_w_ext(ffname, 0));
/* build current_dirname by stripping off last filename from url */
my_snprintf(msg, S(msg), "get_directory {%s}", fname);
my_snprintf(msg, S(msg), "get_directory {%s}", ffname);
my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname));
/* local file name */
my_strdup2(_ALLOC_ID_, &xctx->sch[xctx->currsch], name);
@ -3482,29 +3490,32 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
/* ... but not local file from web download --> reset current_dirname */
char sympath[PATH_MAX];
my_snprintf(sympath, S(sympath), "%s", xschem_web_dirname);
/* fname does not begin with $XSCHEM_TMP_DIR/xschem_web and fname does not exist */
/* ffname does not begin with $XSCHEM_TMP_DIR/xschem_web and ffname does not exist */
if(strstr(fname, sympath) != fname /* && stat(fname, &buf)*/) {
my_snprintf(msg, S(msg), "get_directory {%s}", fname);
if(strstr(ffname, sympath) != ffname /* && stat(ffname, &buf)*/) {
my_snprintf(msg, S(msg), "get_directory {%s}", ffname);
my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname));
}
/* local file name */
my_strdup2(_ALLOC_ID_, &xctx->sch[xctx->currsch], fname);
my_strdup2(_ALLOC_ID_, &xctx->sch[xctx->currsch], ffname);
/* local relative reference */
my_strncpy(xctx->current_name, rel_sym_path(fname), S(xctx->current_name));
my_strncpy(xctx->current_name, rel_sym_path(ffname), S(xctx->current_name));
} else { /* local file specified and not coming from web url */
/* build current_dirname by stripping off last filename from url */
my_snprintf(msg, S(msg), "get_directory {%s}", fname);
my_snprintf(msg, S(msg), "get_directory {%s}", ffname);
my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname));
/* local file name */
my_strdup2(_ALLOC_ID_, &xctx->sch[xctx->currsch], fname);
my_strdup2(_ALLOC_ID_, &xctx->sch[xctx->currsch], ffname);
/* local relative reference */
my_strncpy(xctx->current_name, rel_sym_path(fname), S(xctx->current_name));
my_strncpy(xctx->current_name, rel_sym_path(ffname), S(xctx->current_name));
}
dbg(1, "load_schematic(): opening file for loading:%s, fname=%s\n", name, fname);
dbg(1, "load_schematic(): opening file for loading:%s, ffname=%s\n", name, ffname);
dbg(1, "load_schematic(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
if(!name[0]) return 0; /* empty filename */
if(!name[0]) {
my_free(_ALLOC_ID_, &ffname);
return 0; /* empty filename */
}
if(reset_undo) {
if(!stat(name, &buf)) { /* file exists */
xctx->time_last_modify = buf.st_mtime;
@ -3515,7 +3526,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
} else {xctx->time_last_modify = 0;} /* undefined */
if(generator) {
char *cmd;
cmd = get_generator_command(fname);
cmd = get_generator_command(ffname);
if(cmd) {
fd = popen(cmd, "r");
my_free(_ALLOC_ID_, &cmd);
@ -3526,9 +3537,9 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
size_t len;
ret = 0;
if(alert) {
fprintf(errfp, "load_schematic(): unable to open file: %s, fname=%s\n", name, fname );
fprintf(errfp, "load_schematic(): unable to open file: %s, ffname=%s\n", name, ffname );
if(has_x) {
my_snprintf(msg, S(msg), "update; alert_ {Unable to open file: %s}", fname);
my_snprintf(msg, S(msg), "update; alert_ {Unable to open file: %s}", ffname);
tcleval(msg);
}
}
@ -3567,7 +3578,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
}
}
dbg(1, "load_schematic(): %s, returning\n", xctx->sch[xctx->currsch]);
} else { /* fname == NULL or empty */
} else { /* ffname == NULL or empty */
/* if(reset_undo) xctx->time_last_modify = time(NULL); */ /* no file given, set mtime to current time */
if(reset_undo) xctx->time_last_modify = 0; /* no file given, set mtime to 0 (undefined) */
clear_drawing();
@ -3602,6 +3613,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
set_netlist_dir(2, NULL);
drc_check(-1);
}
my_free(_ALLOC_ID_, &ffname);
return ret;
}
@ -5140,7 +5152,7 @@ int descend_symbol(void)
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].prop_ptr,
xctx->inst[n].prop_ptr);
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ,
get_tok_value(xctx->sym[xctx->inst[n].ptr].prop_ptr, "template", 0));
xctx->sym[xctx->inst[n].ptr].templ);
if(!xctx->inst[n].embed)
/* use -1 to keep track we are descending into symbol from instance with no embed attr

View File

@ -431,7 +431,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else { cmd_found = 0;}
break;
case 'c': /*----------------------------------------------*/
/* callback winpath event mx my key button aux state
/* callback win_path event mx my key button aux state
* Invoke the callback event dispatcher with a software event */
if(!strcmp(argv[1], "callback") )
{
@ -1008,6 +1008,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
/* eval_expr str
* debug function: evaluate arithmetic expression in str */
else if(!strcmp(argv[1], "eval_expr"))
{
if(argc > 2) {
Tcl_SetResult(interp, eval_expr(argv[2]), TCL_VOLATILE);
}
}
/* exit [exit_code] [closewindow] [force]
* Exit the program, ask for confirm if current file modified.
* if exit_code is given exit with its value, otherwise use 0 exit code
@ -2732,7 +2742,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_free(_ALLOC_ID_, &pins);
}
/* is_symgen symbol
/* is_generator symbol
* tell if 'symbol' is a generator (symbol(param1,param2,...) */
else if(!strcmp(argv[1], "is_generator"))
{
@ -3367,6 +3377,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
tclsetvar("show_infowindow_after_netlist", saveshow);
tcleval("eval_netlist_postprocess");
set_netlist_dir(1, savedir);
if(done_netlist) {
if(messages) {
@ -3394,22 +3405,22 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
/* new_schematic create|destroy|destroy_all|switch winpath file [draw]
/* new_schematic create|destroy|destroy_all|switch win_path file [draw]
* Open/destroy a new tab or window
* create: create new empty window or with 'file' loaded if 'file' given.
* The winpath must be given (even {} is ok).
* non empty winpath ({1}) will avoid warnings if opening the
* The win_path must be given (even {} is ok).
* non empty win_path ({1}) will avoid warnings if opening the
* same file multiple times.
* destroy: destroy tab/window identified by winpath. Example:
* destroy: destroy tab/window identified by win_path. Example:
* xschem new_schematic destroy .x1.drw
* destroy_all: close all tabs/additional windows
* if the 'force'argument is given do not issue a warning if modified
* tabs are about to be closed.
* switch: switch context to specified 'winpath' window or specified schematic name
* switch: switch context to specified 'win_path' window or specified schematic name
* If 'draw' is given and set to 0 do not redraw after switching tab
* (only tab i/f)
* Main window/tab has winpath set to .drw,
* Additional windows/tabs have winpath set to .x1.drw, .x2.drw and so on...
* Main window/tab has win_path set to .drw,
* Additional windows/tabs have win_path set to .x1.drw, .x2.drw and so on...
*/
else if(!strcmp(argv[1], "new_schematic"))
{
@ -3613,7 +3624,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
xctx->ui_state2 = MENUSTARTPOLYGON;
}
/* preview_window create|draw|destroy|close [winpath] [file]
/* preview_window create|draw|destroy|close [win_path] [file]
* destroy: will delete preview schematic data and destroy container window
* close: same as destroy but leave the container window.
* Used in fileselector to show a schematic preview.
@ -5749,7 +5760,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
/* switch [window_path |schematic_name]
* Switch context to indicated window path or schematic name
* returns 0 if switch was successfull or 1 in case of errors
* (no tabs/windows present or no matching winpath / schematic name
* (no tabs/windows present or no matching win_path / schematic name
* found).
*/
else if(!strcmp(argv[1], "switch"))
@ -5773,7 +5784,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
char n[100];
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 2 && !strcmp(argv[2], "derived_symbols")) derived_symbols = 1;
else if(argc > 2 && argv[2][0]) {
else if(argc > 2 && argv[2][0] && isonlydigit(argv[2])) {
one_symbol = 1;
i = get_symbol(argv[2]);
if(i >=0) Tcl_AppendResult(interp, my_itoa(i), " {", xctx->sym[i].name, "}", NULL);
@ -6057,9 +6068,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int eat_escapes = 0;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 3) eat_escapes = atoi(argv[3]);
if(argc > 6) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], argv[6]));
else if(argc > 5) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], NULL));
else if(argc > 4) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], NULL, NULL));
if(argc > 6) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], argv[6], NULL));
else if(argc > 5) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], NULL, NULL));
else if(argc > 4) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], NULL, NULL, NULL));
else {
Tcl_SetResult(interp, "xschem translate3: missing arguments", TCL_STATIC);
return TCL_ERROR;

View File

@ -133,9 +133,9 @@ void hier_psprint(char **res, int what) /* netlister driver */
xctx->prev_set_modify = save_prev_mod;
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
xctx->do_copy_area = save;
if(what & 1) ps_draw(4, 1, 0); /* trailer */
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
draw();
if(what & 1) ps_draw(4, 1, 0); /* trailer */
}
static char *model_name_result = NULL; /* safe even with multiple schematics */
@ -455,11 +455,13 @@ int global_spice_netlist(int global, int alert) /* netlister driver */
if(lvs_ignore && (xctx->sym[i].flags & LVS_IGNORE)) continue;
if(!xctx->sym[i].type) continue;
/* store parent symbol template attr (before descending into it) and parent instance prop_ptr
* into xctx->hier_attr[0].templ and xctx->hier_attr[0.prop_ptr,
* to resolve subschematic instances with model=@modp in format string,
* modp will be first looked up in instance prop_ptr string, and if not found
* in parent symbol template string */
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].templ,
tcl_hook2(xctx->sym[i].templ));
/* only additional symbols (created with instance schematic=... attr) will have this attribute */
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch - 1].prop_ptr,
tcl_hook2(xctx->sym[i].parent_prop_ptr));
my_strdup(_ALLOC_ID_, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
@ -641,14 +643,9 @@ int spice_block_netlist(FILE *fd, int i, int alert)
my_strdup(_ALLOC_ID_, &sym_def, get_tok_value(xctx->sym[i].prop_ptr,"spice_sym_def",0));
if(sym_def) {
char *symname_attr = NULL;
char *templ = NULL;
const char *translated_sym_def;
my_strdup2(_ALLOC_ID_, &templ, get_tok_value(xctx->sym[i].prop_ptr, "template", 0));
my_mstrcat(_ALLOC_ID_, &symname_attr, "symname=", get_cell(name, 0), NULL);
translated_sym_def = translate3(sym_def, 1, "",
templ,
symname_attr);
my_free(_ALLOC_ID_, &templ);
translated_sym_def = translate3(sym_def, 1, xctx->sym[i].templ, symname_attr, NULL, NULL);
my_free(_ALLOC_ID_, &symname_attr);
fprintf(fd, "%s\n", translated_sym_def);
my_free(_ALLOC_ID_, &sym_def);

File diff suppressed because it is too large Load Diff

View File

@ -187,7 +187,7 @@ static int window_state (Display *disp, Window win, char *arg) {/*{{{*/
/* ----------------------------------------------------------------------- */
/* used to set icon */
void windowid(const char *winpath)
void windowid(const char *win_path)
{
#ifdef __unix__
int i;
@ -200,11 +200,11 @@ void windowid(const char *winpath)
Window *framewin_child_ptr;
unsigned int framewindow_nchildren;
dbg(1, "windowid(): winpath=%s\n", winpath);
dbg(1, "windowid(): win_path=%s\n", win_path);
framewindow_nchildren =0;
mainwindow=Tk_MainWindow(interp);
display = Tk_Display(mainwindow);
tclvareval("winfo id ", winpath, NULL);
tclvareval("winfo id ", win_path, NULL);
sscanf(tclresult(), "0x%x", (unsigned int *) &ww);
framewin = ww;
XQueryTree(display, framewin, &rootwindow, &parent_of_topwindow, &framewin_child_ptr, &framewindow_nchildren);
@ -949,12 +949,13 @@ static void xwin_exit(void)
list_tokens(NULL, 0); /* clear static data in function */
translate(-1, NULL); /* clear static data in function */
translate2(NULL, 0, NULL); /* clear static data in function */
translate3(NULL, 0, NULL, NULL, NULL); /* clear static data in function */
translate3(NULL, 0, NULL, NULL, NULL, NULL); /* clear static data in function */
subst_token(NULL, NULL, NULL); /* clear static data in function */
find_nth(NULL, "", "", 0, 0); /* clear static data in function */
trim_chars(NULL, ""); /* clear static data in function */
tcl_hook2(NULL); /* clear static data in function */
save_ascii_string(NULL, NULL, 0); /* clear static data in function */
eval_expr_clear_table(); /* clear expression parser data */
dbg(1, "xwin_exit(): removing font\n");
for(i=0;i<127; ++i) my_free(_ALLOC_ID_, &character[i]);
dbg(1, "xwin_exit(): closed display\n");
@ -1445,7 +1446,7 @@ void swap_windows(int dr)
new_schematic("switch", wp_j, "", 0);
resetwin(1, 1, 1, 0, 0);
my_snprintf(old_winpath, S(old_winpath), "");
my_snprintf(old_win_path, S(old_win_path), "");
if(dr) draw();
}
}
@ -1655,6 +1656,7 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch
load_schematic(1, fname, 1, confirm);
if(dr) zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97); /* draw */
tclvareval("set_bindings ", window_path[n], NULL);
tclvareval("set_replace_key_binding ", window_path[n], NULL);
tclvareval("save_ctx ", window_path[n], NULL);
/* restore previous context,
* because the Expose event after new window creation does a context switch prev win -> new win
@ -2186,6 +2188,8 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h)
#else
XWindowAttributes wattr;
#endif
dbg(1, "resetwin(): create=%d, clear=%d, force=%d, w=%d, h=%d\n",
create_pixmap, clear_pixmap, force, w, h);
if(w && h) {
width = w;
height = h;
@ -2310,6 +2314,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
#ifdef __unix__
const char* home_buff;
#endif
eval_expr_init_table();
/* get PWD and HOME */
if(!getcwd(pwd_dir, PATH_MAX)) {
fprintf(errfp, "Tcl_AppInit(): getcwd() failed\n");

View File

@ -229,7 +229,9 @@ extern char win_temp_dir[PATH_MAX];
#define START_SYMPIN 16384U
#define GRAPHPAN 32768U /* bit 15 */
#define MENUSTART 65536U /* bit 16 */
#define GRABSCREEN 131072 /* bit 17 */
#define GRABSCREEN 131072U /* bit 17 */
#define DESEL_CLICK 262144U /* bit 18 */
#define DESEL_AREA 524288U /* bit 19 */
#define SELECTED 1U /* used in the .sel field for selected objs. */
#define SELECTED1 2U /* first point selected... */
@ -238,6 +240,7 @@ extern char win_temp_dir[PATH_MAX];
#define SELECTED4 16U
/* sub states encoded in global ui_state2 to reduce ui_state bits usage */
/* also used when infix_interface=0 */
#define MENUSTARTWIRE 1U /* start wire invoked from menu */
#define MENUSTARTLINE 2U /* start line invoked from menu */
#define MENUSTARTRECT 4U /* start rect invoked from menu */
@ -250,6 +253,7 @@ extern char win_temp_dir[PATH_MAX];
#define MENUSTARTWIRECUT 512U
#define MENUSTARTWIRECUT2 1024U /* do not align cut point to snap */
#define MENUSTARTCOPY 2048U
#define MENUSTARTDESEL 4096U
#define WIRE 1 /* types of defined objects */
#define xRECT 2
@ -1215,7 +1219,7 @@ extern int yyparse_error;
extern char *xschem_executable;
extern Tcl_Interp *interp;
extern double *character[256];
extern char old_winpath[PATH_MAX]; /* previously switched window, used in callback() */
extern char old_win_path[PATH_MAX]; /* previously switched window, used in callback() */
extern const char fopen_read_mode[]; /* "r" on unix, "rb" on windows */
/*********** Cmdline options (used at xinit, and then not used anymore) ***********/
@ -1399,7 +1403,7 @@ extern void draw_crosshair(int what, int state);
extern void draw_snap_cursor(int what);
extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
/* extern void snapped_wire(double c_snap); */
extern int callback(const char *winpath, int event, int mx, int my, KeySym key,
extern int callback(const char *win_path, int event, int mx, int my, KeySym key,
int button, int aux, int state);
extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h);
extern Selected find_closest_obj(double mx,double my, int override_lock);
@ -1609,7 +1613,8 @@ extern int isonlydigit(const char *s);
extern const char *spice_get_node(const char *token);
extern const char *translate(int inst, const char* s);
extern const char* translate2(Lcc *lcc, int level, char* s);
extern const char *translate3(const char* s, int eat_escapes, const char *s1, const char *s2, const char *s3);
extern const char *translate3(const char* s, int eat_escapes, const char *s1,
const char *s2, const char *s3, const char *s4);
extern void print_tedax_element(FILE *fd, int inst);
extern int print_spice_element(FILE *fd, int inst);
extern void print_spice_subckt_nodes(FILE *fd, int symbol);
@ -1675,6 +1680,9 @@ extern void check_box_storage(int c);
extern void check_arc_storage(int c);
extern void check_line_storage(int c);
extern void check_polygon_storage(int c);
extern void eval_expr_init_table(void);
extern void eval_expr_clear_table(void);
extern char *eval_expr(const char *s);
extern const char *expandlabel(const char *s, int *m);
extern void parse(const char *s);
extern void clear_expandlabel_data(void);
@ -1741,7 +1749,7 @@ extern void print_hilight_net(int show);
extern void list_hilights(int all);
extern void change_layer();
extern void launcher();
extern void windowid(const char *winpath);
extern void windowid(const char *win_path);
extern int preview_window(const char *what, const char *tk_win_path, const char *fname);
extern int new_schematic(const char *what, const char *win_path, const char *fname, int dr);
extern void toggle_fullscreen(const char *topwin);

View File

@ -1005,7 +1005,7 @@ proc convert_to_png {filename dest} {
# Alt-Key-c
# ButtonPress-4
#
proc key_binding { s d { topwin {} } } {
proc key_binding { s d { win_path {.drw} } } {
regsub {.*-} $d {} key
@ -1039,14 +1039,14 @@ proc key_binding { s d { topwin {} } } {
if { [regexp ButtonPress-3 $d] } { set state [expr {$state +0x400}] }
# puts "$state $key <${s}>"
if {[regexp ButtonPress- $d]} {
bind $topwin.drw "<${s}>" "xschem callback %W %T %x %y 0 $key 0 $state"
bind $win_path "<${s}>" "xschem callback %W %T %x %y 0 $key 0 $state"
} else {
if {![string compare $d {} ] } {
# puts "bind .drw <${s}> {}"
bind $topwin.drw "<${s}>" {}
bind $win_path "<${s}>" {}
} else {
# puts "bind .drw <${s}> xschem callback %W %T %x %y $keysym 0 0 $state"
bind $topwin.drw "<${s}>" "xschem callback %W %T %x %y $keysym 0 0 $state"
bind $win_path "<${s}>" "xschem callback %W %T %x %y $keysym 0 0 $state"
}
}
@ -1771,7 +1771,7 @@ proc simconf_add {tool} {
# proc cellview prints symbol bindings (default binding or "schematic" attr in symbol)
# of all symbols used in current and sub schematics.
proc cellview_setlabels {w symbol derived_symbol} {
global dark_gui_colorscheme
global dark_gui_colorscheme netlist_type
if {$dark_gui_colorscheme} {
set instfg orange1
set symfg SeaGreen1
@ -1783,6 +1783,7 @@ proc cellview_setlabels {w symbol derived_symbol} {
set symbg SeaGreen1
set missingbg IndianRed1
}
set save_netlist_type [xschem get netlist_type]
set current [xschem get current_name]
set sym_spice_sym_def [xschem getprop symbol $symbol spice_sym_def 2]
set abs_sch [xschem get_sch_from_sym -1 $symbol]
@ -1799,6 +1800,8 @@ proc cellview_setlabels {w symbol derived_symbol} {
if { $sym_spice_sym_def eq {}} {
if { ![file exists [abs_sym_path [$w get]]] } {
$w configure -bg $missingbg
} elseif {$new_sch ne $default_sch } {
$w configure -bg $symbg
}
}
puts ===============
@ -1816,6 +1819,8 @@ proc cellview_setlabels {w symbol derived_symbol} {
xschem save fast
xschem remove_symbols ;# purge all symbols to force a reload from disk
xschem load -keep_symbols -nodraw -noundoreset $current
set netlist_type $save_netlist_type
xschem set netlist_type $netlist_type
xschem netlist -keep_symbols -noalert;# traverse the hierarchy and retain all encountered symbols
puts "get netlist"
}
@ -1826,6 +1831,8 @@ proc cellview_setlabels {w symbol derived_symbol} {
}
proc cellview_edit_item {symbol w} {
global netlist_type
set save_netlist_type [xschem get netlist_type]
set sym_spice_sym_def [xschem getprop symbol $symbol spice_sym_def 2]
if {[xschem is_generator [$w get]]} {
set f [$w get]
@ -1834,7 +1841,6 @@ proc cellview_edit_item {symbol w} {
} elseif { $sym_spice_sym_def eq {}} {
xschem load_new_window [$w get]
} else {
puts $symbol
set current [xschem get current_name]
set old_sym_def [xschem getprop symbol $symbol spice_sym_def 2]
set new_sym_def [editdata $sym_spice_sym_def {Symbol spice_sym_def attribute}]
@ -1847,6 +1853,8 @@ proc cellview_edit_item {symbol w} {
xschem save fast
puts "$symbol: updated spice_sym_def attribute"
xschem load -keep_symbols -nodraw -noundoreset $current
set netlist_type $save_netlist_type
xschem set netlist_type $netlist_type
xschem reload_symbols ;# update in-memory symbol data
}
}
@ -1863,8 +1871,10 @@ proc cellview_edit_sym {w} {
xschem load_new_window $sym
}
proc cellview { {derived_symbols {}} {upd 0} } {
global keep_symbols nolist_libs dark_gui_colorscheme
proc cellview { {derived_symbols {}} {upd 0}} {
global keep_symbols nolist_libs dark_gui_colorscheme netlist_type
set save_netlist_type [xschem get netlist_type]
if {$dark_gui_colorscheme} {
set instfg orange1
@ -1884,6 +1894,8 @@ proc cellview { {derived_symbols {}} {upd 0} } {
}
if {!$upd} {
set netlist_type $save_netlist_type
xschem set netlist_type $netlist_type
xschem reload_symbols ;# purge unused symbols
xschem netlist -keep_symbols -noalert;# traverse the hierarchy and retain all encountered symbols
puts "get netlist"
@ -1906,15 +1918,17 @@ proc cellview { {derived_symbols {}} {upd 0} } {
}
set syms [join [lsort -index 1 [xschem symbols $derived_symbols]]]
# puts "syms=$syms"
foreach {i symbol} $syms {
if { [catch {set base_name [xschem symbol_base_name $symbol]}] } {
set base_name $symbol
}
# puts "i=$i, symbol=$symbol"
set derived_symbol 0
if {$base_name ne {}} {
set derived_symbol 1
}
if { [catch {set abs_sch [xschem get_sch_from_sym -1 $symbol]} ]} {
if { [catch {xschem get_sch_from_sym -1 $symbol} abs_sch ]} {
set abs_sch [abs_sym_path [add_ext $symbol .sch]]
}
if {$derived_symbol} {
@ -1931,6 +1945,9 @@ proc cellview { {derived_symbols {}} {upd 0} } {
}
if {$skip} { continue }
set sym_sch [rel_sym_path $abs_sch]
if {[catch {xschem getprop symbol $symbol type} type]} {
puts "error: $symbol not found: $type"
}
set type [xschem getprop symbol $symbol type]
set sym_spice_sym_def [xschem getprop symbol $symbol spice_sym_def 2]
if {$type eq {subcircuit}} {
@ -1986,7 +2003,7 @@ proc cellview { {derived_symbols {}} {upd 0} } {
if {$upd} {return}
frame .cv.bottom
button .cv.bottom.update -text Update -command "cellview $derived_symbols 1"
button .cv.bottom.update -text Update -command "cellview [list $derived_symbols] 1"
pack .cv.bottom.update -side left
label .cv.bottom.status -text {STATUS LINE}
pack .cv.bottom.status -fill x -expand yes
@ -2006,9 +2023,10 @@ proc cellview { {derived_symbols {}} {upd 0} } {
############ traversal
proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch
inst_spice_sym_def sym_spice_sym_def} {
global traversal dark_gui_colorscheme
global traversal dark_gui_colorscheme netlist_type
set sf .trav.center.f.scrl
set save_netlist_type [xschem get netlist_type]
# puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]"
# update schematic
if {$parent_sch ne {}} {
@ -2026,6 +2044,8 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch
set inst_sch [$w get]
# puts "inst_sch set to: $inst_sch"
xschem load -undoreset -nodraw $current
set netlist_type $save_netlist_type
xschem set netlist_type $netlist_type
}
}
# /update schematic
@ -2955,6 +2975,14 @@ proc touches {sel tag} {
return $res
}
proc set_graph_default_colors {} {
global graph_selected graph_schname
if { [xschem get schname] ne $graph_schname } return
xschem setprop -fast rect 2 $graph_selected color "4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21"
graph_update_nodelist
xschem draw_graph $graph_selected
}
# change color of selected wave in text widget and redraw graph
# OR
# change color attribute of wave given as parameter, redraw graph
@ -3346,13 +3374,13 @@ proc graph_edit_properties {n} {
grid columnconfig .graphdialog.center.right 5 -weight 0
# bottom frame
button .graphdialog.bottom.cancel -text Cancel -command {
button .graphdialog.bottom.cancel -padx 1 -borderwidth 1 -pady 0 -text Cancel -command {
set graph_dialog_default_geometry [winfo geometry .graphdialog]
destroy .graphdialog
set graph_selected {}
set graph_schname {}
}
button .graphdialog.bottom.ok -text OK -command {
button .graphdialog.bottom.ok -padx 1 -borderwidth 1 -pady 0 -text OK -command {
if { [xschem get schname] eq $graph_schname } {
graph_push_undo
graph_update_node [string trim [.graphdialog.center.right.text1 get 1.0 {end - 1 chars}] " \n"]
@ -3367,7 +3395,7 @@ proc graph_edit_properties {n} {
set graph_selected {}
set graph_schname {}
}
button .graphdialog.bottom.apply -text Apply -command {
button .graphdialog.bottom.apply -padx 1 -borderwidth 1 -pady 0 -text Apply -command {
if { [xschem get schname] eq $graph_schname } {
graph_push_undo
graph_update_node [string trim [.graphdialog.center.right.text1 get 1.0 {end - 1 chars}] " \n"]
@ -3384,9 +3412,16 @@ proc graph_edit_properties {n} {
pack .graphdialog.bottom.apply -side left
pack .graphdialog.bottom.cancel -side left
for {set i 4} {$i < $cadlayers} {incr i} {
radiobutton .graphdialog.bottom.r$i -value $i -background [lindex $tctx::colors $i] \
-variable graph_sel_color -command graph_change_wave_color -selectcolor white -foreground black
for {set i 4} {$i <= $cadlayers} {incr i} {
if {$i == $cadlayers } {
button .graphdialog.bottom.r$i -padx 1 -borderwidth 1 -pady 0 \
-command "set_graph_default_colors" \
-text {AUTO SET}
} else {
radiobutton .graphdialog.bottom.r$i -value $i -background [lindex $tctx::colors $i] \
-variable graph_sel_color -command graph_change_wave_color \
-selectcolor white -foreground black
}
pack .graphdialog.bottom.r$i -side left
}
@ -3872,6 +3907,7 @@ proc open_sub_schematic {{inst {}} {inst_number 0}} {
proc is_xschem_file {f} {
regsub {\(.*} $f {} f ;# remove trailing generator args (gen.tcl(....)) if any
if { ![file exists $f] } { return 0
} elseif { [file isdirectory $f] } { return 0 }
set a [catch {open "$f" r} fd]
@ -4246,7 +4282,7 @@ proc file_dialog_place_symbol {} {
proc file_dialog_display_preview {f} {
set type [is_xschem_file $f]
if { $type ne {0} && $type ne {GENERATOR} } {
if { $type ne {0} } {
if { [winfo exists .load] } {
.load.l.paneright.draw configure -background {}
xschem preview_window draw .load.l.paneright.draw "$f"
@ -7831,33 +7867,33 @@ proc housekeeping_ctx {} {
}
# callback that resets simulate button color at end of simulation
proc set_simulate_button {top_path winpath} {
proc set_simulate_button {top_path win_path} {
global simulate_bg execute has_x
if {![info exists has_x]} return
set current_win [xschem get current_win_path]
set simvar tctx::${winpath}_simulate
set simvar tctx::${win_path}_simulate
set sim_button $top_path.menubar
# puts "current_win=|$current_win|"
# puts "simvar=|$simvar|"
# puts "winpath=|$winpath|"
# puts "win_path=|$win_path|"
# puts "top_path=|$top_path|"
# puts "sim_button=|$sim_button|"
# puts "execute(exitcode,last)=|$execute(exitcode,last)|"
if {![info exists execute(exitcode,last)]} {
if { $current_win eq $winpath} {
if { $current_win eq $win_path} {
$sim_button entryconfigure Simulate -background $simulate_bg
}
set $simvar $simulate_bg
} elseif { $execute(exitcode,last) == 0} {
if { $current_win eq $winpath} {
if { $current_win eq $win_path} {
$sim_button entryconfigure Simulate -background Green
}
set $simvar Green
} else {
if { $current_win eq $winpath} {
if { $current_win eq $win_path} {
$sim_button entryconfigure Simulate -background red
}
set $simvar red
@ -8900,11 +8936,11 @@ proc create_layers_menu { {topwin {} } } {
}
}
proc set_replace_key_binding {} {
proc set_replace_key_binding { {win_path {.drw}}} {
global replace_key
if {[array exists replace_key]} {
foreach i [array names replace_key] {
key_binding "$i" "$replace_key($i)"
key_binding "$i" "$replace_key($i)" $win_path
}
}
}
@ -8925,6 +8961,15 @@ proc eval_postinit_commands {} {
}
}
proc eval_netlist_postprocess {} {
global netlist_postprocess
if {[info exists netlist_postprocess]} {
if {[catch {uplevel #0 $netlist_postprocess} res]} {
puts "executing $netlist_postprocess:\n\n$res"
}
}
}
proc setup_tcp_xschem { {port_number {}} } {
global xschem_listen_port xschem_server_getdata

View File

@ -545,7 +545,10 @@
# }
# }
###########################################################################
#### TCL COMMANDS TO BE EXECUTED AFTER GENERATING NETLIST
###########################################################################
# set netlist_postprocess {textfile $netlist_dir/[xschem get netlist_name fallback]}
###########################################################################
#### WEB URL DOWNLOAD HELPER APPLICATION

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.5 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -31,7 +31,7 @@ value=\\"
format="tcleval(
[if \{[catch \{sim_is_@simulator \} retval] \} \{
return \{\} \} elseif \{$retval\} \{ return \{
\\\\@value
@value
\}
\} else \{ return \{\} \}
])"

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.5 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -31,7 +31,7 @@ value=\\"
format="tcleval(
[if \{[catch \{sim_is_@simulator \} retval] \} \{
return \{\} \} elseif \{$retval\} \{ return \{
\\\\@value
@value
\}
\} else \{ return \{\} \}
])"}

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.4 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -31,7 +31,8 @@ template="name=x1 m=1
+ VCCPIN=VCC VSSPIN=VSS"
extra="VCCPIN VSSPIN"
generic_type="m=integer wna=real lna=real wpa=real lpa=real wnb=real lnb=real wpb=real lpb=real VCCPIN=string VSSPIN=string"
verilog_stop=true}
verilog_stop=true
}
V {}
S {}
E {}

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.4 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -19,7 +19,8 @@ v {xschem version=3.4.4 file_version=1.2
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
G {type=subcircuit
G {}
K {type=subcircuit
vhdl_stop=true
verilog_stop=true
format="@name @pinlist @VCCPIN @VSSPIN @symname wna=@wna lna=@lna wpa=@wpa lpa=@lpa wnb=@wnb lnb=@lnb wpb=@wpb lpb=@lpb m=@m"

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.4 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -30,7 +30,8 @@ template="name=x1 m=1
+ VCCPIN=VCC VSSPIN=VSS"
extra="VCCPIN VSSPIN"
generic_type="m=integer wn=real lln=real wp=real lp=real VCCPIN=string VSSPIN=string"
verilog_stop=true}
verilog_stop=true
}
V {}
S {}
E {}

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.4 file_version=1.2
v {xschem version=3.4.6 file_version=1.2
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -19,7 +19,8 @@ v {xschem version=3.4.4 file_version=1.2
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
}
G {type=subcircuit
G {}
K {type=subcircuit
format="@name @pinlist @symname"
template="name=x1"
}