home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / routines.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-07  |  15.7 KB  |  852 lines

  1. /**
  2.    GRAB Graph Layout and Browser System
  3.  
  4.    Copyright (c) 1986, 1988 Regents of the University of California
  5.    Copyright (c) 1989, Tera Computer Company
  6.  **/
  7.  
  8.   /* routines.c -- routines for menu items.  */
  9.  
  10. #include "malloc.h"
  11. #include <stdio.h>
  12. #include <pwd.h>
  13. #include <strings.h>
  14.  
  15. #include "attribute.h"
  16. #include "digraph.h"
  17. #include "screen.h"
  18. #include "globals.h"
  19. #include "scrdep.h"
  20. #include "interf.h"
  21. #include "tedge.h"
  22. #include "cursor.h"
  23.  
  24. void DoGraph();
  25. OUTEDGE* get_edge();
  26. BOOL ReadIn();
  27.  
  28.   /* lots of "turn on/off an option" routines */
  29. void DoShowBC()
  30. {
  31.     if (showbc) 
  32.     {
  33.         showbc = FALSE;
  34.     IChangeStatusLine("Show BC OFF", FALSE);
  35.     IChangeBC();
  36.     } 
  37.     else 
  38.     {
  39.         showbc = TRUE;
  40.     IChangeStatusLine("Show BC ON", FALSE);
  41.     IChangeBC();
  42.     }
  43.  
  44.     AsteriskOnToggles();
  45. }
  46.  
  47. void DoStraighten()
  48. {
  49.     if (straightenEdges) 
  50.     {
  51.     IChangeStatusLine("Straighten Edges OFF", FALSE);
  52.     }
  53.     else 
  54.     {
  55.     IChangeStatusLine("Straighten Edges ON", FALSE);
  56.     }
  57.  
  58.     straightenEdges = !straightenEdges;
  59.     AsteriskOnToggles();
  60. }
  61.  
  62. void DoDebugMode()
  63. {
  64.     if (debug) 
  65.     {
  66.     IChangeStatusLine("Debug Mode OFF", FALSE);
  67.     }
  68.     else 
  69.     {
  70.     IChangeStatusLine("Debug Mode ON", FALSE);
  71.     }
  72.  
  73.     debug = !debug;
  74.     AsteriskOnToggles();
  75. }
  76.  
  77. void DoPrintLabel()
  78. {
  79.     if (!printNodeLabel) 
  80.     {
  81.     printNodeLabel = TRUE;
  82.     IForceNL();
  83.     IChangeStatusLine("Print Node Label Mode is ON", FALSE);
  84.     }
  85.     else 
  86.     {
  87.     printNodeLabel = FALSE;
  88.     INoForceNL();
  89.     IChangeStatusLine("Print Node Label Mode is OFF", FALSE);
  90.     }
  91.  
  92.     IChangeForceNL();
  93.     AsteriskOnToggles();
  94. }
  95.  
  96. void DoChangeOutEdges()
  97. {
  98.     if (!changeOutEdges) 
  99.     {
  100.     changeOutEdges = TRUE;
  101.     IChangeStatusLine("Change Out Edges ON", FALSE);
  102.     }
  103.     else 
  104.     {
  105.     changeOutEdges = FALSE;
  106.     IChangeStatusLine("Change Out Edges OFF", FALSE);
  107.     }
  108.  
  109.     AsteriskOnToggles();
  110. }
  111.  
  112. void DoChangeInEdges()
  113. {
  114.     if (!changeInEdges) 
  115.     {
  116.     changeInEdges = TRUE;
  117.     IChangeStatusLine("Change In Edges ON", FALSE);
  118.     }
  119.     else 
  120.     {
  121.     changeInEdges = FALSE;
  122.     IChangeStatusLine("Change In Edges OFF", FALSE);
  123.     }
  124.  
  125.     AsteriskOnToggles();
  126. }
  127.  
  128. void DoMarkDummyNodes()
  129. {
  130.     if (markDummyNodes) 
  131.     {
  132.     markDummyNodes = FALSE;
  133.     IChangeStatusLine("Mark Dummy Nodes OFF", FALSE);
  134.     } 
  135.     else 
  136.     {
  137.     markDummyNodes = TRUE;
  138.     IChangeStatusLine("Mark Dummy Nodes ON", FALSE);
  139.     }
  140.  
  141.     IChangeMarkDummy();
  142.     AsteriskOnToggles();
  143. }
  144.  
  145. void DoDrawArrow()
  146. {
  147.     if (printArrow) 
  148.     {
  149.     printArrow = FALSE;
  150.     IChangeStatusLine("Draw Arrows OFF", FALSE);
  151.     } 
  152.     else 
  153.     {
  154.     printArrow = TRUE;
  155.     IChangeStatusLine("Draw Arrow ON", FALSE);
  156.     }
  157.  
  158.     IChangePA();
  159.     AsteriskOnToggles();
  160. }
  161.  
  162. void DoRotatePSFile()
  163. {
  164.     if (landscapePSFile) 
  165.     {
  166.     landscapePSFile = FALSE;
  167.     IChangeStatusLine("Rotate PostScript File OFF", FALSE);
  168.     } 
  169.     else 
  170.     {
  171.     landscapePSFile = TRUE;
  172.     IChangeStatusLine("Rotate PostScript File ON", FALSE);
  173.     }
  174.  
  175.     AsteriskOnToggles();
  176. }
  177.  
  178. void DoPrintEdgeLabel()
  179. {
  180.     if (printEdgeLabel) 
  181.     {
  182.     printEdgeLabel = FALSE;
  183.     INoForceEL();
  184.     IChangeStatusLine("Print Edge Label OFF", FALSE);
  185.     } 
  186.     else 
  187.     {
  188.     printEdgeLabel = TRUE;
  189.     IForceEL();
  190.     IChangeStatusLine("Print Edge Label ON", FALSE);
  191.     }
  192.  
  193.     IChangeForceEL();
  194.     AsteriskOnToggles();
  195. }
  196.  
  197. void DoIgnoreHidden()
  198. {
  199.     if (ignoreHidden) 
  200.     {
  201.     ignoreHidden = FALSE;
  202.     IChangeStatusLine("Ignore Hidden OFF", FALSE);
  203.     } 
  204.     else 
  205.     {
  206.     ignoreHidden = TRUE;
  207.     IChangeStatusLine("Ignore Hidden ON", FALSE);
  208.     }
  209.  
  210.     AsteriskOnToggles();
  211. }
  212.  
  213. AsteriskOnToggles()
  214.   /** 
  215.      Mark toggles of options menu with asterisk if toggle is on.
  216.      For some reason, passing boolean arrays doesn't work, so we
  217.      use character arrays
  218.    **/
  219. {
  220.     char optarr[NUMOPTS];
  221.  
  222.     optarr[0] = (char) printNodeLabel;
  223.     optarr[1] = (char) markDummyNodes;
  224.     optarr[2] = (char) printArrow;
  225.     optarr[3] = (char) printEdgeLabel;
  226.     optarr[4] = (char) changeInEdges;
  227.     optarr[5] = (char) changeOutEdges;
  228.     optarr[6] = (char) landscapePSFile;
  229.     optarr[7] = (char) showbc;
  230.     optarr[8] = (char) debug;
  231.     optarr[9] = (char) straightenEdges;
  232.     optarr[10] = (char) ignoreHidden;
  233.     IChangeToggles(optarr);
  234. }
  235.  
  236.   /**
  237.      routines the C++ routines can call to get the state of the world
  238.    **/
  239.  
  240. BOOL GetOutEFlag()
  241. {
  242.     return (changeOutEdges);
  243. }
  244.  
  245. BOOL GetInEFlag()
  246. {
  247.     return (changeInEdges);
  248. }
  249.  
  250. BOOL GetBModeFlag()
  251. {
  252.     return (currMode == IN_BROWSE_MODE);
  253. }
  254.  
  255. BOOL GetEModeFlag()
  256. {
  257.     return (currMode == IN_EDIT_MODE);
  258. }
  259.  
  260. BOOL GetCModeFlag()
  261. {
  262.     return (currMode == IN_CHANGE_MODE);
  263. }
  264.  
  265. BOOL GetMarkDummyFlag()
  266. {
  267.     return markDummyNodes;
  268. }
  269.  
  270. void DoBrowseMode()
  271. {
  272.     currMode = IN_BROWSE_MODE;
  273. }
  274.  
  275. void DoChangeMode()
  276. {
  277.     currMode = IN_CHANGE_MODE;
  278. }
  279.  
  280. void DoEditMode()
  281. {
  282.     currMode = IN_EDIT_MODE;
  283. }
  284.  
  285. BOOL GetPAFlag()
  286. {
  287.     return printArrow;
  288. }
  289.  
  290. BOOL GetBCFlag()
  291. {
  292.     return showbc;
  293. }
  294.  
  295.   /**
  296.      Other routines
  297.    **/
  298.  
  299. void DoRedisplay()
  300. {
  301.     IRedrawWorld();
  302. }
  303.  
  304. void DoLayoutGraph()
  305. {
  306.     if (digraph == NULL) 
  307.     {
  308.     IChangeStatusLine("no graph to lay out", FALSE);
  309.     return;
  310.     }
  311.  
  312.     IChangeStatusLine("Laying out graph", TRUE);
  313.     ISetCursor(waitC);
  314.     relay_digraph(digraph);
  315.     StartDisp();
  316.     IUnsetCursor();
  317.     IChangeStatusLine("Graph layout done", FALSE);
  318. }
  319.  
  320. static char newName[MAXSTR];        /* new file name */
  321. int EndDoChangeFileName();    
  322.  
  323. void DoChangeFileName()
  324. {
  325.     IChangeStatusLine("Type new file name", FALSE);
  326.     
  327.     TakeTextInput(EndDoChangeFileName);
  328. }
  329.  
  330. #define BAD     0
  331. #define OK     1
  332.  
  333. EndDoChangeFileName()
  334. {
  335.     int status    = OK;
  336.     char *buf;
  337.  
  338.     OutofText(newName);
  339.  
  340.     if (newName[0] != '\0')         /* if user entered a name */
  341.     {        
  342.     if (newName[0] == '~') 
  343.     {
  344.         status = expand_tilde(newName, name);
  345.     } 
  346.  
  347.     if (status == BAD || newName[0] != '~') 
  348.     {
  349.         strcpy(name, newName);    /* copy name of file to global var */
  350.     }
  351.     }
  352.  
  353.     buf = (char *) malloc(sizeof(char) * MAXSTR);
  354.  
  355.     if (newName[0] == '\0') 
  356.     {
  357.     sprintf(buf, "old file name retained");
  358.     }
  359.     else if (status == OK) 
  360.     {
  361.     sprintf(buf, "new file name is %s", name);
  362.     }
  363.     else 
  364.     {
  365.     sprintf(buf, "bad file name: \"%s\"", name);
  366.     }
  367.  
  368.     IChangeStatusLine(buf, FALSE);
  369.     IChangeFileName(name);
  370.     dispose(buf);
  371. }
  372.  
  373. expand_tilde(s, name)
  374.     char *s, *name;
  375. {
  376.     register int i;
  377.     struct passwd *pw;
  378.     char userName[MAXSTR];
  379.  
  380.     s++;            /* skip the ~ */
  381.  
  382.     if (*s ==  '/')         /* file name of form ~/foo */
  383.     {        
  384.     pw = getpwuid(getuid());
  385.     }
  386.     else             /* file name of form ~user/foo */
  387.     {            
  388.     i = 0;
  389.  
  390.     while (*s != '/' && *s && i < MAXSTR) 
  391.     {
  392.         userName[i++] = *s++;
  393.     }
  394.  
  395.     userName[i] = '\0';
  396.  
  397.     if ((pw = getpwnam(userName)) == 0) 
  398.     {
  399.         return BAD;
  400.     }
  401.     }
  402.  
  403.     strcpy(name, pw->pw_dir);
  404.     strncat(name, s, MAXSTR-strlen(name));
  405.     return OK;
  406. }
  407.  
  408. void DoReadFile()
  409. {
  410.       /* free old data structure, get rid of old graph */
  411.     dispose_digraph(digraph);
  412.  
  413.       /* read in the file, layout the graph, and draw it on the screen */
  414.     (void) ReadIn();
  415.     DisplayReadGraph();
  416. }
  417.  
  418. void DoWriteFile()
  419. {
  420.     char* s[MAXSTR];
  421.     FILE *graph_file;
  422.  
  423.     if ((graph_file = fopen(name, "r")) != NULL) 
  424.     {
  425.     fclose(graph_file);
  426.     sprintf(s, "File %s exists.  Overwrite?", name);
  427.  
  428.         if (IConfirm(s) == 'y') 
  429.         {
  430.             write_out();
  431.     }
  432.     }
  433.     else
  434.     {
  435.         write_out();
  436.     }
  437. }
  438.  
  439. void DoCreatePSFile()
  440. {
  441.     ISetCursor(waitC);
  442.     IChangeStatusLine("Creating postscript file of graph", TRUE);
  443.     DrawGraphPS(digraph, showbc);
  444.     IUnsetCursor();
  445. }
  446.  
  447. void DoPSScreen()
  448. {
  449.     ISetCursor(waitC);
  450.     IChangeStatusLine("Creating postscript file of screen", TRUE);
  451.     DrawScreenPS(digraph, showbc);
  452.     IUnsetCursor();
  453. }
  454.  
  455. int EndSetZoomGrad(), EndSetPanGrad();
  456. char gradString[MAXSTR];
  457.  
  458. void DoSetZoomGrad()
  459. {
  460.     char *buf;
  461.  
  462.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  463.     sprintf(buf, "Type in new zoom gradient (current zoom gradient = %1.2f)", 
  464.         zoomGradient);
  465.     IChangeStatusLine(buf, FALSE);
  466.  
  467.     TakeTextInput(EndSetZoomGrad);
  468.     dispose(buf);
  469. }
  470.  
  471. EndSetZoomGrad()
  472. {
  473.     char *buf;
  474.  
  475.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  476.     OutofText(gradString);
  477.     sscanf(gradString, "%f", &zoomGradient);
  478.     sprintf(buf, "new zoom gradient is %1.2f", zoomGradient);
  479.     IChangeStatusLine(buf, FALSE);
  480.     IChangeZGrad(zoomGradient);
  481.     dispose(buf);
  482. }
  483.     
  484. void DoSetPanGrad()
  485. {
  486.     char *buf;
  487.  
  488.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  489.     sprintf(buf, "Type in new pan gradient (current pan gradient = %1.2f)",
  490.         panGradient);
  491.     IChangeStatusLine(buf, FALSE);
  492.  
  493.     TakeTextInput(EndSetPanGrad);
  494.     dispose(buf);
  495. }
  496.  
  497. EndSetPanGrad()
  498. {
  499.     char *buf;
  500.     int a, b, c, d, e, f, width, height;
  501.  
  502.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  503.     OutofText(gradString);
  504.     sscanf(gradString, "%f", &panGradient);
  505.     sprintf(buf, "new pan gradient is %1.2f", panGradient);
  506.     IChangeStatusLine(buf, FALSE);
  507.     IGetBounds(&a, &b, &c, &d, &e, &f, &width, &height);
  508.     IChangePGrad((int) (panGradient * width), (int) (panGradient * height));
  509.     dispose(buf);
  510. }
  511.  
  512.  
  513. void DoSizeToFit()
  514. {
  515.     IChangeStatusLine("Sizing to Fit", TRUE);
  516.     ICenterGraph();
  517.     DoGraph();
  518. }
  519.  
  520. void DoShowSize()
  521. {
  522.     int x0, y0, width, height, curx, cury, curwidth, curheight;
  523.  
  524.     IGetBounds(&x0, &y0, &width, &height, &curx, &cury, &curwidth, &curheight);
  525.     printf("\nXgrab\n");
  526.     printf("Display x0: %d, y0: %d, width: %d, height: %d\n",
  527.         x0, y0, width, height);
  528.  
  529.     printf("Canvas x0: %d, y0: %d, width: %d, height: %d\n",
  530.         curx, cury, curwidth, curheight);
  531.  
  532.     printf("screen minx: %d, miny: %d, maxx: %d, maxy:%d\n",
  533.         screen.canvas.min_x, screen.canvas.min_y,
  534.         screen.canvas.max_x, screen.canvas.max_y);
  535.  
  536. /*
  537.     printf("bounding box minx: %d, miny: %d, maxx: %d, maxy:%d\n",
  538.         screen.bound.min_x, screen.bound.min_y,
  539.         screen.bound.max_x, screen.bound.max_y);
  540. */
  541.  
  542.     printf("Absolute minx: %d, miny: %d, maxx: %d, maxy:%d\n",
  543.         screen.absview.min_x, screen.absview.min_y,
  544.         screen.absview.max_x, screen.absview.max_y);
  545. }
  546.  
  547. void DoFocusNode()
  548. {
  549.     inFocusNodeMode = TRUE;
  550.     IChangeStatusLine("select a node", FALSE);
  551. }
  552.  
  553. void DoChangeText()
  554. {
  555.     inChangeTextMode = TRUE;
  556.     IChangeStatusLine("select a node", FALSE);
  557. }
  558.  
  559. static char newNodeName[MAXSTR]; 
  560. static NODE *changeTextNode;
  561. int EndChangeNodeText();
  562.  
  563. DoChangeNodeText()
  564. {
  565.     NODE *node;
  566.     node = (NODE *) ICurNode();
  567.  
  568.     changeTextNode = node;
  569.  
  570.     IChangeStatusLine("Type new node name", FALSE);
  571.     TakeTextInput(EndChangeNodeText);
  572. }
  573.  
  574. EndChangeNodeText()
  575. {
  576.     char *s;
  577.     int nameLen;
  578.     char *buf;
  579.  
  580.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  581.     OutofText(newNodeName);
  582.  
  583.     nameLen = strlen(newNodeName);
  584.     s = (char *) malloc(nameLen+1 * sizeof(char));
  585.     strcpy(s, newNodeName);
  586.  
  587.     sprintf(buf, "new node name is %s", s);
  588.     IChangeStatusLine(buf, FALSE);
  589.  
  590.     Text(changeTextNode) = s;
  591.     IChangeNodeText(s);
  592.     graphChanged = TRUE;
  593.     ckpt_done = FALSE;
  594.     dispose(buf);
  595. }
  596.  
  597. void DoChangeEdgeLabel()
  598. {
  599.     inChangeEdgeLabelMode = TRUE;
  600.     IChangeStatusLine("select an edge", FALSE);
  601. }
  602.  
  603. static char newLabel[MAXSTR];
  604. static NODE *fromNode, *toNode, *nextnode;
  605. static int ord;
  606. int EndChangeEdgeLabel();
  607.  
  608. extern NODE *get_prev_node();
  609. extern NODE *get_next_node();
  610.  
  611. DoChangeEdgeText()
  612. {
  613.     TEDGE* tedge;
  614.     VNO to_vno;
  615.  
  616.     tedge = (TEDGE *) ICurEdge();
  617.  
  618.     fromNode = (NODE *) tedge->fromnode;
  619.     toNode = (NODE *) tedge->tonode;
  620.     ord = tedge->ord;
  621.  
  622.     if (Is_dummy(fromNode) || Is_dummy(toNode))
  623.     {
  624.         if (Is_dummy(fromNode))
  625.         {
  626.             fromNode = get_prev_node(digraph, fromNode);
  627.         }
  628.     
  629.         if (Is_dummy(toNode))
  630.         {
  631.             toNode = get_next_node(digraph, toNode);
  632.         }
  633.  
  634.     each_element(Succ_set(fromNode), to_vno)
  635.     loop
  636.         if (Is_dummy(Node(digraph, to_vno)) && 
  637.         get_next_node(digraph, Node(digraph, to_vno)) == toNode)
  638.         {
  639.         nextnode = Node(digraph, to_vno);
  640.         break;
  641.         }
  642.     endloop;
  643.     }
  644.     else
  645.     {
  646.     nextnode = toNode;
  647.     }
  648.  
  649.     IChangeStatusLine("Type new edge label", FALSE);
  650.     TakeTextInput(EndChangeEdgeLabel);
  651. }
  652.  
  653. EndChangeEdgeLabel()
  654. {
  655.     char *s;
  656.     int labelLen;
  657.     OUTEDGE *outedge;
  658.     char *buf;
  659.  
  660.     buf = (char *) malloc(sizeof(char) * MAXSTR);
  661.     OutofText(newLabel);
  662.  
  663.     labelLen = strlen(newLabel);
  664.     s = (char *) malloc(labelLen+1 * sizeof(char));
  665.     strcpy(s, newLabel);
  666.  
  667.     sprintf(buf, "new edge label is %s", s);
  668.     IChangeStatusLine(buf, FALSE);
  669.  
  670.     outedge = get_edge(digraph, fromNode, toNode, ord);
  671.     Label(outedge) = s;
  672.  
  673.     IChangeEdgeLabel(fromNode, nextnode, ord, s);
  674.     graphChanged = TRUE;
  675.     ckpt_done = FALSE;
  676.     dispose(buf);
  677. }
  678.  
  679. void DoRedrawGraph()
  680. {
  681.     DoGraph();
  682. }
  683.  
  684. void DoShowLevels()
  685. {
  686.     int absY;
  687.     LEVEL *level;
  688.     MEMBER *member;
  689.     BOOL inLoop = FALSE;
  690.     int nodeThisLevelY, nodeNextLevelY;
  691.     int x, width;
  692.  
  693.     each_level(digraph, level) 
  694.     loop
  695.     inLoop = TRUE;
  696.     break;
  697.     endloop;
  698.  
  699.     if (!inLoop) 
  700.     {
  701.     IChangeStatusLine("no level structure", FALSE);
  702.     } 
  703.     else
  704.     {
  705.     width = ABSX_TO_SCRX(&screen, screen.absview.max_x);
  706.     x = ABSX_TO_SCRX(&screen, screen.absview.min_x);
  707.  
  708.         each_level(digraph, level) 
  709.         loop
  710.         if (Next_level(level) == NULL) 
  711.         {
  712.             break;
  713.         }
  714.  
  715.         each_member(level, member)
  716.         loop
  717.             nodeThisLevelY = Y_position(member);
  718.             break;
  719.         endloop
  720.  
  721.         each_member(Next_level(level), member)
  722.         loop
  723.             nodeNextLevelY = Y_position(member);
  724.             break;
  725.         endloop
  726.  
  727.         absY = nodeThisLevelY + ((nodeNextLevelY - nodeThisLevelY) / 2);
  728.         IAddLine(x, (int) ABSY_TO_SCRY(&screen, absY), 
  729.              width, (int) ABSY_TO_SCRY(&screen, absY), 
  730.              DOTTEDB, BLACK, TRUE);
  731.         endloop
  732.     }
  733. }
  734.  
  735. int EndFocusNamedNode();
  736. extern VNO get_vno();
  737.  
  738. DoFocusNamedNode()
  739. {
  740.     IChangeStatusLine("Type name of node", FALSE);
  741.     TakeTextInput(EndFocusNamedNode);
  742. }
  743.  
  744. EndFocusNamedNode()
  745. {
  746.     char nodeName[MAXSTR];
  747.     VNO vno;
  748.     char *buf;
  749.  
  750.     buf = (char *) malloc(sizeof(char) * MAXSTR);
  751.     OutofText(nodeName);
  752.  
  753.     if ((vno = get_vno(digraph, nodeName)) == (VNO) -1)
  754.     {
  755.     sprintf (buf, "No node with name %s", nodeName);
  756.     IChangeStatusLine(buf, FALSE);
  757.     }
  758.     else
  759.     {
  760.         FocusNode(Node(digraph, vno));
  761.     }
  762.  
  763.     dispose(buf);
  764. }
  765.  
  766. DoFocusCurNode()
  767. {
  768.     NODE *node;
  769.  
  770.     node = (NODE *) ICurNode();
  771.     FocusNode(node);
  772. }
  773.  
  774. FocusNode(node)
  775. NODE *node;
  776. {
  777.     float sizeX, sizeY;
  778.     int wantedX, wantedY;
  779.     float wantedMag;
  780.     int fsizeX, fsizeY;
  781.  
  782.     IChangeStatusLine("Focusing Graph", FALSE);
  783.  
  784.       /* find coordinates that should be the new 'center' of the screen */
  785.     wantedX = (int) ABSX_TO_SCRX(&screen, X_position(node)) + 
  786.             screen.display.min_x;
  787.     wantedY = (int) ABSY_TO_SCRY(&screen, Y_position(node)) +
  788.             screen.display.min_y;
  789.  
  790.       /* find magnification needed to see font */
  791.     FindFontSize(digraph, &screen, &sizeX, &sizeY);
  792.     IFindSmallestFont(&fsizeX, &fsizeY);
  793.     wantedMag = MAX (MAX((float) fsizeX / (float) sizeX, 
  794.                  (float) fsizeY / (float) sizeY), 1.0);
  795.               /* don't shrink it */
  796.  
  797.     IFocusGraph(wantedX, wantedY, wantedMag);
  798. }
  799.  
  800. FindFontSize(digraph, screen, sizeX, sizeY)
  801. DIGRAPH *digraph;
  802. SCREEN *screen;
  803. float *sizeX;
  804. float *sizeY;
  805. {
  806.     int a, b, c, d, e, f;
  807.     int width, height;
  808.  
  809.       /* find size of font to use */
  810.  
  811.     IGetBounds (&a, &b, &width, &height, &c, &d, &e, &f);
  812.     *sizeX = (float) (HALF_CHAR * 2) * (float) width /
  813.                (float) (screen->absview.max_x - screen->absview.min_x);
  814.     *sizeY = (float) get_height(digraph) * (float) height /
  815.            (float) (screen->absview.max_y - screen->absview.min_y);
  816. }
  817.  
  818.  
  819. void DoHelp()
  820. {
  821.     IPrintHelp();
  822. }
  823.  
  824. void DoShowNAttr()
  825. {
  826.     NODE* node;
  827.  
  828.     node = (NODE *) ICurNode();
  829.     IShowNAttr(node->attributes);
  830. }
  831.  
  832. void DoShowEAttr()
  833. {
  834.     TEDGE* tedge;
  835.     OUTEDGE* e;
  836.  
  837.     tedge = (TEDGE *) ICurEdge();
  838.     e = get_edge(digraph, (NODE *) tedge->fromnode, (NODE *) tedge->tonode,
  839.          tedge->ord);
  840.     IShowEAttr(e->attributes);
  841. }
  842.  
  843. void DoEraseAttrBox()
  844. {
  845.     IEraseAttrBox();
  846. }
  847.  
  848. void DoSetDisplayed()
  849. {
  850.     ISetDisplayed();
  851. }
  852.