summaryrefslogtreecommitdiff
path: root/tclxcircuit.c
diff options
context:
space:
mode:
Diffstat (limited to 'tclxcircuit.c')
-rw-r--r--tclxcircuit.c475
1 files changed, 285 insertions, 190 deletions
diff --git a/tclxcircuit.c b/tclxcircuit.c
index 2c192bd..6e49bba 100644
--- a/tclxcircuit.c
+++ b/tclxcircuit.c
@@ -18,16 +18,15 @@
#include <tk.h>
+#ifdef HAVE_CAIRO
+#include <cairo/cairo-xlib.h>
+#endif
+
#ifndef _MSC_VER
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#endif
-#ifdef OPENGL
-#include <GL/gl.h>
-#include <GL/glx.h>
-#endif /* OPENGL */
-
#include "xcircuit.h"
#include "colordefs.h"
#include "menudep.h"
@@ -44,7 +43,6 @@ extern char _STR[150], _STR2[250];
extern XCWindowData *areawin;
extern Globaldata xobjs;
extern int number_colors;
-extern int *appcolors;
extern colorindex *colorlist;
extern Cursor appcursors[NUM_CURSORS];
extern ApplicationData appdata;
@@ -57,12 +55,6 @@ extern short flstart;
extern int pressmode;
extern u_char undo_collect;
-#ifdef OPENGL
-GLXContext grXcontext;
-XVisualInfo *grVisualInfo;
-float gl_line_limit, gl_point_limit;
-#endif /* OPENGL */
-
char STIPDATA[STIPPLES][4] = {
"\000\004\000\001",
"\000\005\000\012",
@@ -91,6 +83,25 @@ short flags = -1;
#endif
/*----------------------------------------------------------------------*/
+/* Procedure for waiting on X to map a window */
+/* This code copied from Tk sources, where it is used for the "tkwait" */
+/* command. */
+/*----------------------------------------------------------------------*/
+
+static void
+WaitVisibilityProc(ClientData clientData, XEvent *eventPtr)
+{
+ int *donePtr = (int *) clientData;
+
+ if (eventPtr->type == VisibilityNotify) {
+ *donePtr = 1;
+ }
+ if (eventPtr->type == DestroyNotify) {
+ *donePtr = 2;
+ }
+}
+
+/*----------------------------------------------------------------------*/
/* Deal with systems which don't define va_copy(). */
/*----------------------------------------------------------------------*/
@@ -483,8 +494,8 @@ int xctcl_eventmode(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
static char *modeNames[] = {
- "normal", "undo", "move", "copy", "pan", "selarea",
- "pending", "rescale", "catalog", "cattext",
+ "normal", "undo", "move", "copy", "pan",
+ "selarea", "rescale", "catalog", "cattext",
"fontcat", "efontcat", "text", "wire", "box",
"arc", "spline", "etext", "epoly", "earc",
"espline", "epath", "einst", "assoc", "catmove",
@@ -815,7 +826,15 @@ int GetXCStringFromList(Tcl_Interp *interp, Tcl_Obj *list, stringpart **rstring)
"string part types", TCL_EXACT, &idx) != TCL_OK) {
Tcl_ResetResult(interp);
idx = -1;
- result = Tcl_ListObjIndex(interp, lobj, 0, &tobj);
+
+ // If there's only one object and the first item doesn't match
+ // a stringpart itentifying word, then assume that "list" is a
+ // single text string.
+
+ if (numobjs == 1)
+ tobj = list;
+ else
+ result = Tcl_ListObjIndex(interp, lobj, 0, &tobj);
}
else {
result = Tcl_ListObjIndex(interp, lobj, (numparts > 1) ? 1 : 0, &tobj);
@@ -1360,9 +1379,9 @@ int xctcl_symschem(ClientData clientData, Tcl_Interp *interp,
return TCL_ERROR;
break;
case GoToIdx:
- /* This is supposed to specifically go to the specified type, */
- /* so don't call swapschem to change views if we're already */
- /* on the right view. */
+ /* This is supposed to specifically go to the specified type, */
+ /* so don't call swapschem to change views if we're already */
+ /* on the right view. */
if (topobject->schemtype == PRIMARY || topobject->schemtype == SECONDARY) {
if (!strncmp(Tcl_GetString(objv[0]), "sym", 3)) {
@@ -2405,7 +2424,7 @@ int xctcl_color(ClientData clientData, Tcl_Interp *interp,
break;
case IndexIdx:
- /* Return the index of the color */
+ /* Return the index of the color. For use with parameterized color */
if ((objc - nidx) == 2) {
result = GetColorFromObj(interp, objv[nidx + 1], &cindex, TRUE);
if (result != TCL_OK) return result;
@@ -2419,7 +2438,7 @@ int xctcl_color(ClientData clientData, Tcl_Interp *interp,
break;
case ValueIdx:
- /* Return the value of the color. For use with parameterized color */
+ /* Return the value of the color as an {R G B} list */
if ((objc - nidx) == 2) {
result = GetColorFromObj(interp, objv[nidx + 1], &cindex, TRUE);
if (result != TCL_OK) return result;
@@ -2427,7 +2446,7 @@ int xctcl_color(ClientData clientData, Tcl_Interp *interp,
Tcl_SetResult(interp, "Color index out of range", NULL);
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewIntObj(colorlist[cindex].color.pixel));
+ Tcl_SetObjResult(interp, TclIndexToRGB(cindex));
return TCL_OK;
}
else {
@@ -2441,7 +2460,7 @@ int xctcl_color(ClientData clientData, Tcl_Interp *interp,
if ((objc - nidx) == 2) {
option = Tcl_GetString(objv[nidx + 1]);
if (!strncmp(option, "-all", 4)) {
- for (i = 0; i < number_colors; i++) {
+ for (i = NUMBER_OF_COLORS; i < number_colors; i++) {
char colorstr[14];
sprintf(colorstr, "#%04x%04x%04x",
colorlist[i].color.red,
@@ -2468,7 +2487,7 @@ int xctcl_color(ClientData clientData, Tcl_Interp *interp,
if (ccol == DEFAULTCOLOR)
Tcl_SetObjResult(interp, Tcl_NewStringObj("inherit", 7));
else {
- for (i = 0; i < number_colors; i++)
+ for (i = NUMBER_OF_COLORS; i < number_colors; i++)
if (colorlist[i].color.pixel == ccol)
break;
Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
@@ -2739,15 +2758,15 @@ int xctcl_rotate(ClientData clientData, Tcl_Interp *interp,
objPtr = NULL;
if (SELECTTYPE(areawin->selectlist + i) == OBJINST) {
objinstptr pinst = SELTOOBJINST(areawin->selectlist + i);
- objPtr = Tcl_NewIntObj(pinst->rotation);
+ objPtr = Tcl_NewDoubleObj((double)(pinst->rotation));
}
else if (SELECTTYPE(areawin->selectlist + i) == LABEL) {
labelptr plab = SELTOLABEL(areawin->selectlist + i);
- objPtr = Tcl_NewIntObj(plab->rotation);
+ objPtr = Tcl_NewDoubleObj((double)(plab->rotation));
}
else if (SELECTTYPE(areawin->selectlist + i) == GRAPHIC) {
graphicptr gp = SELTOGRAPHIC(areawin->selectlist + i);
- objPtr = Tcl_NewIntObj(gp->rotation);
+ objPtr = Tcl_NewDoubleObj((double)(gp->rotation));
}
if (objPtr != NULL) {
if (numfound > 0)
@@ -2911,7 +2930,7 @@ char *
translateparamtype(int type)
{
const char *param_types[] = {"numeric", "substring", "x position",
- "y position", "style", "justification", "start angle", "end angle",
+ "y position", "style", "anchoring", "start angle", "end angle",
"radius", "minor axis", "rotation", "scale", "linewidth", "color",
"expression", "position", NULL};
@@ -2955,7 +2974,7 @@ int xctcl_param(ClientData clientData, Tcl_Interp *interp,
/* The order of these type names must match the enumeration in xcircuit.h */
static char *param_types[] = {"numeric", "substring", "x position",
- "y position", "style", "justification", "start angle", "end angle",
+ "y position", "style", "anchoring", "start angle", "end angle",
"radius", "minor axis", "rotation", "scale", "linewidth", "color",
"expression", "position", NULL}; /* (jdk) */
@@ -3353,6 +3372,7 @@ next_param:
}
/* Redraw everything (this could be finessed. . .) */
+ areawin->redraw_needed = True;
drawarea(areawin->area, (caddr_t)NULL, (caddr_t)NULL);
}
else {
@@ -3639,7 +3659,6 @@ int xctcl_deselect(ClientData clientData, Tcl_Interp *interp,
for (i = 0; i < areawin->selects; i++) {
short *newselect = areawin->selectlist + i;
if ((genericptr)ehandle == SELTOGENERIC(newselect)) {
- SetFunction(dpy, areawin->gc, GXcopy);
XTopSetForeground(SELTOCOLOR(newselect));
geneasydraw(*newselect, DEFAULTCOLOR, topobject,
areawin->topinstance);
@@ -3905,74 +3924,86 @@ int xctcl_object(ClientData clientData, Tcl_Interp *interp,
}
/*----------------------------------------------------------------------*/
-/* Get justification (or associated fields) global setting, or apply */
+/* Get anchoring (or associated fields) global setting, or apply */
/* to selected labels. */
/*----------------------------------------------------------------------*/
int
-getjustification(Tcl_Interp *interp, short bitfield)
+getanchoring(Tcl_Interp *interp, short bitfield)
{
int i, rval;
labelptr tlab;
if (areawin->selects == 0) {
if (bitfield & RIGHT) {
- Tcl_AppendElement(interp, (areawin->justify & RIGHT) ?
- "right" : (areawin->justify & NOTLEFT) ? "center" : "left");
+ Tcl_AppendElement(interp, (areawin->anchor & RIGHT) ?
+ "right" : (areawin->anchor & NOTLEFT) ? "center" : "left");
}
else if (bitfield & TOP) {
- Tcl_AppendElement(interp, (areawin->justify & TOP) ?
- "top" : (areawin->justify & NOTBOTTOM) ? "middle" : "bottom");
+ Tcl_AppendElement(interp, (areawin->anchor & TOP) ?
+ "top" : (areawin->anchor & NOTBOTTOM) ? "middle" : "bottom");
+ }
+ else if (bitfield & JUSTIFYRIGHT) {
+ Tcl_AppendElement(interp, (areawin->anchor & JUSTIFYRIGHT) ? "right" :
+ (areawin->anchor & TEXTCENTERED) ? "center" :
+ (areawin->anchor & JUSTIFYBOTH) ? "both" :
+ "left");
}
else {
- Tcl_AppendElement(interp, (areawin->justify & bitfield) ?
+ Tcl_AppendElement(interp, (areawin->anchor & bitfield) ?
"true" : "false");
}
- return (areawin->justify & bitfield);
+ return (areawin->anchor & bitfield);
}
for (i = 0; i < areawin->selects; i++) {
if (SELECTTYPE(areawin->selectlist + i) != LABEL) continue;
tlab = SELTOLABEL(areawin->selectlist + i);
if (bitfield == PINVISIBLE && tlab->pin == NORMAL) continue;
if (bitfield & RIGHT) {
- Tcl_AppendElement(interp, (tlab->justify & RIGHT) ?
- "right" : (tlab->justify & NOTLEFT) ? "center" : "left");
+ Tcl_AppendElement(interp, (tlab->anchor & RIGHT) ?
+ "right" : (tlab->anchor & NOTLEFT) ? "center" : "left");
}
else if (bitfield & TOP) {
- Tcl_AppendElement(interp, (tlab->justify & TOP) ?
- "top" : (tlab->justify & NOTBOTTOM) ? "middle" : "bottom");
+ Tcl_AppendElement(interp, (tlab->anchor & TOP) ?
+ "top" : (tlab->anchor & NOTBOTTOM) ? "middle" : "bottom");
+ }
+ else if (bitfield & JUSTIFYRIGHT) {
+ Tcl_AppendElement(interp, (tlab->anchor & JUSTIFYRIGHT) ? "right" :
+ (tlab->anchor & TEXTCENTERED) ? "center" :
+ (tlab->anchor & JUSTIFYBOTH) ? "both" :
+ "left");
}
else {
- Tcl_AppendElement(interp, (tlab->justify & bitfield) ? "true" : "false");
+ Tcl_AppendElement(interp, (tlab->anchor & bitfield) ? "true" : "false");
}
- rval = tlab->justify;
+ rval = tlab->anchor;
}
return (rval & bitfield);
}
/*----------------------------------------------------------------------*/
-/* Set justification (and associated fields) global setting, or apply */
+/* Set anchoring (and associated fields) global setting, or apply */
/* to selected labels. */
/*----------------------------------------------------------------------*/
void
-setjustification(short bitfield, short value)
+setanchoring(short bitfield, short value)
{
int i;
labelptr tlab;
if (areawin->selects == 0) {
- areawin->justify &= (~bitfield);
- if (value > 0) areawin->justify |= value;
+ areawin->anchor &= (~bitfield);
+ if (value > 0) areawin->anchor |= value;
return;
}
for (i = 0; i < areawin->selects; i++) {
if (SELECTTYPE(areawin->selectlist + i) != LABEL) continue;
tlab = SELTOLABEL(areawin->selectlist + i);
if (bitfield == PINVISIBLE && tlab->pin == NORMAL) continue;
- tlab->justify &= (~bitfield);
- if (value > 0) tlab->justify |= value;
+ tlab->anchor &= (~bitfield);
+ if (value > 0) tlab->anchor |= value;
}
}
@@ -3989,7 +4020,7 @@ translateencoding(int psfont)
{
const char *encValues[] = {"Standard", "special", "ISOLatin1",
"ISOLatin2", "ISOLatin3", "ISOLatin4", "ISOLatin5",
- "ISOLatin6", NULL};
+ "ISOLatin6", "ISO8859-5", NULL};
int i;
i = (fonts[psfont].flags & 0xf80) >> 7;
@@ -4026,11 +4057,12 @@ int xctcl_label(ClientData clientData, Tcl_Interp *interp,
Tcl_Obj *objPtr, *listPtr;
labelptr tlab;
- static char *subCmds[] = {"make", "type", "insert", "justify", "flipinvariant",
- "visible", "font", "scale", "encoding", "style", "family", "substring",
- "text", "latex", "list", "replace", "position", NULL};
+ static char *subCmds[] = {"make", "type", "insert", "anchor", "justify",
+ "flipinvariant", "visible", "font", "scale", "encoding", "style",
+ "family", "substring", "text", "latex", "list", "replace", "position",
+ NULL};
enum SubIdx {
- MakeIdx, TypeIdx, InsertIdx, JustIdx, FlipIdx, VisibleIdx,
+ MakeIdx, TypeIdx, InsertIdx, AnchorIdx, JustifyIdx, FlipIdx, VisibleIdx,
FontIdx, ScaleIdx, EncodingIdx, StyleIdx, FamilyIdx, SubstringIdx,
TextIdx, LaTeXIdx, ListIdx, ReplaceIdx, PositionIdx
};
@@ -4047,14 +4079,16 @@ int xctcl_label(ClientData clientData, Tcl_Interp *interp,
static int pinTypes[] = {NORMAL, NORMAL, LOCAL, LOCAL, GLOBAL, INFO, INFO};
- static char *justValues[] = {"left", "center", "right", "top", "middle",
+ static char *anchorValues[] = {"left", "center", "right", "top", "middle",
"bottom", NULL};
+ static char *justifyValues[] = {"left", "center", "right", "both", NULL};
+
const char *styValues[] = {"normal", "bold", "italic", "bolditalic", NULL};
const char *encValues[] = {"Standard", "special", "ISOLatin1",
"ISOLatin2", "ISOLatin3", "ISOLatin4", "ISOLatin5",
- "ISOLatin6", NULL};
+ "ISOLatin6", "ISO8859-5", NULL};
/* Tk "label" has been renamed to "tcl_label", but we want to */
/* consider the "label" command to be overloaded, such that the */
@@ -4143,7 +4177,8 @@ int xctcl_label(ClientData clientData, Tcl_Interp *interp,
&position)) != TCL_OK)
return result;
- newlab = new_label(NULL, strptr, idx2, position.x, position.y);
+ newlab = new_label(NULL, strptr, idx2, position.x, position.y,
+ (u_char)1);
singlebbox((genericptr *)&newlab);
objPtr = Tcl_NewHandleObj(newlab);
Tcl_SetObjResult(interp, objPtr);
@@ -4407,53 +4442,77 @@ int xctcl_label(ClientData clientData, Tcl_Interp *interp,
case VisibleIdx: /* Change visibility of pin */
if (objc == nidx + 1)
- jval = getjustification(interp, PINVISIBLE);
+ jval = getanchoring(interp, PINVISIBLE);
else {
if ((result = Tcl_GetBooleanFromObj(interp, objv[nidx + 1],
&value)) != TCL_OK)
return result;
if (jval != value)
- setjustification(PINVISIBLE, (value) ? PINVISIBLE : NORMAL);
+ setanchoring(PINVISIBLE, (value) ? PINVISIBLE : NORMAL);
}
break;
case FlipIdx:
if (objc == nidx + 1)
- jval = getjustification(interp, FLIPINV);
+ jval = getanchoring(interp, FLIPINV);
else {
if ((result = Tcl_GetBooleanFromObj(interp, objv[nidx + 1],
&value)) != TCL_OK)
return result;
if (jval != value)
- setjustification(FLIPINV, (value) ? FLIPINV : NORMAL);
+ setanchoring(FLIPINV, (value) ? FLIPINV : NORMAL);
}
break;
case LaTeXIdx:
if (objc == nidx + 1)
- jval = getjustification(interp, LATEXLABEL);
+ jval = getanchoring(interp, LATEXLABEL);
else {
if ((result = Tcl_GetBooleanFromObj(interp, objv[nidx + 1],
&value)) != TCL_OK)
return result;
if (jval != value)
- setjustification(LATEXLABEL, (value) ? LATEXLABEL : NORMAL);
+ setanchoring(LATEXLABEL, (value) ? LATEXLABEL : NORMAL);
}
break;
- case JustIdx:
+ case JustifyIdx:
if (objc == nidx + 1) {
- jval = getjustification(interp, RIGHT | NOTLEFT);
- jval2 = getjustification(interp, TOP | NOTBOTTOM);
+ jval = getanchoring(interp, JUSTIFYRIGHT | JUSTIFYBOTH | TEXTCENTERED);
}
else {
if (Tcl_GetIndexFromObj(interp, objv[nidx + 1],
- (CONST84 char **)justValues,
+ (CONST84 char **)justifyValues,
"justification", 0, &idx2) != TCL_OK) {
return TCL_ERROR;
}
switch (idx2) {
case 0: value = NORMAL; break;
+ case 1: value = TEXTCENTERED; break;
+ case 2: value = JUSTIFYRIGHT; break;
+ case 3: value = JUSTIFYBOTH; break;
+ }
+ jval = getanchoring(interp, JUSTIFYRIGHT | JUSTIFYBOTH | TEXTCENTERED);
+ if (jval != value) {
+ setanchoring(JUSTIFYRIGHT | JUSTIFYBOTH | TEXTCENTERED, value);
+ refresh(NULL, NULL, NULL);
+ }
+ }
+ break;
+
+ case AnchorIdx:
+ if (objc == nidx + 1) {
+ jval = getanchoring(interp, RIGHT | NOTLEFT);
+ jval2 = getanchoring(interp, TOP | NOTBOTTOM);
+ }
+ else {
+ if (Tcl_GetIndexFromObj(interp, objv[nidx + 1],
+ (CONST84 char **)anchorValues,
+ "anchoring", 0, &idx2) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (idx2) {
+ case 0: value = NORMAL; break;
case 1: value = NOTLEFT; break;
case 2: value = NOTLEFT | RIGHT; break;
case 3: value = NOTBOTTOM | TOP; break;
@@ -4462,16 +4521,16 @@ int xctcl_label(ClientData clientData, Tcl_Interp *interp,
}
switch (idx2) {
case 0: case 1: case 2:
- jval = getjustification(interp, RIGHT | NOTLEFT);
+ jval = getanchoring(interp, RIGHT | NOTLEFT);
if (jval != value) {
- setjustification(RIGHT | NOTLEFT, value);
+ setanchoring(RIGHT | NOTLEFT, value);
refresh(NULL, NULL, NULL);
}
break;
case 3: case 4: case 5:
- jval2 = getjustification(interp, TOP | NOTBOTTOM);
+ jval2 = getanchoring(interp, TOP | NOTBOTTOM);
if (jval2 != value) {
- setjustification(TOP | NOTBOTTOM, value);
+ setanchoring(TOP | NOTBOTTOM, value);
refresh(NULL, NULL, NULL);
}
break;
@@ -5274,7 +5333,9 @@ int xctcl_graphic(ClientData clientData, Tcl_Interp *interp,
oldscale = gp->scale;
gp->scale = (float)dvalue;
if (gp->scale != oldscale) {
+#ifndef HAVE_CAIRO
gp->valid = False;
+#endif /* !HAVE_CAIRO */
drawarea(areawin->area, (caddr_t)clientData, (caddr_t)NULL);
calcbboxvalues(areawin->topinstance,
topobject->plist + *(areawin->selectlist + i));
@@ -6447,13 +6508,14 @@ int xctcl_config(ClientData clientData, Tcl_Interp *interp,
/* Give it the same page number and view as the current window */
if (objc == 3) {
- XCWindowData *newwin;
+ XCWindowData *newwin, *savewin;
+ savewin = areawin; // In case focus callback overwrites areawin.
newwin = GUI_init(objc - 2, objv + 2);
if (newwin != NULL) {
- newwin->page = areawin->page;
- newwin->vscale = areawin->vscale;
- newwin->pcorner = areawin->pcorner;
- newwin->topinstance = areawin->topinstance;
+ newwin->page = savewin->page;
+ newwin->vscale = savewin->vscale;
+ newwin->pcorner = savewin->pcorner;
+ newwin->topinstance = savewin->topinstance;
}
else {
Tcl_SetResult(interp, "Unable to create new window structure\n", NULL);
@@ -6481,6 +6543,10 @@ int xctcl_config(ClientData clientData, Tcl_Interp *interp,
objectptr savestack;
if (areawin == winptr) break;
+ else if (areawin == NULL) {
+ areawin = winptr;
+ break;
+ }
if ((eventmode == MOVE_MODE || eventmode == COPY_MODE) &&
winptr->editstack->parts == 0) {
locsave = areawin->save;
@@ -7006,7 +7072,13 @@ int xctcl_quit(ClientData clientData, Tcl_Interp *interp,
return TCL_ERROR;
}
quit(areawin->area, NULL);
- return XcTagCallback(interp, objc, objv);
+
+ if (consoleinterp == interp)
+ Tcl_Exit(XcTagCallback(interp, objc, objv));
+ else
+ Tcl_Eval(interp, "catch {tkcon eval exit}\n");
+
+ return TCL_OK; /* Not reached */
}
/*----------------------------------------------------------------------*/
@@ -7014,13 +7086,23 @@ int xctcl_quit(ClientData clientData, Tcl_Interp *interp,
int xctcl_promptquit(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[])
{
+ int result;
+
/* quit, with checks */
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
return TCL_ERROR;
}
- if (areawin != NULL)
- quitcheck(areawin->area, NULL, NULL);
+ if (areawin != NULL) {
+ result = quitcheck(areawin->area, NULL, NULL);
+ if (result == 1) {
+ /* Immediate exit */
+ if (consoleinterp == interp)
+ Tcl_Exit(XcTagCallback(interp, objc, objv));
+ else
+ Tcl_Eval(interp, "catch {tkcon eval exit}\n");
+ }
+ }
return XcTagCallback(interp, objc, objv);
}
@@ -7034,6 +7116,7 @@ int xctcl_refresh(ClientData clientData, Tcl_Interp *interp,
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
return TCL_ERROR;
}
+ areawin->redraw_needed = True;
drawarea(areawin->area, (caddr_t)clientData, (caddr_t)NULL);
if (areawin->scrollbarh)
drawhbar(areawin->scrollbarh, NULL, NULL);
@@ -7058,6 +7141,7 @@ int loadlinkfile(objinstptr tinst, char *filename, int target, Boolean do_load)
FILE *ps;
char file_return[150];
int result;
+ Boolean fgood;
/* Shorthand: "%n" can be used to indicate that the link filename is */
/* the same as the name of the object, minus technology prefix. */
@@ -7085,36 +7169,41 @@ int loadlinkfile(objinstptr tinst, char *filename, int target, Boolean do_load)
ps = fileopen(_STR, ".ps", file_return, 149);
if (ps != NULL) {
+ fgood = TRUE;
fclose(ps);
- for (j = 0; j < xobjs.pages; j++) {
- if (xobjs.pagelist[j]->filename == NULL)
- continue;
- else if (!strcmp(file_return, xobjs.pagelist[j]->filename))
- break;
- else if ((strlen(xobjs.pagelist[j]->filename) > 0) &&
+ }
+ else
+ fgood = FALSE;
+
+ for (j = 0; j < xobjs.pages; j++) {
+ if (xobjs.pagelist[j]->filename == NULL)
+ continue;
+ else if (!strcmp(file_return, xobjs.pagelist[j]->filename))
+ break;
+ else if ((strlen(xobjs.pagelist[j]->filename) > 0) &&
!strcmp(file_return + strlen(file_return) - 3, ".ps")
&& !strncmp(xobjs.pagelist[j]->filename, file_return,
strlen(file_return) - 3))
- break;
- else if ((xobjs.pagelist[j]->pageinst != NULL) && (tinst->thisobject ==
+ break;
+ else if ((xobjs.pagelist[j]->pageinst != NULL) && (tinst->thisobject ==
xobjs.pagelist[j]->pageinst->thisobject->symschem))
- break;
- }
- if (j < xobjs.pages) {
+ break;
+ }
+ if (j < xobjs.pages) {
- /* Duplicate page. Don't load it, but make sure that an association */
- /* exists between the symbol and schematic. */
+ /* Duplicate page. Don't load it, but make sure that an association */
+ /* exists between the symbol and schematic. */
- if (tinst->thisobject->symschem == NULL) {
- tinst->thisobject->symschem =
+ if (tinst->thisobject->symschem == NULL) {
+ tinst->thisobject->symschem =
xobjs.pagelist[j]->pageinst->thisobject;
- if (xobjs.pagelist[j]->pageinst->thisobject->symschem == NULL)
+ if (xobjs.pagelist[j]->pageinst->thisobject->symschem == NULL)
xobjs.pagelist[j]->pageinst->thisobject->symschem = tinst->thisobject;
- }
- return 0;
}
+ return 0;
}
- else {
+
+ if (fgood == FALSE) {
Fprintf(stderr, "Failed to open dependency \"%s\"\n", _STR);
return -1;
}
@@ -7173,13 +7262,13 @@ int xctcl_page(ClientData clientData, Tcl_Interp *interp,
"load", "list", "import", "save", "saveonly", "make", "directory",
"reset", "links", "fit", "filename", "label", "scale", "width",
"height", "size", "margins", "bbox", "goto", "orientation",
- "encapsulation", "handle", "changes", NULL
+ "encapsulation", "handle", "update", "changes", NULL
};
enum SubIdx {
LoadIdx, ListIdx, ImportIdx, SaveIdx, SaveOnlyIdx, MakeIdx, DirIdx,
ResetIdx, LinksIdx, FitIdx, FileIdx, LabelIdx, ScaleIdx,
WidthIdx, HeightIdx, SizeIdx, MarginsIdx, BBoxIdx, GoToIdx,
- OrientIdx, EPSIdx, HandleIdx, ChangesIdx
+ OrientIdx, EPSIdx, HandleIdx, UpdateIdx, ChangesIdx
};
char *importTypes[] = {"xcircuit", "postscript", "background", "spice", NULL};
@@ -7568,6 +7657,11 @@ int xctcl_page(ClientData clientData, Tcl_Interp *interp,
newpage((short)pageno);
break;
+ case UpdateIdx:
+ calcbbox(curpage->pageinst);
+ if (curpage->pmode & 2) autoscale(pageno);
+ break;
+
case BBoxIdx:
if (((objc - nidx) == 2) || ((objc - nidx) == 3)) {
Tcl_Obj *tuple;
@@ -8305,7 +8399,7 @@ int xctcl_library(ClientData clientData, Tcl_Interp *interp,
{
char *filename = NULL, *objname, *argv;
int j = 0, libnum = -1;
- int idx, nidx, result;
+ int idx, nidx, result, res;
Tcl_Obj *olist;
Tcl_Obj **newobjv;
int newobjc, hidmode;
@@ -8339,8 +8433,10 @@ int xctcl_library(ClientData clientData, Tcl_Interp *interp,
lname = xobjs.libtop[libnum + LIBRARY]->thisobject->name;
Tcl_SetObjResult(interp, Tcl_NewStringObj(lname, strlen(lname)));
}
- else
+ else {
+ result = TCL_OK;
Tcl_SetObjResult(interp, Tcl_NewIntObj(libnum + 1));
+ }
}
else
Tcl_SetObjResult(interp, Tcl_NewIntObj(libnum + 1));
@@ -8380,7 +8476,7 @@ int xctcl_library(ClientData clientData, Tcl_Interp *interp,
/* if loading of default libraries is not overridden, load them first */
if (!(flags & (LIBOVERRIDE | LIBLOADED))) {
- defaultscript();
+ result = defaultscript();
flags |= LIBLOADED;
}
@@ -8413,11 +8509,11 @@ int xctcl_library(ClientData clientData, Tcl_Interp *interp,
}
strcpy(_STR, filename);
- result = loadlibrary(libnum);
- if (result == False) {
- result = loadfile(2, libnum);
+ res = loadlibrary(libnum);
+ if (res == False) {
+ res = loadfile(2, libnum);
TechReplaceRestore();
- if (result == False) {
+ if (res == False) {
Tcl_SetResult(interp, "Error loading library.\n", NULL);
return TCL_ERROR;
}
@@ -8566,7 +8662,7 @@ int xctcl_library(ClientData clientData, Tcl_Interp *interp,
return TCL_OK; /* no tag callback */
break;
}
- return XcTagCallback(interp, objc, objv);
+ return (result == TCL_OK) ? XcTagCallback(interp, objc, objv) : result;
}
/*----------------------------------------------------------------------*/
@@ -8719,7 +8815,7 @@ int xctcl_bind(ClientData clientData, Tcl_Interp *interp,
Tcl_SetResult(interp, "Key is already bound to a command.\n", NULL);
return (result);
}
- return XcTagCallback(interp, objc, objv);
+ return (result == TCL_OK) ? XcTagCallback(interp, objc, objv) : result;
}
/*----------------------------------------------------------------------*/
@@ -8834,10 +8930,11 @@ short execcommand(short pflags, char *cmdptr)
/* loading of the startup script) */
/*----------------------------------------------------------------------*/
-void defaultscript()
+int defaultscript()
{
FILE *fd;
char *tmp_s = getenv((const char *)"XCIRCUIT_SRC_DIR");
+ int result;
flags = LIBOVERRIDE | LIBLOADED | FONTOVERRIDE;
@@ -8855,7 +8952,8 @@ void defaultscript()
}
}
fclose(fd);
- Tcl_EvalFile(xcinterp, _STR2);
+ result = Tcl_EvalFile(xcinterp, _STR2);
+ return result;
}
/*----------------------------------------------------------------------*/
@@ -8927,8 +9025,8 @@ Tcl_Obj *evaluate_raw(objectptr thisobj, oparamptr ops, objinstptr pinst,
if ((ips == NULL) && !strncmp(pptr, "p_", 2)) {
ips = &temps;
if (!strcmp(pptr + 2, "rotation")) {
- temps.type = XC_INT;
- temps.parameter.ivalue = pinst ? pinst->rotation : 0;
+ temps.type = XC_FLOAT;
+ temps.parameter.fvalue = pinst ? pinst->rotation : 0;
}
else if (!strcmp(pptr + 2, "xposition")) {
temps.type = XC_INT;
@@ -8955,8 +9053,8 @@ Tcl_Obj *evaluate_raw(objectptr thisobj, oparamptr ops, objinstptr pinst,
UTopDrawingOffset(NULL, &temps.parameter.ivalue);
}
else if (!strcmp(pptr + 2, "top_rotation")) {
- temps.type = XC_INT;
- temps.parameter.ivalue = UTopRotation();
+ temps.type = XC_FLOAT;
+ temps.parameter.fvalue = UTopRotation();
}
else if (!strcmp(pptr + 2, "top_scale")) {
temps.type = XC_FLOAT;
@@ -9128,11 +9226,12 @@ char *evaluate_expr(objectptr thisobj, oparamptr ops, objinstptr pinst)
/* Execute the .xcircuitrc startup script */
/*----------------------------------------------------------------------*/
-void loadrcfile()
+int loadrcfile()
{
char *userdir = getenv((const char *)"HOME");
FILE *fd;
short i;
+ int result, result1 = TCL_OK;
/* Initialize flags */
@@ -9167,10 +9266,14 @@ void loadrcfile()
}
if (fd != NULL) {
fclose(fd);
- Tcl_EvalFile(xcinterp, _STR2);
+ result = Tcl_EvalFile(xcinterp, _STR2);
+ if (result != TCL_OK) {
+ Fprintf(stderr, "Encountered error in startup file.");
+ Fprintf(stderr, "%s\n", Tcl_GetStringResult(xcinterp));
+ Fprintf(stderr, "Running default startup script instead.\n");
+ }
}
-
/* Add the default font if not loaded already */
if (!(flags & FONTOVERRIDE)) {
@@ -9188,8 +9291,8 @@ void loadrcfile()
/* arrange the loaded libraries */
- if (!(flags & (LIBOVERRIDE | LIBLOADED))) {
- defaultscript();
+ if ((result != TCL_OK) || !(flags & (LIBOVERRIDE | LIBLOADED))) {
+ result1 = defaultscript();
}
/* Add the default colors */
@@ -9214,14 +9317,16 @@ void loadrcfile()
/* These colors must be enabled whether or not colors are overridden, */
/* because they are needed by the schematic capture system. */
- addnewcolorentry(xc_getlayoutcolor(LOCALPINCOLOR));
- addnewcolorentry(xc_getlayoutcolor(GLOBALPINCOLOR));
- addnewcolorentry(xc_getlayoutcolor(INFOLABELCOLOR));
- addnewcolorentry(xc_getlayoutcolor(RATSNESTCOLOR));
- addnewcolorentry(xc_getlayoutcolor(BBOXCOLOR));
+ // addnewcolorentry(xc_getlayoutcolor(LOCALPINCOLOR));
+ // addnewcolorentry(xc_getlayoutcolor(GLOBALPINCOLOR));
+ // addnewcolorentry(xc_getlayoutcolor(INFOLABELCOLOR));
+ // addnewcolorentry(xc_getlayoutcolor(RATSNESTCOLOR));
+ // addnewcolorentry(xc_getlayoutcolor(BBOXCOLOR));
- if (!(flags & KEYOVERRIDE))
+ if ((result != TCL_OK) || !(flags & KEYOVERRIDE)) {
default_keybindings();
+ }
+ return (result1 != TCL_OK) ? result1 : result;
}
/*----------------------------------------------------------------------*/
@@ -9346,7 +9451,8 @@ int xctcl_action(ClientData clientData,
void xctk_drawarea(ClientData clientData, XEvent *eventPtr)
{
Tcl_ServiceAll();
- drawarea(areawin->area, (caddr_t)clientData, (caddr_t)NULL);
+ if (areawin->topinstance != NULL)
+ drawarea(areawin->area, (caddr_t)clientData, (caddr_t)NULL);
}
/*----------------------------------------------------------------------*/
@@ -9385,28 +9491,32 @@ void xctk_panvbar(ClientData clientData, XEvent *eventPtr)
void xctk_drawhbar(ClientData clientData, XEvent *eventPtr)
{
- drawhbar(areawin->scrollbarh, (caddr_t)clientData, (caddr_t)NULL);
+ if (areawin->topinstance)
+ drawhbar(areawin->scrollbarh, (caddr_t)clientData, (caddr_t)NULL);
}
/*----------------------------------------------------------------------*/
void xctk_drawvbar(ClientData clientData, XEvent *eventPtr)
{
- drawvbar(areawin->scrollbarv, (caddr_t)clientData, (caddr_t)NULL);
+ if (areawin->topinstance)
+ drawvbar(areawin->scrollbarv, (caddr_t)clientData, (caddr_t)NULL);
}
/*----------------------------------------------------------------------*/
void xctk_endhbar(ClientData clientData, XEvent *eventPtr)
{
- endhbar(areawin->scrollbarh, (caddr_t)clientData, (XButtonEvent *)eventPtr);
+ if (areawin->topinstance)
+ endhbar(areawin->scrollbarh, (caddr_t)clientData, (XButtonEvent *)eventPtr);
}
/*----------------------------------------------------------------------*/
void xctk_endvbar(ClientData clientData, XEvent *eventPtr)
{
- endvbar(areawin->scrollbarv, (caddr_t)clientData, (XButtonEvent *)eventPtr);
+ if (areawin->topinstance)
+ endvbar(areawin->scrollbarv, (caddr_t)clientData, (XButtonEvent *)eventPtr);
}
/*----------------------------------------------------------------------*/
@@ -9431,6 +9541,10 @@ void xctk_drag(ClientData clientData, XEvent *eventPtr)
drag((int)b_event->x, (int)b_event->y);
flusharea();
+#ifdef HAVE_CAIRO
+ if (areawin->redraw_needed)
+ drawarea(NULL, NULL, NULL);
+#endif /* HAVE_CAIRO */
}
/*----------------------------------------------------------------------*/
@@ -9662,7 +9776,7 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
{
Tk_Window tkwind, tktop, tkdraw, tksb;
Tk_Window wsymb, wschema, corner;
- int i, locobjc;
+ int i, locobjc, done = 1;
XGCValues values;
Window win;
popupstruct *fileliststruct;
@@ -9670,13 +9784,6 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
char winpath[512];
XCWindowData *newwin;
-#ifdef OPENGL
- int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
- GLfloat params[2];
- GLenum errnum;
- int n;
-#endif
-
tktop = Tk_MainWindow(xcinterp);
if (tktop == (Tk_Window)NULL) {
Fprintf(stderr, "No Top-Level Tk window available. . .\n");
@@ -9786,26 +9893,41 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
(Tk_EventProc *)xctk_swapschem, Number(0));
Tk_CreateEventHandler(wschema, ButtonPressMask,
(Tk_EventProc *)xctk_swapschem, Number(0));
- }
- /* Setup event handlers for the drawing area and scrollbars */
- /* There are purposely no callback functions for these windows---they are */
- /* defined as type "simple" to keep down the cruft, as I will define my own */
- /* event handlers. */
+ /* Setup event handlers for the drawing area and scrollbars */
+ /* There are purposely no callback functions for these windows---they are */
+ /* defined as type "simple" to keep down the cruft, as I will define my */
+ /* own event handlers. */
- if (locobjc > 0) {
Tk_CreateEventHandler(newwin->area, StructureNotifyMask,
(Tk_EventProc *)xctk_resizearea, NULL);
Tk_CreateEventHandler(newwin->area, ExposureMask,
(Tk_EventProc *)xctk_drawarea, NULL);
}
+ if ((locobjc > 0) || !Tk_IsMapped(newwin->area)) {
+
+ /* This code copied from code for the "tkwait" command */
+
+ Tk_CreateEventHandler(newwin->area,
+ VisibilityChangeMask|StructureNotifyMask,
+ WaitVisibilityProc, (ClientData) &done);
+ done = 0;
+ }
+
/* Make sure the window is mapped */
Tk_MapWindow(tkwind);
win = Tk_WindowId(tkwind);
-
Tk_MapWindow(newwin->area);
+
+ if (!done) {
+ while (!done) Tcl_DoOneEvent(0);
+ Tk_DeleteEventHandler(newwin->area,
+ VisibilityChangeMask|StructureNotifyMask,
+ WaitVisibilityProc, (ClientData) &done);
+ }
+
newwin->window = Tk_WindowId(newwin->area);
newwin->width = Tk_Width(newwin->area);
newwin->height = Tk_Height(newwin->area);
@@ -9830,9 +9952,8 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
/* Allocate space for the basic color map */
/*----------------------------------------*/
- number_colors = 0;
- colorlist = (colorindex *)malloc(sizeof(colorindex));
- appcolors = (int *) malloc(NUMBER_OF_COLORS * sizeof(int));
+ number_colors = NUMBER_OF_COLORS;
+ colorlist = (colorindex *)malloc(NUMBER_OF_COLORS * sizeof(colorindex));
areawin = newwin;
build_app_database(tkwind);
areawin = NULL;
@@ -9867,37 +9988,6 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
Tk_CreateEventHandler(tkdraw, LeaveWindowMask,
(Tk_EventProc *)xctk_endfiletrack, (ClientData)tkdraw);
}
-
- /* OpenGL setup */
-
-#ifdef OPENGL
- grVisualInfo = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
- grXcontext = glXCreateContext(dpy, grVisualInfo, NULL, GL_FALSE);
-
- glLineWidth(1.0);
- glShadeModel(GL_FLAT);
- glPixelStorei(GL_PACK_LSB_FIRST, TRUE);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
-
- /* Check OpenGL line and point size limits. */
- /* Note that one has to do glXMakeCurrent() for the values */
- /* returned by glGet*() to be meaningful! */
-
- glXMakeCurrent(dpy, (GLXDrawable)win, grXcontext);
- params[0] = params[1] = 0.0;
- glGetFloatv(GL_LINE_WIDTH_RANGE, (GLfloat *)params);
- errnum = glGetError();
- if (errnum != GL_NO_ERROR) Fprintf(stdout, "Error %d\n", errnum);
- gl_line_limit = (float)params[1];
- Fprintf(stdout, "line limits: %g and %g\n", (float)params[0], gl_line_limit);
- /* glGetFloatv(GL_POINT_SIZE_RANGE, params); */
- glGetFloatv(GL_POINT_SIZE_RANGE, (GLfloat *)params);
- gl_point_limit = (float)params[1];
- Fprintf(stdout, "point limits: %g and %g\n", (float)params[0], gl_point_limit);
-
-#endif /* OPENGL */
}
/*-------------------------------------------------------------------*/
@@ -9914,6 +10004,11 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
newwin->gc = XCreateGC(dpy, win, GCForeground | GCBackground
| GCGraphicsExposures, &values);
+#ifdef HAVE_CAIRO
+ newwin->surface = cairo_xlib_surface_create(dpy, newwin->window,
+ DefaultVisual(dpy, 0), newwin->width, newwin->height);
+ newwin->cr = cairo_create(newwin->surface);
+#else /* HAVE_CAIRO */
newwin->clipmask = XCreatePixmap(dpy, win, newwin->width,
newwin->height, 1);
@@ -9921,6 +10016,7 @@ XCWindowData *GUI_init(int objc, Tcl_Obj *CONST objv[])
values.background = 0;
newwin->cmgc = XCreateGC(dpy, newwin->clipmask, GCForeground
| GCBackground, &values);
+#endif /* HAVE_CAIRO */
XDefineCursor (dpy, win, *newwin->defaultcursor);
return newwin;
@@ -9953,9 +10049,7 @@ int xctcl_start(ClientData clientData, Tcl_Interp *interp,
}
post_initialize();
-#ifndef OPENGL
ghostinit();
-#endif
/* The Tcl version accepts some command-line arguments. Due */
/* to the way ".wishrc" is processed, all arguments are */
@@ -10000,19 +10094,19 @@ int xctcl_start(ClientData clientData, Tcl_Interp *interp,
for (argc = 0; argc < objc; argc++) {
argv = Tcl_GetString(objv[argc]);
- if (*argv == '-') {
+ if (*argv == '-') {
if (!strncmp(argv, "-exec", 5)) {
if (++argc < objc) {
argv = Tcl_GetString(objv[argc]);
- result = Tcl_EvalFile(interp, argv);
- if (result != TCL_OK)
+ result = Tcl_EvalFile(interp, argv);
+ if (result != TCL_OK)
return result;
- else
+ else
rcoverride = True;
}
else {
- Tcl_SetResult(interp, "No filename given to exec argument.", NULL);
- return TCL_ERROR;
+ Tcl_SetResult(interp, "No filename given to exec argument.", NULL);
+ return TCL_ERROR;
}
}
else if (!strncmp(argv, "-2", 2)) {
@@ -10024,7 +10118,8 @@ int xctcl_start(ClientData clientData, Tcl_Interp *interp,
}
}
- if (!rcoverride) loadrcfile();
+ if (!rcoverride)
+ result = loadrcfile();
composelib(PAGELIB); /* make sure we have a valid page list */
composelib(LIBLIB); /* and library directory */
@@ -10057,7 +10152,7 @@ int xctcl_start(ClientData clientData, Tcl_Interp *interp,
drawarea(areawin->area, NULL, NULL);
/* Return back to the interpreter; Tk is handling the GUI */
- return XcTagCallback(interp, 1, &cmdname);
+ return (result == TCL_OK) ? XcTagCallback(interp, 1, &cmdname) : result;
}
/*--------------------------------------------------------------*/