diff options
Diffstat (limited to 'tclxcircuit.c')
-rw-r--r-- | tclxcircuit.c | 475 |
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; } /*--------------------------------------------------------------*/ |