]> granicus.if.org Git - graphviz/commitdiff
get all players using same context struct, both with and w/o cgraph
authorJohn Ellson <ellson@research.att.com>
Mon, 27 Feb 2012 21:02:54 +0000 (16:02 -0500)
committerJohn Ellson <ellson@research.att.com>
Mon, 27 Feb 2012 21:02:54 +0000 (16:02 -0500)
tclpkg/tcldot/tcldot.c

index 65d073804fb7065bf195220336a30d475a16c5be..63d4c8b5c67edadc888b7b9fe2117dac2a073711 100644 (file)
@@ -40,38 +40,48 @@ Tcl_GetString(Tcl_Obj *obj) {
 #endif
 ********* */
 
-/*  Globals */
-
+typedef struct {
 #ifdef WITH_CGRAPH
-static Tcl_Interp *myiddisc_usercontext;
+    Agdisc_t mydisc;    // must be first to allow casting mydisc to mycontext
 #endif
-static void *graphTblPtr, *nodeTblPtr, *edgeTblPtr;
+    void *graphTblPtr, *nodeTblPtr, *edgeTblPtr;
+    Tcl_Interp *interp;
+    GVC_t *gvc;
+} mycontext_t;
+
+/*  Globals */
+
 #if HAVE_LIBGD
 extern void *GDHandleTable;
 extern int Gdtclft_Init(Tcl_Interp *);
 #endif
 
 #ifndef WITH_CGRAPH
+#undef AGID
 #define AGID(x) ((x)->handle)
 #endif
 
 
 #ifdef WITH_CGRAPH
-static void *myiddisc_open(Agraph_t *g) {
+static void *myiddisc_open(Agraph_t *g, Agdisc_t *disc) {
        fprintf(stderr,"myiddisc_open:\n");
-        return NIL(void*);
+        return (void *)disc;
 }
 static long myiddisc_map(void *state, int objtype, char *str, unsigned long *id, int createflag) {
+       mycontext_t *mycontext = (mycontext_t *)state;
+
         switch (objtype) {
-                case AGRAPH: tclhandleAlloc(graphTblPtr, Tcl_GetStringResult(myiddisc_usercontext), id); break;
-                case AGNODE: tclhandleAlloc(nodeTblPtr, Tcl_GetStringResult(myiddisc_usercontext), id); break;
+                case AGRAPH: tclhandleAlloc(mycontext->graphTblPtr, Tcl_GetStringResult(mycontext->interp), id); break;
+                case AGNODE: tclhandleAlloc(mycontext->nodeTblPtr, Tcl_GetStringResult(mycontext->interp), id); break;
                 case AGINEDGE:
-                case AGOUTEDGE: tclhandleAlloc(edgeTblPtr, Tcl_GetStringResult(myiddisc_usercontext), id); break;
+                case AGOUTEDGE: tclhandleAlloc(mycontext->edgeTblPtr, Tcl_GetStringResult(mycontext->interp), id); break;
         }
         fprintf(stderr,"myiddisc_map: objtype %d, str \"%s\", id %lu, createflag %d\n", objtype, str, *id, createflag);
         return 1;
 }
 static long myiddisc_alloc(void *state, int objtype, unsigned long id) {
+//     mycontext_t *mycontext = (mycontext_t *)state;
+
         switch (objtype) {
                 case AGRAPH: break;
                 case AGNODE: break;
@@ -82,15 +92,19 @@ static long myiddisc_alloc(void *state, int objtype, unsigned long id) {
         return 0;
 }
 static void myiddisc_free(void *state, int objtype, unsigned long id) {
+       mycontext_t *mycontext = (mycontext_t *)state;
+
         switch (objtype) {
-                case AGRAPH: tclhandleFreeIndex(graphTblPtr, id); break;
-                case AGNODE: tclhandleFreeIndex(nodeTblPtr, id); break;
+                case AGRAPH: tclhandleFreeIndex(mycontext->graphTblPtr, id); break;
+                case AGNODE: tclhandleFreeIndex(mycontext->nodeTblPtr, id); break;
                 case AGINEDGE:
-                case AGOUTEDGE: tclhandleFreeIndex(edgeTblPtr, id); break;
+                case AGOUTEDGE: tclhandleFreeIndex(mycontext->edgeTblPtr, id); break;
         }
         fprintf(stderr,"myiddisc_free: objtype %d, id %lu\n", objtype, id);
 }
 static char *myiddisc_print(void *state, int objtype, unsigned long id) {
+//     mycontext_t *mycontext = (mycontext_t *)state;
+#if 0
         static char buf[64];
         switch (objtype) {
                 case AGRAPH: sprintf(buf, "graph%lu", id); break;
@@ -100,11 +114,14 @@ static char *myiddisc_print(void *state, int objtype, unsigned long id) {
         }
         fprintf(stderr,"myiddisc_print: objtype %d, id %lu\n", objtype, id);
         return buf;
+#else
+       return NIL(char*);
+#endif
 }
 static void myiddisc_close(void *state) {
+//     mycontext_t *mycontext = (mycontext_t *)state;
         fprintf(stderr,"myiddisc_close:\n");
 }
-
 static Agiddisc_t myiddisc = {
         myiddisc_open,
         myiddisc_map,
@@ -113,11 +130,6 @@ static Agiddisc_t myiddisc = {
         myiddisc_print,
         myiddisc_close
 };
-static Agdisc_t mydisc = {
-        NIL(Agmemdisc_t *),
-        &myiddisc,
-        NIL(Agiodisc_t *)
-};
 
 #endif // WITH_CGRAPH
 
@@ -142,39 +154,39 @@ static void reset_layout(GVC_t *gvc, Agraph_t * sg)
     }
 }
 
-static void deleteEdges(Tcl_Interp * interp, Agraph_t * g, Agnode_t * n)
+static void deleteEdges(mycontext_t * mycontext, Agraph_t * g, Agnode_t * n)
 {
     Agedge_t **ep, *e, *e1;
     char buf[16];
 
     e = agfstedge(g, n);
     while (e) {
-       tclhandleString(edgeTblPtr, buf, AGID(e));
-       Tcl_DeleteCommand(interp, buf);
-       ep = (Agedge_t **) tclhandleXlateIndex(edgeTblPtr, AGID(e));
+       tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
+       Tcl_DeleteCommand(mycontext->interp, buf);
+       ep = (Agedge_t **) tclhandleXlateIndex(mycontext->edgeTblPtr, AGID(e));
        if (!ep)
            fprintf(stderr, "Bad entry in edgeTbl\n");
-       tclhandleFreeIndex(edgeTblPtr, AGID(e));
+       tclhandleFreeIndex(mycontext->edgeTblPtr, AGID(e));
        e1 = agnxtedge(g, e, n);
        agdelete(agroot(g), e);
        e = e1;
     }
 }
 
-static void deleteNodes(Tcl_Interp * interp, Agraph_t * g)
+static void deleteNodes(mycontext_t * mycontext, Agraph_t * g)
 {
     Agnode_t **np, *n, *n1;
     char buf[16];
 
     n = agfstnode(g);
     while (n) {
-       tclhandleString(nodeTblPtr, buf, AGID(n));
-       Tcl_DeleteCommand(interp, buf);
-       np = (Agnode_t **) tclhandleXlateIndex(nodeTblPtr, AGID(n));
+       tclhandleString(mycontext->nodeTblPtr, buf, AGID(n));
+       Tcl_DeleteCommand(mycontext->interp, buf);
+       np = (Agnode_t **) tclhandleXlateIndex(mycontext->nodeTblPtr, AGID(n));
        if (!np)
            fprintf(stderr, "Bad entry in nodeTbl\n");
-       tclhandleFreeIndex(nodeTblPtr, AGID(n));
-       deleteEdges(interp, agroot(g), n);
+       tclhandleFreeIndex(mycontext->nodeTblPtr, AGID(n));
+       deleteEdges(mycontext, agroot(g), n);
        n1 = agnxtnode(g, n);
        agdelete(agroot(g), n);
        n = n1;
@@ -182,22 +194,24 @@ static void deleteNodes(Tcl_Interp * interp, Agraph_t * g)
 }
 
 #ifdef WITH_CGRAPH
-static void deleteGraph(Tcl_Interp * interp, Agraph_t * g)
+static void deleteGraph(mycontext_t * mycontext, Agraph_t * g)
 {
+#ifndef WITH_CGRAPH
     Agraph_t **sgp;
+#endif
     Agraph_t *sg;
     char buf[16];
 
     for (sg = agfstsubg (g); sg; sg = agnxtsubg (sg)) {
-       deleteGraph(interp, sg);
+       deleteGraph(mycontext, sg);
     }
-    tclhandleString(graphTblPtr, buf, AGID(g));
-    Tcl_DeleteCommand(interp, buf);
+    tclhandleString(mycontext->graphTblPtr, buf, AGID(g));
+    Tcl_DeleteCommand(mycontext->interp, buf);
 #ifndef WITH_CGRAPH
-    sgp = (Agraph_t **) tclhandleXlateIndex(graphTblPtr, AGID(g));
+    sgp = (Agraph_t **) tclhandleXlateIndex(mycontext->graphTblPtr, AGID(g));
     if (!sgp)
        fprintf(stderr, "Bad entry in graphTbl\n");
-    tclhandleFreeIndex(graphTblPtr, AGID(g));
+    tclhandleFreeIndex(mycontext->graphTblPtr, AGID(g));
 #endif
     if (g == agroot(g)) {
        agclose(g);
@@ -206,7 +220,7 @@ static void deleteGraph(Tcl_Interp * interp, Agraph_t * g)
     }
 }
 #else
-static void deleteGraph(Tcl_Interp * interp, Agraph_t * g)
+static void deleteGraph(mycontext_t * mycontext, Agraph_t * g)
 {
     Agraph_t **sgp;
     Agedge_t *e;
@@ -215,14 +229,14 @@ static void deleteGraph(Tcl_Interp * interp, Agraph_t * g)
     if (g->meta_node) {
        for (e = agfstout(g->meta_node->graph, g->meta_node); e;
             e = agnxtout(g->meta_node->graph, e)) {
-           deleteGraph(interp, agusergraph(aghead(e)));
+           deleteGraph(mycontext, agusergraph(aghead(e)));
        }
-       tclhandleString(graphTblPtr, buf, AGID(g));
-       Tcl_DeleteCommand(interp, buf);
-       sgp = (Agraph_t **) tclhandleXlateIndex(graphTblPtr, AGID(g));
+       tclhandleString(mycontext->graphTblPtr, buf, AGID(g));
+       Tcl_DeleteCommand(mycontext->interp, buf);
+       sgp = (Agraph_t **) tclhandleXlateIndex(mycontext->graphTblPtr, AGID(g));
        if (!sgp)
            fprintf(stderr, "Bad entry in graphTbl\n");
-       tclhandleFreeIndex(graphTblPtr, AGID(g));
+       tclhandleFreeIndex(mycontext->graphTblPtr, AGID(g));
        if (g == agroot(g)) {
            agclose(g);
        } else {
@@ -360,7 +374,8 @@ static int edgecmd(ClientData clientData, Tcl_Interp * interp,
     Agraph_t *g;
     Agedge_t **ep, *e;
     Agsym_t *a;
-    GVC_t *gvc = (GVC_t *) clientData;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
+    GVC_t *gvc = mycontext->gvc;
 
     if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -368,7 +383,7 @@ static int edgecmd(ClientData clientData, Tcl_Interp * interp,
                         NULL);
        return TCL_ERROR;
     }
-    if (!(ep = (Agedge_t **) tclhandleXlate(edgeTblPtr, argv[0]))) {
+    if (!(ep = (Agedge_t **) tclhandleXlate(mycontext->edgeTblPtr, argv[0]))) {
        Tcl_AppendResult(interp, " \"", argv[0], "\"", NULL);
        return TCL_ERROR;
     }
@@ -379,7 +394,7 @@ static int edgecmd(ClientData clientData, Tcl_Interp * interp,
     length = strlen(argv[1]);
 
     if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
-       tclhandleFreeIndex(edgeTblPtr, AGID(e));
+       tclhandleFreeIndex(mycontext->edgeTblPtr, AGID(e));
        Tcl_DeleteCommand(interp, argv[0]);
        agdelete(g, e);
        reset_layout(gvc, g);
@@ -391,9 +406,9 @@ static int edgecmd(ClientData clientData, Tcl_Interp * interp,
        return TCL_OK;
 
     } else if ((c == 'l') && (strncmp(argv[1], "listnodes", length) == 0)) {
-       tclhandleString(nodeTblPtr, buf, AGID(agtail(e)));
+       tclhandleString(mycontext->nodeTblPtr, buf, AGID(agtail(e)));
        Tcl_AppendElement(interp, buf);
-       tclhandleString(nodeTblPtr, buf, AGID(aghead(e)));
+       tclhandleString(mycontext->nodeTblPtr, buf, AGID(aghead(e)));
        Tcl_AppendElement(interp, buf);
        return TCL_OK;
 
@@ -509,8 +524,8 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
     Agnode_t **np, *n, *head;
     Agedge_t **ep, *e;
     Agsym_t *a;
-
-    GVC_t *gvc = (GVC_t *) clientData;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
+    GVC_t *gvc = mycontext->gvc;
 
     if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -518,7 +533,7 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
                         NULL);
        return TCL_ERROR;
     }
-    if (!(np = (Agnode_t **) tclhandleXlate(nodeTblPtr, argv[0]))) {
+    if (!(np = (Agnode_t **) tclhandleXlate(mycontext->nodeTblPtr, argv[0]))) {
        Tcl_AppendResult(interp, " \"", argv[0], "\"", NULL);
        return TCL_ERROR;
     }
@@ -537,7 +552,7 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
                             NULL);
            return TCL_ERROR;
        }
-       if (!(np = (Agnode_t **) tclhandleXlate(nodeTblPtr, argv[2]))) {
+       if (!(np = (Agnode_t **) tclhandleXlate(mycontext->nodeTblPtr, argv[2]))) {
            if (!(head = agfindnode(g, argv[2]))) {
                Tcl_AppendResult(interp, "Head node \"", argv[2],
                                 "\" not found.", NULL);
@@ -558,31 +573,31 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
        e = agedge(g, n, head);
 #endif
        if (!
-           (ep = (Agedge_t **) tclhandleXlateIndex(edgeTblPtr, AGID(e)))
+           (ep = (Agedge_t **) tclhandleXlateIndex(mycontext->edgeTblPtr, AGID(e)))
            || *ep != e) {
-           ep = (Agedge_t **) tclhandleAlloc(edgeTblPtr, Tcl_GetStringResult(interp),
+           ep = (Agedge_t **) tclhandleAlloc(mycontext->edgeTblPtr, Tcl_GetStringResult(interp),
                                              &id);
            *ep = e;
            AGID(e) = id;
 #ifndef TCLOBJ
            Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), edgecmd,
-                             (ClientData) gvc,
+                             (ClientData) mycontext,
                              (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
            Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), edgecmd,
-                                (ClientData) gvc,
+                                (ClientData) mycontext,
                                 (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
        } else {
-           tclhandleString(edgeTblPtr, Tcl_GetStringResult(interp), AGID(e));
+           tclhandleString(mycontext->edgeTblPtr, Tcl_GetStringResult(interp), AGID(e));
        }
        setedgeattributes(agroot(g), e, &argv[3], argc - 3);
        reset_layout(gvc, g);
        return TCL_OK;
 
     } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
-       deleteEdges(interp, g, n);
-       tclhandleFreeIndex(nodeTblPtr, AGID(n));
+       deleteEdges(mycontext, g, n);
+       tclhandleFreeIndex(mycontext->nodeTblPtr, AGID(n));
        Tcl_DeleteCommand(interp, argv[0]);
        agdelete(g, n);
        reset_layout(gvc, g);
@@ -601,12 +616,12 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
            return TCL_ERROR;
        }
        if (!(e = agfindedge(g, n, head))) {
-           tclhandleString(nodeTblPtr, buf, AGID(head));
+           tclhandleString(mycontext->nodeTblPtr, buf, AGID(head));
            Tcl_AppendResult(interp, "Edge \"", argv[0],
                             " - ", buf, "\" not found.", NULL);
            return TCL_ERROR;
        }
-       tclhandleString(edgeTblPtr, buf, AGID(e));
+       tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
        Tcl_AppendElement(interp, buf);
        return TCL_OK;
 
@@ -617,7 +632,7 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
 
     } else if ((c == 'l') && (strncmp(argv[1], "listedges", length) == 0)) {
        for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
-           tclhandleString(edgeTblPtr, buf, AGID(e));
+           tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
            Tcl_AppendElement(interp, buf);
        }
        return TCL_OK;
@@ -625,7 +640,7 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
     } else if ((c == 'l')
               && (strncmp(argv[1], "listinedges", length) == 0)) {
        for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
-           tclhandleString(edgeTblPtr, buf, AGID(e));
+           tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
            Tcl_AppendElement(interp, buf);
        }
        return TCL_OK;
@@ -633,7 +648,7 @@ static int nodecmd(ClientData clientData, Tcl_Interp * interp,
     } else if ((c == 'l')
               && (strncmp(argv[1], "listoutedges", length) == 0)) {
        for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
-           tclhandleString(edgeTblPtr, buf, AGID(e));
+           tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
            Tcl_AppendElement(interp, buf);
        }
        return TCL_OK;
@@ -805,7 +820,8 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
     char c, buf[256], **argv2;
     int i, j, length, argc2, rc;
     unsigned long id;
-    GVC_t *gvc = (GVC_t *) clientData;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
+    GVC_t *gvc = mycontext->gvc;
     GVJ_t *job = gvc->job;
 
     if (argc < 2) {
@@ -814,7 +830,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                         NULL);
        return TCL_ERROR;
     }
-    if (!(gp = (Agraph_t **) tclhandleXlate(graphTblPtr, argv[0]))) {
+    if (!(gp = (Agraph_t **) tclhandleXlate(mycontext->graphTblPtr, argv[0]))) {
        Tcl_AppendResult(interp, " \"", argv[0], "\"", NULL);
        return TCL_ERROR;
     }
@@ -831,7 +847,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                             NULL);
            return TCL_ERROR;
        }
-       if (!(np = (Agnode_t **) tclhandleXlate(nodeTblPtr, argv[2]))) {
+       if (!(np = (Agnode_t **) tclhandleXlate(mycontext->nodeTblPtr, argv[2]))) {
            if (!(tail = agfindnode(g, argv[2]))) {
                Tcl_AppendResult(interp, "Tail node \"", argv[2],
                                 "\" not found.", NULL);
@@ -845,7 +861,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                return TCL_ERROR;
            }
        }
-       if (!(np = (Agnode_t **) tclhandleXlate(nodeTblPtr, argv[3]))) {
+       if (!(np = (Agnode_t **) tclhandleXlate(mycontext->nodeTblPtr, argv[3]))) {
            if (!(head = agfindnode(g, argv[3]))) {
                Tcl_AppendResult(interp, "Head node \"", argv[3],
                                 "\" not found.", NULL);
@@ -864,19 +880,19 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
 #else
        e = agedge(g, tail, head);
 #endif
-       if (!(ep = (Agedge_t **) tclhandleXlateIndex(edgeTblPtr, AGID(e))) || *ep != e) {
-           ep = (Agedge_t **) tclhandleAlloc(edgeTblPtr, Tcl_GetStringResult(interp), &id);
+       if (!(ep = (Agedge_t **) tclhandleXlateIndex(mycontext->edgeTblPtr, AGID(e))) || *ep != e) {
+           ep = (Agedge_t **) tclhandleAlloc(mycontext->edgeTblPtr, Tcl_GetStringResult(interp), &id);
            *ep = e;
            AGID(e) = id;
 #ifndef TCLOBJ
            Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), edgecmd,
-                             (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                             (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
            Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), edgecmd,
-                                (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
        } else {
-           tclhandleString(edgeTblPtr, Tcl_GetStringResult(interp), AGID(e));
+           tclhandleString(mycontext->edgeTblPtr, Tcl_GetStringResult(interp), AGID(e));
        }
        setedgeattributes(agroot(g), e, &argv[4], argc - 4);
        reset_layout(gvc, g);
@@ -891,23 +907,23 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            n = agnode(g, argv[2]);
 #endif
            i = 3;
-           if (!(np = (Agnode_t **) tclhandleXlateIndex(nodeTblPtr, AGID(n))) || *np != n) {
-               np = (Agnode_t **) tclhandleAlloc(nodeTblPtr, Tcl_GetStringResult(interp), &id);
+           if (!(np = (Agnode_t **) tclhandleXlateIndex(mycontext->nodeTblPtr, AGID(n))) || *np != n) {
+               np = (Agnode_t **) tclhandleAlloc(mycontext->nodeTblPtr, Tcl_GetStringResult(interp), &id);
                *np = n;
                AGID(n) = id;
 #ifndef TCLOBJ
                Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), nodecmd,
-                                 (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                 (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else /* TCLOBJ */
                Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), nodecmd,
-                                    (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                    (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif /* TCLOBJ */
            } else {
-               tclhandleString(nodeTblPtr, Tcl_GetStringResult(interp), AGID(n));
+               tclhandleString(mycontext->nodeTblPtr, Tcl_GetStringResult(interp), AGID(n));
            }
        } else {
            /* else use handle as name */
-           np = (Agnode_t **) tclhandleAlloc(nodeTblPtr, Tcl_GetStringResult(interp), &id);
+           np = (Agnode_t **) tclhandleAlloc(mycontext->nodeTblPtr, Tcl_GetStringResult(interp), &id);
 #ifdef WITH_CGRAPH
            n = agnode(g, Tcl_GetStringResult(interp), 1);
 #else
@@ -918,10 +934,10 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            AGID(n) = id;
 #ifndef TCLOBJ
            Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), nodecmd,
-                             (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                             (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
            Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), nodecmd,
-                                (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
        }
        setnodeattributes(agroot(g), n, &argv[i], argc - i);
@@ -943,23 +959,23 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            sg = agsubg(g, argv[2]);
 #endif
            i = 3;
-           if (!  (sgp = (Agraph_t **) tclhandleXlateIndex(graphTblPtr, AGID(sg))) || *sgp != sg) {
-               sgp = (Agraph_t **) tclhandleAlloc(graphTblPtr, Tcl_GetStringResult(interp), &id);
+           if (!  (sgp = (Agraph_t **) tclhandleXlateIndex(mycontext->graphTblPtr, AGID(sg))) || *sgp != sg) {
+               sgp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, Tcl_GetStringResult(interp), &id);
                *sgp = sg;
                AGID(sg) = id;
 #ifndef TCLOBJ
                Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                                 (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                 (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
                Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                                    (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                    (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
            } else {
-               tclhandleString(graphTblPtr, Tcl_GetStringResult(interp), AGID(sg));
+               tclhandleString(mycontext->graphTblPtr, Tcl_GetStringResult(interp), AGID(sg));
            }
        } else {
            /* else use handle as name */
-           sgp = (Agraph_t **) tclhandleAlloc(graphTblPtr, Tcl_GetStringResult(interp), &id);
+           sgp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, Tcl_GetStringResult(interp), &id);
 #ifdef WITH_CGRAPH
            sg = agsubg(g, Tcl_GetStringResult(interp), 1);
 #else
@@ -970,10 +986,10 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            AGID(sg) = id;
 #ifndef TCLOBJ
            Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                             (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                             (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
            Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                                (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                                (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
        }
        setgraphattributes(sg, &argv[i], argc - i);
@@ -992,8 +1008,8 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
 
     } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) {
        reset_layout(gvc, g);
-       deleteNodes(interp, g);
-       deleteGraph(interp, g);
+       deleteNodes(mycontext, g);
+       deleteGraph(mycontext, g);
        return TCL_OK;
 
     } else if ((c == 'f') && (strncmp(argv[1], "findedge", length) == 0)) {
@@ -1014,7 +1030,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            Tcl_AppendResult(interp, "Edge \"", argv[2], " - ", argv[3], "\" not found.", NULL);
            return TCL_ERROR;
        }
-       tclhandleString(edgeTblPtr, buf, AGID(e));
+       tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
        Tcl_AppendElement(interp, buf);
        return TCL_OK;
 
@@ -1027,7 +1043,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            Tcl_AppendResult(interp, "Node not found.", NULL);
            return TCL_ERROR;
        }
-       tclhandleString(nodeTblPtr, buf, AGID(n));
+       tclhandleString(mycontext->nodeTblPtr, buf, AGID(n));
        Tcl_AppendResult(interp, buf, NULL);
        return TCL_OK;
 
@@ -1063,7 +1079,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
     } else if ((c == 'l') && (strncmp(argv[1], "listedges", length) == 0)) {
        for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
            for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
-               tclhandleString(edgeTblPtr, buf, AGID(e));
+               tclhandleString(mycontext->edgeTblPtr, buf, AGID(e));
                Tcl_AppendElement(interp, buf);
            }
        }
@@ -1071,7 +1087,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
 
     } else if ((c == 'l') && (strncmp(argv[1], "listnodes", length) == 0)) {
        for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
-           tclhandleString(nodeTblPtr, buf, AGID(n));
+           tclhandleString(mycontext->nodeTblPtr, buf, AGID(n));
            Tcl_AppendElement(interp, buf);
        }
        return TCL_OK;
@@ -1079,7 +1095,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
     } else if ((c == 'l')
               && (strncmp(argv[1], "listnodesrev", length) == 0)) {
        for (n = aglstnode(g); n; n = agprvnode(g, n)) {
-           tclhandleString(nodeTblPtr, buf, AGID(n));
+           tclhandleString(mycontext->nodeTblPtr, buf, AGID(n));
            Tcl_AppendElement(interp, buf);
        }
        return TCL_OK;
@@ -1088,7 +1104,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
               && (strncmp(argv[1], "listsubgraphs", length) == 0)) {
 #ifdef WITH_CGRAPH
        for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) {
-           tclhandleString(graphTblPtr, buf, AGID(sg));
+           tclhandleString(mycontext->graphTblPtr, buf, AGID(sg));
            Tcl_AppendElement(interp, buf);
        }
 #else
@@ -1096,7 +1112,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
            for (e = agfstout(g->meta_node->graph, g->meta_node); e;
                 e = agnxtout(g->meta_node->graph, e)) {
                sg = agusergraph(aghead(e));
-               tclhandleString(graphTblPtr, buf, AGID(sg));
+               tclhandleString(mycontext->graphTblPtr, buf, AGID(sg));
                Tcl_AppendElement(interp, buf);
            }
        }
@@ -1523,7 +1539,7 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
 #endif                         /* TCLOBJ */
     )
 {
-    GVC_t *gvc;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
     Agraph_t *g, **gp;
     char c;
     int i, length;
@@ -1540,7 +1556,6 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
                         NULL);
        return TCL_ERROR;
     }
-    gvc = (GVC_t *) clientData;
     c = argv[1][0];
     length = strlen(argv[1]);
     if ((c == 'd') && (strncmp(argv[1], "digraph", length) == 0)) {
@@ -1575,14 +1590,14 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
        return TCL_ERROR;
     }
 #ifndef WITH_CGRAPH
-    gp = (Agraph_t **) tclhandleAlloc(graphTblPtr, Tcl_GetStringResult(interp), &id);
+    gp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, Tcl_GetStringResult(interp), &id);
 #endif
     if (argc % 2) {
        /* if odd number of args then argv[2] is name */
 #ifndef WITH_CGRAPH
        g = agopen(argv[2], kind);
 #else
-       g = agopen(argv[2], kind, &mydisc);
+       g = agopen(argv[2], kind, (Agdisc_t*)mycontext);
 #endif
        i = 3;
     } else {
@@ -1590,7 +1605,7 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
 #ifndef WITH_CGRAPH
        g = agopen(Tcl_GetStringResult(interp), kind);
 #else
-       g = agopen(Tcl_GetStringResult(interp), kind, &mydisc);
+       g = agopen(Tcl_GetStringResult(interp), kind, (Agdisc_t*)mycontext);
 #endif
        i = 2;
     }
@@ -1605,16 +1620,16 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
     *gp = g;
     AGID(g) = id;
 #else
-    gp = (Agraph_t **)tclhandleXlateIndex(graphTblPtr, AGID(g));
+    gp = (Agraph_t **)tclhandleXlateIndex(mycontext->graphTblPtr, AGID(g));
     *gp = g;
 #endif
 
 #ifndef TCLOBJ
     Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                     (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                     (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
     Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                        (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                        (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
     setgraphattributes(g, &argv[i], argc - i);
     /* we use GD_drawing(g) as a flag that layout has been done.
@@ -1626,22 +1641,23 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
 
 #ifdef WITH_CGRAPH
 static void
-init_graphs (Tcl_Interp * interp, GVC_t * gvc, graph_t* g)
+init_graphs (mycontext_t *mycontext, graph_t* g)
 {
     Agraph_t *sg, **sgp;
     unsigned long id;
     char buf[16];
+    Tcl_Interp *interp = mycontext->interp;
 
     for (sg = agfstsubg (g); sg; sg = agnxtsubg (sg))
-       init_graphs (interp, gvc, sg);
+       init_graphs (mycontext, sg);
 
-    sgp = (Agraph_t **) tclhandleAlloc(graphTblPtr, buf, &id);
+    sgp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, buf, &id);
     *sgp = g;
     AGID(g) = id;
 #ifndef TCLOBJ
-    Tcl_CreateCommand(interp, buf, graphcmd, (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+    Tcl_CreateCommand(interp, buf, graphcmd, (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
-    Tcl_CreateObjCommand(interp, buf, graphcmd, (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+    Tcl_CreateObjCommand(interp, buf, graphcmd, (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
     if (agroot(g) == g)
        Tcl_SetResult(interp, buf, TCL_VOLATILE);
@@ -1653,7 +1669,7 @@ init_graphs (Tcl_Interp * interp, GVC_t * gvc, graph_t* g)
  * it to create the handles and tcl commands for each 
  * graph, subgraph, node, and edge.
  */
-static int tcldot_fixup(Tcl_Interp * interp, GVC_t * gvc, graph_t * g)
+static int tcldot_fixup(mycontext_t *mycontext, graph_t * g)
 {
 #ifndef WITH_CGRAPH
     Agraph_t **gp, *sg, **sgp;
@@ -1662,57 +1678,58 @@ static int tcldot_fixup(Tcl_Interp * interp, GVC_t * gvc, graph_t * g)
     Agedge_t *e, **ep;
     char buf[16];
     unsigned long id;
+    Tcl_Interp *interp = mycontext->interp;
 
 #ifdef WITH_CGRAPH
-    init_graphs (interp, gvc, g);
+    init_graphs (mycontext, g);
 #else
     if (g->meta_node) {
        for (n = agfstnode(g->meta_node->graph); n;
             n = agnxtnode(g->meta_node->graph, n)) {
            sg = agusergraph(n);
-           sgp = (Agraph_t **) tclhandleAlloc(graphTblPtr, buf, &id);
+           sgp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, buf, &id);
            *sgp = sg;
            AGID(sg) = id;
 #ifndef TCLOBJ
-           Tcl_CreateCommand(interp, buf, graphcmd, (ClientData) gvc,
+           Tcl_CreateCommand(interp, buf, graphcmd, (ClientData) mycontext,
                              (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
-           Tcl_CreateObjCommand(interp, buf, graphcmd, (ClientData) gvc,
+           Tcl_CreateObjCommand(interp, buf, graphcmd, (ClientData) mycontext,
                                 (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
            if (sg == g)
                Tcl_SetResult(interp, buf, TCL_VOLATILE);
        }
     } else {
-       gp = (Agraph_t **) tclhandleAlloc(graphTblPtr, Tcl_GetStringResult(interp), &id);
+       gp = (Agraph_t **) tclhandleAlloc(mycontext->graphTblPtr, Tcl_GetStringResult(interp), &id);
        *gp = g;
        AGID(g) = id;
 #ifndef TCLOBJ
        Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                         (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                         (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
        Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), graphcmd,
-                            (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                            (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
     }
 #endif /* WITH_CGRAPH */
     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
-       np = (Agnode_t **) tclhandleAlloc(nodeTblPtr, buf, &id);
+       np = (Agnode_t **) tclhandleAlloc(mycontext->nodeTblPtr, buf, &id);
        *np = n;
        AGID(n) = id;
 #ifndef TCLOBJ
        Tcl_CreateCommand(interp, buf, nodecmd,
-                         (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                         (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
        Tcl_CreateObjCommand(interp, buf, nodecmd,
                             (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
        for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
-           ep = (Agedge_t **) tclhandleAlloc(edgeTblPtr, buf, &id);
+           ep = (Agedge_t **) tclhandleAlloc(mycontext->edgeTblPtr, buf, &id);
            *ep = e;
            AGID(e) = id;
 #ifndef TCLOBJ
-           Tcl_CreateCommand(interp, buf, edgecmd, (ClientData) gvc,
+           Tcl_CreateCommand(interp, buf, edgecmd, (ClientData) mycontext,
                              (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
            Tcl_CreateObjCommand(interp, buf, edgecmd, (ClientData) gvc,
@@ -1795,7 +1812,6 @@ static char *mygets(char *ubuf, int n, FILE * channel)
 {
     static Tcl_DString dstr;
     static int strpos;
-    int nput;
 
     if (!n) {                  /* a call with n==0 (from aglexinit) resets */
        *ubuf = '\0';
@@ -1896,10 +1912,10 @@ static int dotread(ClientData clientData, Tcl_Interp * interp,
 #endif                         /* TCLOBJ */
     )
 {
-    GVC_t *gvc;
     Agraph_t *g;
     Tcl_Channel channel;
     int mode;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
 
     if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -1911,7 +1927,6 @@ static int dotread(ClientData clientData, Tcl_Interp * interp,
        Tcl_AppendResult(interp, "\nChannel \"", argv[1], "\"", "is unreadable.", NULL);
        return TCL_ERROR;
     }
-    gvc = (GVC_t *) clientData;
     /*
      * read a graph from the channel, the channel is left open
      *   ready to read the first line after the last line of
@@ -1934,7 +1949,7 @@ static int dotread(ClientData clientData, Tcl_Interp * interp,
      * so we make sure that it is initialized to "not done" */
     GD_drawing(g) = NULL;
 
-    return (tcldot_fixup(interp, gvc, g));
+    return (tcldot_fixup(mycontext, g));
 }
 
 static int dotstring(ClientData clientData, Tcl_Interp * interp,
@@ -1945,8 +1960,8 @@ static int dotstring(ClientData clientData, Tcl_Interp * interp,
 #endif                         /* TCLOBJ */
     )
 {
-    GVC_t *gvc;
     Agraph_t *g;
+    mycontext_t *mycontext = (mycontext_t *)clientData;
 
     if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " string\"", NULL);
@@ -1967,10 +1982,7 @@ static int dotstring(ClientData clientData, Tcl_Interp * interp,
      * so we make sure that it is initialized to "not done" */
     GD_drawing(g) = NULL;
 
-    /* link graph to context */
-    gvc = (GVC_t *) clientData;
-
-    return (tcldot_fixup(interp, gvc, g));
+    return (tcldot_fixup(mycontext, g));
 }
 
 #if defined(_BLD_tcldot) && defined(_DLL)
@@ -1978,10 +1990,16 @@ __EXPORT__
 #endif
 int Tcldot_Init(Tcl_Interp * interp)
 {
-GVC_t *gvc;
+    mycontext_t *mycontext;
+    GVC_t *gvc;
 
+    mycontext = calloc(1, sizeof(mycontext_t));
+    if (!mycontext)
+       return TCL_ERROR;
+
+    mycontext->interp = interp;
 #ifdef WITH_CGRAPH    
-    myiddisc_usercontext = interp;
+    mycontext->mydisc.id = &myiddisc;
 #endif
 
 #ifdef USE_TCL_STUBS
@@ -2013,29 +2031,31 @@ GVC_t *gvc;
 
     /* create a GraphViz Context and pass a pointer to it in clientdata */
     gvc = gvNEWcontext(lt_preloaded_symbols, DEMAND_LOADING);
+    mycontext->gvc = gvc;
 
     /* configure for available plugins */
     gvconfig(gvc, FALSE);
 
 #ifndef TCLOBJ
     Tcl_CreateCommand(interp, "dotnew", dotnew,
-                     (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                     (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
     Tcl_CreateCommand(interp, "dotread", dotread,
-                     (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                     (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
     Tcl_CreateCommand(interp, "dotstring", dotstring,
-                     (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                     (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #else                          /* TCLOBJ */
     Tcl_CreateObjCommand(interp, "dotnew", dotnew,
-                        (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                        (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
     Tcl_CreateObjCommand(interp, "dotread", dotread,
-                        (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                        (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
     Tcl_CreateObjCommand(interp, "dotstring", dotstring,
-                        (ClientData) gvc, (Tcl_CmdDeleteProc *) NULL);
+                        (ClientData) mycontext, (Tcl_CmdDeleteProc *) NULL);
 #endif                         /* TCLOBJ */
 
-    graphTblPtr = (void *) tclhandleInit("graph", sizeof(Agraph_t *), 10);
-    nodeTblPtr = (void *) tclhandleInit("node", sizeof(Agnode_t *), 100);
-    edgeTblPtr = (void *) tclhandleInit("edge", sizeof(Agedge_t *), 100);
+    mycontext->graphTblPtr = (void *) tclhandleInit("graph", sizeof(Agraph_t *), 10);
+    mycontext->nodeTblPtr = (void *) tclhandleInit("node", sizeof(Agnode_t *), 100);
+    mycontext->edgeTblPtr = (void *) tclhandleInit("edge", sizeof(Agedge_t *), 100);
+
 
     return TCL_OK;
 }