home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xmgt23.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  426.5 KB  |  16,870 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    Board.c
  7. #    Board.h
  8. #    BoardP.h
  9. #    DirMgr.c
  10. #    DirMgr.h
  11. #    Directory.c
  12. #    Directory.h
  13. #    FileSel.c
  14. #    FileSel.h
  15. #    FileSelP.h
  16. #    Makefile.1
  17. #    MultiList.c
  18. #    MultiList.h
  19. #    MultiListP.h
  20. #    Prop.lst
  21. #    README
  22. #    README.X11
  23. #    RegExp.c
  24. #    RegExp.h
  25. #    Rules
  26. #    Sample.01
  27. #    Sample.02
  28. #    ScrList.c
  29. #    ScrList.h
  30. #    ScrListP.h
  31. #    Smart-Go.def
  32. #    Spec.io
  33. #    advunix.c
  34. #    advunix.h
  35. #    build.c
  36. #    comment.c
  37. #    doit.c
  38. #    edit.c
  39. #    format
  40. #    goserver.c
  41. #    help.c
  42. #    imakefile
  43. #    mailgo
  44. #    mailgo.6
  45. #    mgt.6
  46. #    mgt.c
  47. #    mgt.h
  48. #    parse.c
  49. #    play.c
  50. #    proto.h
  51. #    shared.h
  52. #    tree.c
  53. #    wrapmgt.6
  54. #    wrapmgt.c
  55. #    x11.4.c
  56. #    xutil.c
  57. #    xutil.h
  58. # This archive created: Wed Feb 24 16:59:47 1993
  59. export PATH; PATH=/bin:/usr/bin:$PATH
  60. if test -f 'Board.c'
  61. then
  62.     echo shar: "will not over-write existing file 'Board.c'"
  63. else
  64. cat << \SHAR_EOF > 'Board.c'
  65. /*  Board.c
  66.  *
  67.  *  Copyright (c) 1992 by Tim Casey and Chien-Min Wang.
  68.  *  All rights reserved.
  69.  */
  70.  
  71. #include <stdio.h>
  72. #include <ctype.h>
  73. #include <assert.h>
  74. #include <X11/keysymdef.h>
  75. #include <X11/StringDefs.h>
  76. #include <X11/IntrinsicP.h>
  77. #include <X11/Xaw/FormP.h>
  78. #include <X11/Xaw/ViewportP.h>
  79. #include "Board.h"
  80. #include "BoardP.h"
  81.  
  82. #define InitSize 504    /*  = 21 * 24  */
  83. #define MinWidth 150
  84. #define HT_INC(w) (w->board.length / (w->board.boardsize + 2))
  85. #define WD_INC(w) (w->board.length / (w->board.boardsize + 2))
  86. #define HT_COORD_PIX(n, w) (w->board.htinc * (w->board.boardsize - (n)) + w->board.htinc / 2)
  87. #define WD_COORD_PIX(n, w) (w->board.wdinc * ((n) + 1) + w->board.wdinc / 2) 
  88. #define DEG_X_ANGLE(d) (d * 64)
  89. #define GET_PIECE(w,i,j)    ((w)->board.pieces[i][j].p)
  90. #define GET_MARK(w,i,j)        ((w)->board.pieces[i][j].m)
  91. #define GET_LETTER(w,i,j)    ((w)->board.pieces[i][j].l)
  92.  
  93. extern XtAppContext app_context;
  94.  
  95. int resized = 0;
  96.  
  97. static void pseudo_realize(), redisplay();
  98. static XtInitProc initialize();
  99. static XtActionProc CallButtonUp(), CallButtonDown(), CallKeyDown();
  100. static XtWidgetProc destroy();
  101.  
  102. static char translations[] =
  103. "<BtnUp>:      button_up()   \n\
  104.  <BtnDown>:    button_down() \n\
  105.  <KeyDown>:    key_down()    \n\
  106. ";
  107.  
  108. static XtActionsRec actions[] =
  109. {
  110.   /* {name, procedure}, */
  111.     {"button_up",    (XtActionProc)CallButtonUp},
  112.     {"button_down",  (XtActionProc)CallButtonDown},
  113.     {"key_down",     (XtActionProc)CallKeyDown},
  114. };
  115.  
  116.  
  117. #define offset(field) XtOffset(BoardWidget, board.field)
  118.  
  119. static XtResource resources[] = {
  120.  
  121.     {XtNboardSize, XtCBoardSize, XtRInt, sizeof(int),
  122.         offset(boardsize), XtRString, "19"},
  123.  
  124.     {XtNboardColor, XtCBoardColor, XtRPixel, sizeof(Pixel),
  125.         offset(boardcolor), XtRString, "tan1"},
  126.  
  127.     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  128.         offset(foreground), XtRString, "black"},
  129.  
  130.     {XtNboardFont, XtCBoardFont, XtRFontStruct, sizeof( XFontStruct * ),
  131.         offset(font), XtRString, XtDefaultFont},
  132.  
  133.     {XtNbuttonUp, XtCButtonUp, XtRCallback, sizeof( caddr_t ),
  134.         offset(Bup), XtRPointer, NULL}, 
  135.  
  136.     {XtNbuttonDown, XtCButtonDown, XtRCallback, sizeof( caddr_t ),
  137.         offset(Bdown), XtRPointer, NULL}, 
  138.  
  139.     {XtNkeyDown, XtCKeyDown, XtRCallback, sizeof( caddr_t ),
  140.         offset(Kdown), XtRPointer, NULL}, 
  141.  
  142. };
  143. #undef offset(field)
  144.  
  145. void PutCStr(w, s, len, wd, ht, drawable)
  146.     BoardWidget w;
  147.     char *s;
  148.     int len, wd, ht;
  149. {
  150.     int x, y;
  151.     int width, height;
  152.     GC tmpGC, invGC;
  153.     unsigned long GCMask;
  154.     XGCValues GCValues;
  155.     Display *theDisplay = XtDisplay(w);
  156.  
  157.     GCMask = GCFont | GCForeground | GCBackground;
  158.     GCValues.background = w->board.foreground;
  159.     GCValues.foreground = w->board.foreground;
  160.     GCValues.font = w->board.font->fid;
  161.     tmpGC = XtGetGC(w, GCMask, &GCValues);
  162.  
  163.     GCMask = GCForeground | GCBackground;
  164.     GCValues.background = w->board.boardcolor;
  165.     GCValues.foreground = w->board.boardcolor;
  166.     invGC = XtGetGC(w, GCMask, &GCValues);
  167.  
  168.     width = XTextWidth( w->board.font, s, len);
  169.     height = w->board.font->ascent + w->board.font->descent;
  170.  
  171.     x = wd - (width / 2);
  172.     y = ht + (height / 2) - 2;
  173.  
  174.     if (x < 0)
  175.         x = 0;
  176.     if (x > w->core.width)
  177.         x = w->core.width;
  178.     if (y > w->core.height)
  179.         y = w->core.height;
  180.     
  181.     XFillRectangle(theDisplay, drawable, invGC, x - 2, y - (height / 2) - 4, 
  182.                             width + 4, height + 2);
  183.     XDrawString(theDisplay, drawable, tmpGC, x, y, s, len);
  184.  
  185.     XtReleaseGC(w, tmpGC);
  186. }
  187.  
  188. static void redisplay( w, evnt, regn)
  189.     BoardWidget w;
  190.     XEvent *evnt;
  191.     Region regn;
  192. {
  193. #ifdef DEBUG
  194.     fprintf(stderr, "redisplay called\n");
  195. #endif
  196.  
  197.     XCopyArea(XtDisplay(w), w->board.board, w->core.window, w->board.gc,
  198.     0, 0, w->core.width, w->core.height, 0, 0);
  199. }
  200.  
  201. static void resize( w )
  202.     BoardWidget w;
  203. {
  204.     int        i, j;
  205.     BWPiece    p;
  206.     BWMark    m;
  207.     char    l;
  208.  
  209. #ifdef DEBUG
  210.     fprintf(stderr, "resize called\n");
  211. #endif
  212.     
  213.     if (resized == 0) {
  214.     resized = 1;
  215.     return;
  216.     }
  217.  
  218.     if ( ! XtIsRealized( w ) )
  219.         return;
  220.  
  221.     destroy(w);
  222.     pseudo_realize(w);
  223.     XCopyArea( XtDisplay(w), w->board.backing, w->board.board, w->board.gc,
  224.     0, 0, w->core.width, w->core.height, 0, 0);
  225.     for(i=0 ; i < w->board.boardsize ; i++ ) {
  226.     for(j=0 ; j < w->board.boardsize ; j++) {
  227.         p = GET_PIECE (w, i, j);
  228.         m = GET_MARK  (w, i, j);
  229.         l = GET_LETTER(w, i, j);
  230.         BWPutPiece (w, i, j, p);
  231.         BWSetMark  (w, i, j, m);
  232.         BWSetLetter(w, i, j, l);
  233.     }
  234.     }
  235. }
  236.  
  237. void reconfig(bw, fw, vw)
  238. BoardWidget bw;
  239. FormWidget fw;
  240. ViewportWidget vw;
  241. {
  242.     int diff, diff1, diff2;
  243.     FormConstraints form;
  244.  
  245.     diff1 = bw->core.width - bw->core.height;
  246.     diff2 = MinWidth - fw->core.width;
  247.     diff  = (diff1 > diff2) ? diff1 : diff2;
  248.     diff += (bw->core.width - diff) % 21;
  249.     if (diff == 0) {
  250.     resize(bw);
  251.     return;
  252.     }
  253.     form = (FormConstraints) bw->core.constraints;
  254.     form->form.virtual_width = bw->core.width - diff;
  255.     XtResizeWidget(bw, bw->core.width - diff,
  256.                bw->core.height, bw->core.border_width);
  257.     form = (FormConstraints) fw->core.constraints;
  258.     form->form.virtual_width = fw->core.width + diff;
  259.     XtMoveWidget(fw, fw->core.x - diff, fw->core.y);
  260.     XtResizeWidget(fw, fw->core.width + diff,
  261.                fw->core.height, fw->core.border_width);
  262.     form = (FormConstraints) vw->core.constraints;
  263.     form->form.virtual_width = vw->core.width + diff;
  264.     XtMoveWidget(vw, vw->core.x - diff, vw->core.y);
  265.     XtResizeWidget(vw, vw->core.width + diff,
  266.                vw->core.height, vw->core.border_width);
  267. }
  268.  
  269. static Boolean setVals( cur, req, new )
  270.     BoardWidget cur, req, new;
  271. {
  272.     return( False );
  273. }
  274.  
  275. /* Need a fake realize, so I can use it to re-do the board pixmaps, 
  276.  * for resizing.
  277.  */
  278. static XtRealizeProc realize(w, mask, attr)
  279.     BoardWidget w;
  280.     Mask *mask;
  281.     XSetWindowAttributes *attr;
  282. {
  283. #ifdef DEBUG
  284.     fprintf(stderr, "realize called\n");
  285. #endif
  286.  
  287.     XtCreateWindow(w, InputOutput, (Visual *) CopyFromParent,
  288.         *mask, attr); /* I hope, from some x docs. */
  289.  
  290.     pseudo_realize(w);
  291.  
  292.     return 0;
  293. }
  294.  
  295. static int pts[21][2] = {
  296.     {0, 1},
  297.     {0, 1}, /* 1 */
  298.     {0, 1},
  299.     {0, 1},
  300.     {0, 1},
  301.     {0, 1}, /* 5 */
  302.     {0, 1},
  303.     {0, 1},
  304.     {0, 1},
  305.     {2, 4}, /* 9 */
  306.     {0, 1},
  307.     {3, 4}, /* 11 */
  308.     {0, 1},
  309.     {3, 3}, /* 13 */
  310.     {0, 1},
  311.     {0, 1}, /* 15 */
  312.     {0, 1},
  313.     {0, 1}, /* 17 */
  314.     {0, 1},
  315.     {3, 6}, /* 19 */
  316.     {0, 1},
  317. };
  318.  
  319. static void SetUpStarPts(w)
  320.     BoardWidget w;
  321. {
  322.     int brdsz = w->board.boardsize;
  323.     int st, inc;
  324.     int i, j;
  325.     Dimension x, y;
  326.     Display *theDpy = XtDisplay(w);;
  327.  
  328.     st  = pts[brdsz][0];
  329.     inc = pts[brdsz][1];
  330.  
  331.     for(i=st ; i < brdsz ; i += inc ) {
  332.     for(j=st ; j < brdsz ; j += inc ) {
  333.  
  334.         x = WD_COORD_PIX(i, w);
  335.         y = HT_COORD_PIX(j, w);
  336.  
  337.         XFillRectangle(theDpy, w->board.backing, w->board.gc,
  338.         x - 2, y - 2, 5, 5);
  339.     }
  340.     }
  341. }
  342.  
  343. /* 
  344.  * This is called on resize as well as "realize".
  345.  * I should create the GCs in "realize"
  346.  */
  347. static void pseudo_realize(w)
  348.     BoardWidget w;
  349. {
  350.     Dimension wd, ht, stonewd, stoneht, st, end;
  351.     unsigned long GCMask;
  352.     XGCValues GCVals;
  353.     GC invGC;
  354.     Display *theDisplay;
  355.     Window boardWindow;
  356.     int i;
  357.     char label[3];
  358.  
  359. #ifdef DEBUG
  360.     fprintf(stderr, "pseudo_realize called\n");
  361. #endif /* DEBUG */
  362.  
  363.     boardWindow = w->core.window;
  364.     theDisplay = XtDisplay(w);
  365.  
  366.     w->board.length = (w->core.width <= w->core.height) ? w->core.width
  367.                             : w->core.height;
  368.     wd = w->core.width;
  369.     ht = w->core.height;
  370.     stoneht = w->board.htinc = HT_INC(w);
  371.     stonewd = w->board.wdinc = WD_INC(w);
  372.  
  373.     /*
  374.      * Pixmap hell
  375.      */
  376.     w->board.backing = XCreatePixmap(theDisplay, boardWindow, 
  377.                             wd, ht, w->core.depth);
  378.     w->board.board = XCreatePixmap(theDisplay, boardWindow, 
  379.                             wd, ht, w->core.depth);
  380.     w->board.white = XCreatePixmap(theDisplay, boardWindow, 
  381.                         stonewd, stoneht, w->core.depth);
  382.     w->board.black = XCreatePixmap(theDisplay, boardWindow, 
  383.                         stonewd, stoneht, w->core.depth);
  384.     w->board.dame  = XCreatePixmap(theDisplay, boardWindow, 
  385.                         stonewd, stoneht, w->core.depth);
  386.     w->board.bterr = XCreatePixmap(theDisplay, boardWindow, 
  387.                         stonewd, stoneht, w->core.depth);
  388.     w->board.wterr = XCreatePixmap(theDisplay, boardWindow, 
  389.                         stonewd, stoneht, w->core.depth);
  390.     w->board.last  = XCreatePixmap(theDisplay, boardWindow, 
  391.                         stonewd, stoneht, w->core.depth);
  392.  
  393.  
  394.     GCMask = GCForeground | GCBackground;
  395.     GCVals.foreground = w->board.foreground;
  396.     GCVals.background = w->core.background_pixel;
  397.     w->board.gc = XCreateGC( theDisplay, w->board.board, GCMask, &GCVals );
  398.  
  399.  
  400.     GCVals.background = w->board.boardcolor;
  401.     GCVals.foreground = w->board.boardcolor;
  402.     invGC = XCreateGC( theDisplay, w->board.board, GCMask, &GCVals );
  403.  
  404.     XFillRectangle( theDisplay, w->board.backing, invGC,
  405.         0, 0, wd, ht );
  406.     XFillRectangle( theDisplay, w->board.board, invGC,
  407.         0, 0, wd, ht );
  408.     XFillRectangle( theDisplay, w->board.black, invGC,
  409.         0, 0, stonewd, stoneht );
  410.     XFillRectangle( theDisplay, w->board.white, invGC,
  411.         0, 0, stonewd, stoneht );
  412.     XFillRectangle( theDisplay, w->board.dame, invGC,
  413.         0, 0, stonewd, stoneht );
  414.     XFillRectangle( theDisplay, w->board.bterr, invGC,
  415.         0, 0, stonewd, stoneht );
  416.     XFillRectangle( theDisplay, w->board.wterr, invGC,
  417.         0, 0, stonewd, stoneht );
  418.  
  419.     st = WD_COORD_PIX(0, w);
  420.     end = WD_COORD_PIX(w->board.boardsize - 1, w);
  421.     for(i=0 ; i < w->board.boardsize ; i++ ) {
  422.     int pos;
  423.  
  424.     sprintf(label,"%2d", i+1);
  425.     pos = HT_COORD_PIX(i, w);
  426.     XDrawLine(theDisplay, w->board.backing, w->board.gc, st, pos, end, pos);
  427.     PutCStr(w, label, 2, st - stonewd, pos, w->board.backing);
  428.     PutCStr(w, label, 2, end + stonewd, pos, w->board.backing);
  429.     }
  430.     st = HT_COORD_PIX(0, w);
  431.     end = HT_COORD_PIX(w->board.boardsize - 1, w);
  432.     for(i=0 ; i < w->board.boardsize ; i++ ) {
  433.     int pos;
  434.  
  435.     label[0] = INDEX_TO_CHAR(i);
  436.     pos = WD_COORD_PIX(i, w);
  437.  
  438.     XDrawLine(theDisplay, w->board.backing, w->board.gc, pos, st, pos, end);
  439.     PutCStr(w, label, 1, pos, st + stoneht, w->board.backing);
  440.     PutCStr(w, label, 1, pos, end - stoneht, w->board.backing);
  441.     }
  442.  
  443.     SetUpStarPts( w );
  444.  
  445.     /*
  446.      * the piece pixmaps
  447.      */
  448.     XFillArc(theDisplay, w->board.black, w->board.gc, 
  449.         0, 0, w->board.wdinc-1, w->board.htinc-1, 0, DEG_X_ANGLE(360));
  450.  
  451.     XDrawArc(theDisplay, w->board.black, w->board.gc, 
  452.         0, 0, w->board.wdinc-1, w->board.htinc-1, 0, DEG_X_ANGLE(360));
  453.  
  454.     XSetForeground(theDisplay, invGC, w->core.background_pixel);
  455.     XSetBackground(theDisplay, invGC, w->board.boardcolor);
  456.  
  457.     XFillArc(theDisplay, w->board.white, invGC, 
  458.         0, 0, w->board.wdinc-1, w->board.htinc-1, 0, DEG_X_ANGLE(360));
  459.  
  460.     XSetForeground(theDisplay, invGC, w->board.foreground);
  461.  
  462.     XDrawArc(theDisplay, w->board.white, invGC, 
  463.         0, 0, w->board.wdinc-1, w->board.htinc-1, 0, DEG_X_ANGLE(360));
  464.  
  465.     /*
  466.      * Territory
  467.      */
  468.     XFillRectangle(theDisplay, w->board.bterr, w->board.gc, 
  469.     stonewd/4, stoneht/4, stonewd/2, stoneht/2);
  470.     
  471.     XSetForeground(theDisplay, invGC, w->core.background_pixel);
  472.     XSetBackground(theDisplay, invGC, w->board.boardcolor);
  473.     
  474.     XFillRectangle(theDisplay, w->board.wterr, invGC, 
  475.     stonewd/4, stoneht/4, stonewd/2, stoneht/2);
  476.  
  477.     XSetForeground(theDisplay, invGC, w->board.foreground);
  478.     
  479.     XDrawRectangle(theDisplay, w->board.wterr, invGC, 
  480.     stonewd/4, stoneht/4, stonewd/2, stoneht/2);
  481.  
  482.     /*
  483.      * dame
  484.      */
  485.     XDrawRectangle(theDisplay, w->board.dame, w->board.gc, 
  486.     stonewd/4, stoneht/4, stonewd/2, stoneht/2);
  487.     XDrawLine(theDisplay, w->board.dame, w->board.gc,
  488.     stonewd/4, stoneht/4, 3 * stonewd/4, 3 * stoneht/4);
  489.     XDrawLine(theDisplay, w->board.dame, w->board.gc,
  490.     stonewd/4, 3 * stoneht/4, 3 * stonewd/4, stoneht/4);
  491.  
  492.     XFreeGC( theDisplay, invGC );
  493. }
  494.  
  495. static XtWidgetProc destroy(w)
  496.     BoardWidget w;
  497. {
  498.     Display *theDisplay = XtDisplay(w);
  499.  
  500.     if ( ! XtIsRealized( w ) )
  501.         return 0;
  502.  
  503.     /*
  504.      * Pixmap hell
  505.      */
  506.     XFreePixmap(theDisplay, w->board.board);
  507.     XFreePixmap(theDisplay, w->board.backing);
  508.     XFreePixmap(theDisplay, w->board.white);
  509.     XFreePixmap(theDisplay, w->board.black);
  510.     XFreePixmap(theDisplay, w->board.dame);
  511.     XFreePixmap(theDisplay, w->board.bterr);
  512.     XFreePixmap(theDisplay, w->board.wterr);
  513.     XFreePixmap(theDisplay, w->board.last);
  514.     XFreeGC( theDisplay, w->board.gc );
  515.  
  516.     return 0;
  517. }
  518.  
  519. static XtActionProc CallButtonUp( w, evnt, str, n )
  520.     BoardWidget w;
  521.     XButtonEvent *evnt; /* we know it to be a union */
  522.     String *str;
  523.     Cardinal *n;
  524. {
  525.     evnt->x = (evnt->x - w->board.wdinc) / w->board.wdinc;
  526.     if (evnt->x >= w->board.boardsize)
  527.     evnt->x = evnt->y = -1;
  528.     evnt->y = w->board.boardsize - (evnt->y / w->board.htinc);
  529.     if (evnt->y >= w->board.boardsize)
  530.     evnt->x = evnt->y = -1;
  531.     XtCallCallbacks( w, XtNbuttonUp, evnt);
  532.     return 0;
  533. }
  534.  
  535. static XtActionProc CallButtonDown( w, evnt, str, n )
  536.     BoardWidget w;
  537.     XButtonEvent *evnt; /* we know it to be a union */
  538.     String *str;
  539.     Cardinal *n;
  540. {
  541.     evnt->x = (evnt->x - w->board.wdinc) / w->board.wdinc;
  542.     if (evnt->x >= w->board.boardsize)
  543.     evnt->x = evnt->y = -1;
  544.     evnt->y = w->board.boardsize - (evnt->y / w->board.htinc);
  545.     if (evnt->y >= w->board.boardsize)
  546.     evnt->x = evnt->y = -1;
  547.     XtCallCallbacks( w, XtNbuttonDown, evnt);
  548.     return 0;
  549. }
  550.  
  551. static XtActionProc CallKeyDown( w, evnt, str, n )
  552.     BoardWidget w;
  553.     XButtonEvent *evnt; /* we know it to be a union */
  554.     String *str;
  555.     Cardinal *n;
  556. {
  557.     XtCallCallbacks( w, XtNkeyDown, evnt );
  558.     return 0;
  559. }
  560.  
  561. static XtActionProc CallResize( w, evnt, str, n )
  562.     BoardWidget w;
  563.     XButtonEvent *evnt; /* we know it to be a union */
  564.     String *str;
  565.     Cardinal *n;
  566. {
  567.     XtCallCallbacks( w, XtNresize, evnt);
  568.     return 0;
  569. }
  570.  
  571.  
  572. static void ClassInitialize();
  573.  
  574. BoardClassRec boardClassRec = {
  575.     {
  576.         (WidgetClass)        &widgetClassRec,
  577.         (String)        "Board",
  578.         (Cardinal)        sizeof(BoardRec),
  579.         (XtProc)        ClassInitialize, /* called only once */
  580.         (XtWidgetClassProc)    NULL, /* class part init */
  581.         (Boolean)        False,
  582.         (XtInitProc)        initialize,
  583.         (XtArgsProc)        NULL,
  584.         (XtRealizeProc)        realize,
  585.         (XtActionList)        actions,
  586.         (Cardinal)        XtNumber(actions),
  587.         (XtResourceList)    resources,
  588.         (Cardinal)        XtNumber( resources ),
  589.         (XrmClass)        NULLQUARK,
  590.         (Boolean)        False,
  591.         (Boolean)        True, /* Compress exposure */
  592.         (Boolean)        False,
  593.         (Boolean)        True, /* Visible interest */
  594.         (XtWidgetProc)        destroy,
  595.         (XtWidgetProc)        resize,
  596.         (XtWidgetProc)        redisplay,
  597.         (XtSetValuesFunc)    setVals,
  598.         (XtArgsFunc)            NULL, /* set vals hook */
  599.         (XtAlmostProc)        XtInheritSetValuesAlmost,
  600.         (XtArgsProc)            NULL,
  601.         (XtAcceptFocusProc)    NULL,
  602.         (XtVersionType)        XtVersion,
  603.                     NULL,
  604.         (String)                NULL,
  605.         (XtGeometryHandler)    XtInheritQueryGeometry,
  606.         (XtStringProc)        XtInheritDisplayAccelerator,
  607.         (caddr_t)        NULL
  608.     },
  609.     {
  610.         NULL,
  611.         NULL,
  612.     }
  613. };
  614.  
  615. WidgetClass boardWidgetClass = (WidgetClass)&boardClassRec;
  616.  
  617. static XtInitProc initialize( req, new )
  618.     BoardWidget req, new;
  619. {
  620.     if (req->core.height <= 0)
  621.         new->core.height = InitSize;
  622.  
  623.     if (req->core.width <= 0)
  624.         new->core.width = InitSize;
  625.  
  626.     new->board.curhx = -1; /* flag for highlight */
  627.     XtAugmentTranslations((Widget) new, boardClassRec.board_class.translations);
  628.  
  629.     /*
  630.      * Need to put in something to protect the color of the board.
  631.      * If tan1 was not allocated, then the background needs to be white.
  632.      */
  633.     return 0;
  634. }
  635.  
  636. static void ClassInitialize()
  637. {
  638.     boardClassRec.board_class.translations = 
  639.         XtParseTranslationTable( translations );
  640. }
  641.  
  642. static void BWUpdatePos(w, i, j)
  643.     BoardWidget w;
  644.     int i, j;
  645. {
  646.     Dimension x, y;
  647.  
  648. #ifdef DEBUG
  649.     fprintf(stderr, "UpdatePos called %d %d\n", i, j);
  650. #endif
  651.  
  652.     x = WD_COORD_PIX(i, w) - w->board.wdinc / 2;
  653.     y = HT_COORD_PIX(j, w) - w->board.htinc / 2;
  654.  
  655.     XCopyArea( XtDisplay( w ), w->board.board, w->core.window, w->board.gc,
  656.         x, y, w->board.wdinc, w->board.htinc, x, y );
  657. }
  658.  
  659. void BWUpdateBoard( w )
  660.     BoardWidget w;
  661. {
  662. #ifdef DEBUG
  663.     fprintf(stderr, "UpdateBoard called\n");
  664. #endif
  665.  
  666.     XCopyArea( XtDisplay( w ), w->board.board, w->core.window, w->board.gc,
  667.         0, 0, w->core.width, w->core.height, 0, 0 );
  668. }
  669.  
  670. void BWClearBoard( w )
  671.     BoardWidget w;
  672. {
  673.     long GCMask;
  674.     XGCValues GCVals;
  675.     GC tmpgc;
  676.  
  677. #ifdef DEBUG
  678.     fprintf(stderr, "ClearBoard called\n");
  679. #endif
  680.  
  681.     GCMask = GCForeground | GCBackground;
  682.     GCVals.foreground = w->core.background_pixel;
  683.     GCVals.background = w->board.foreground;
  684.  
  685.     tmpgc = XtGetGC( w, GCMask, &GCVals );
  686.     /*
  687.      * XCopyArea backing --> board
  688.      */
  689.     BWUpdateBoard( w );
  690.     w->board.curhx = -1;
  691.     
  692.     XtReleaseGC( w, tmpgc );
  693. }
  694.  
  695. void BWReset(w)
  696.     BoardWidget w;
  697. {
  698.     int i, j;
  699.  
  700. #ifdef DEBUG
  701.     fprintf(stderr, "Reset called\n");
  702. #endif
  703.  
  704.     XCopyArea( XtDisplay(w), w->board.backing, w->board.board,
  705.     w->board.gc,
  706.     0, 0, w->core.width, w->core.height,
  707.     0, 0);
  708.     BWUpdateBoard(w);
  709.  
  710.     w->board.curhx = -1;
  711.     for(i=0 ; i < w->board.boardsize ; i++) {
  712.     for(j=0 ; j < w->board.boardsize ; j++) {
  713.        w->board.pieces[i][j].p = Empty;
  714.        w->board.pieces[i][j].m = NoMark;
  715.        w->board.pieces[i][j].l = '\0';
  716.     }
  717.     }
  718. }
  719.  
  720. void BWUnhighlight(w)
  721.     BoardWidget w;
  722. {
  723.     int x, y;
  724.  
  725. #ifdef DEBUG
  726.     fprintf(stderr, "Unhighlight called\n");
  727. #endif
  728.  
  729.     if (w->board.curhx == -1)
  730.     return;
  731.  
  732.     x = WD_COORD_PIX(w->board.curhx, w) - w->board.wdinc / 2;
  733.     y = HT_COORD_PIX(w->board.curhy, w) - w->board.htinc / 2;
  734.     XCopyArea(XtDisplay(w), w->board.last, w->board.board, w->board.gc,
  735.             0, 0, w->board.wdinc, w->board.htinc, x, y);
  736.     BWUpdatePos(w, w->board.curhx, w->board.curhy);
  737.     w->board.curhx = -1;
  738. }
  739.  
  740. void BWHighlightPiece(w, i, j)
  741.     BoardWidget w;
  742.     int i, j;
  743. {
  744.     Dimension x, y;
  745.  
  746. #ifdef DEBUG
  747.     fprintf(stderr, "HighlightPiece called %d %d\n", i, j);
  748. #endif
  749.  
  750.     BWUnhighlight(w);
  751.  
  752.     x = WD_COORD_PIX(i, w) - w->board.wdinc / 2;
  753.     y = HT_COORD_PIX(j, w) - w->board.htinc / 2;
  754.     XCopyArea(XtDisplay(w), w->board.board, w->board.last, w->board.gc,
  755.             x, y, w->board.wdinc, w->board.htinc, 0, 0);
  756.     XDrawRectangle(XtDisplay(w), w->board.board, w->board.gc,
  757.             x, y, w->board.wdinc - 1, w->board.htinc - 1);
  758.     w->board.curhx = i;
  759.     w->board.curhy = j;
  760.     BWUpdatePos(w, i, j);
  761. }
  762.  
  763. void BWPutPiece(w, i, j, p)
  764.     BoardWidget w;
  765.     int i, j;
  766.     BWPiece p;
  767. {
  768.     Dimension x, y;
  769.     Display *theDisplay = XtDisplay(w);
  770.  
  771. #ifdef DEBUG
  772.     fprintf(stderr, "PutPiece called %d %d %d\n", i, j, p);
  773. #endif
  774.  
  775.     BWUnhighlight(w);
  776.  
  777.     x = WD_COORD_PIX(i, w) - w->board.wdinc / 2;
  778.     y = HT_COORD_PIX(j, w) - w->board.htinc / 2;
  779.  
  780.     switch( p ) {
  781.     case Empty:
  782.     XCopyArea(theDisplay, w->board.backing, w->board.board, w->board.gc,
  783.                 x, y, w->board.wdinc, w->board.htinc, x, y);
  784.     break;
  785.     case Black:
  786.     XCopyArea(theDisplay, w->board.black, w->board.board, w->board.gc,
  787.                 0, 0, w->board.wdinc, w->board.htinc, x, y);
  788.     break;
  789.     case White:
  790.     XCopyArea(theDisplay, w->board.white, w->board.board, w->board.gc,
  791.                 0, 0, w->board.wdinc, w->board.htinc, x, y);
  792.     break;
  793.     case Dame:
  794.     XCopyArea(theDisplay, w->board.dame, w->board.board, w->board.gc,
  795.                 0, 0, w->board.wdinc, w->board.htinc, x, y);
  796.     break;
  797.     case WhiteTerritory:
  798.     XCopyArea(theDisplay, w->board.wterr, w->board.board, w->board.gc,
  799.                 0, 0, w->board.wdinc, w->board.htinc, x, y);
  800.     break;
  801.     case BlackTerritory:
  802.     XCopyArea(theDisplay, w->board.bterr, w->board.board, w->board.gc,
  803.                 0, 0, w->board.wdinc, w->board.htinc, x, y);
  804.     break;
  805.     default:
  806.     XtAppWarning(app_context, "BWPutPiece:  Not a valid Piece");
  807.     return;
  808.     break;
  809.     }
  810.  
  811.     w->board.pieces[i][j].p = p;
  812.     w->board.pieces[i][j].m = NoMark;
  813.     w->board.pieces[i][j].l = '\0';
  814.     BWUpdatePos(w, i, j);
  815. }
  816.  
  817. void BWSetMark(w, i, j, m)
  818.     BoardWidget w;
  819.     int i, j;
  820.     BWMark m;
  821. {
  822.     Dimension deltax, deltay;
  823.     Dimension x, y;
  824.     long GCMask;
  825.     XGCValues GCVals;
  826.     GC tmpgc;
  827.     BWPiece p;
  828.     XPoint lines[5];
  829.     int linecnt = 0;
  830.  
  831. #ifdef DEBUG
  832.     fprintf(stderr, "SetMark called %d %d %d\n", i, j, m);
  833. #endif
  834.  
  835.     p = GET_PIECE(w, i, j);
  836.  
  837.     GCMask = GCForeground | GCBackground;
  838.     if( p == Black ) {
  839.         GCVals.foreground = w->core.background_pixel;
  840.         GCVals.background = w->board.foreground;
  841.     } else {
  842.         GCVals.background = w->core.background_pixel;
  843.         GCVals.foreground = w->board.foreground;
  844.     }
  845.     tmpgc = XtGetGC( w, GCMask, &GCVals );
  846.  
  847.     x = WD_COORD_PIX(i, w);
  848.     y = HT_COORD_PIX(j, w);
  849.  
  850.     switch( m ) {
  851.     case NoMark:
  852.     break;
  853.  
  854.     case SquareMark:
  855.         deltax = w->board.wdinc / 4;
  856.         deltay = w->board.htinc / 4;
  857.     lines[linecnt].x = x - deltax; 
  858.     lines[linecnt].y = y - deltay;
  859.     linecnt++;
  860.     lines[linecnt].x = x + deltax; 
  861.     lines[linecnt].y = y - deltay;
  862.     linecnt++;
  863.     lines[linecnt].x = x + deltax; 
  864.     lines[linecnt].y = y + deltay;
  865.     linecnt++;
  866.     lines[linecnt].x = x - deltax; 
  867.     lines[linecnt].y = y + deltay;
  868.     linecnt++;
  869.     lines[linecnt].x = x - deltax; 
  870.     lines[linecnt].y = y - deltay;
  871.     linecnt++;
  872.     break;
  873.  
  874.     case TriangleMark:
  875.         deltax = w->board.wdinc / 3;
  876.         deltay = w->board.htinc / 3;
  877.     lines[linecnt].x = x; 
  878.     lines[linecnt].y = y - deltay;
  879.     linecnt++;
  880.     lines[linecnt].x = x + deltax;
  881.     lines[linecnt].y = y + deltay;
  882.     linecnt++;
  883.     lines[linecnt].x = x - deltax;
  884.     lines[linecnt].y = y + deltay;
  885.     linecnt++;
  886.     lines[linecnt].x = x; 
  887.     lines[linecnt].y = y - deltay;
  888.     linecnt++;
  889.     break;
  890.  
  891.     case DiamondMark:
  892.         deltax = w->board.wdinc / 3;
  893.         deltay = w->board.htinc / 3;
  894.     lines[linecnt].x = x; 
  895.     lines[linecnt].y = y - deltay;
  896.     linecnt++;
  897.     lines[linecnt].x = x + deltax; 
  898.     lines[linecnt].y = y;
  899.     linecnt++;
  900.     lines[linecnt].x = x; 
  901.     lines[linecnt].y = y + deltay;
  902.     linecnt++;
  903.     lines[linecnt].x = x - deltax;
  904.     lines[linecnt].y = y;
  905.     linecnt++;
  906.     lines[linecnt].x = x; 
  907.     lines[linecnt].y = y - deltay;
  908.     linecnt++;
  909.     break;
  910.  
  911.     case XMark:
  912.     XtAppWarning(app_context, "BWSetMark: XMark, not implemented.");
  913.     return;
  914.     break;
  915.  
  916.     case HLineMark:
  917.     XtAppWarning(app_context, "BWSetMark: HLineMark, not implemented.");
  918.     return;
  919.     break;
  920.  
  921.     case VLineMark:
  922.     XtAppWarning(app_context, "BWSetMark: VLineMark, not implemented.");
  923.     return;
  924.     break;
  925.  
  926.     default:
  927.     XtAppWarning(app_context, "BWSetMark:  Not a valid Mark");
  928.     return;
  929.     break;
  930.     }
  931.  
  932.     w->board.pieces[i][j].m = m;
  933.     BWUnhighlight(w);
  934.     XDrawLines(XtDisplay(w), w->board.board, tmpgc, 
  935.         lines, linecnt, CoordModeOrigin);
  936.     XtReleaseGC(w, tmpgc);
  937.     BWUpdatePos(w, i, j);
  938. }
  939.  
  940. BWPiece BWGetPiece(w, i, j)
  941.     BoardWidget w;
  942.     int i, j;
  943. {
  944. #ifdef DEBUG
  945.     fprintf(stderr, "GetPiece called %d %d\n", i, j);
  946. #endif
  947.  
  948.     return GET_PIECE(w, i, j);
  949. }
  950.  
  951. void BWSetLetter(w, i, j, c)
  952.     BoardWidget w;
  953.     int i, j;
  954.     char c;
  955. {
  956.     BWPiece p;
  957.     Dimension x, y;
  958.  
  959. #ifdef DEBUG
  960.     fprintf(stderr, "SetLetter called %d %d %c\n", i, j, c);
  961. #endif
  962.  
  963.     p = GET_PIECE(w, i, j);
  964.  
  965.     if (p != Empty && isalpha(c)) {
  966.     XtAppWarning(app_context, "Letters on non-empty spaces not supported");
  967.     return;
  968.     }
  969.  
  970. #if 0
  971.     x = WD_COORD_PIX(i, w) + w->board.wdinc / 4;
  972.     y = HT_COORD_PIX(j, w) + w->board.htinc / 4;
  973. #else
  974.     x = WD_COORD_PIX(i, w);
  975.     y = HT_COORD_PIX(j, w);
  976. #endif
  977.  
  978.     w->board.pieces[i][j].l = c;
  979.     BWUnhighlight(w);
  980.     if (isalpha(c))
  981.         PutCStr(w, &c, 1, x, y, w->board.board);
  982.     BWUpdatePos(w, i, j);
  983. }
  984. SHAR_EOF
  985. fi
  986. if test -f 'Board.h'
  987. then
  988.     echo shar: "will not over-write existing file 'Board.h'"
  989. else
  990. cat << \SHAR_EOF > 'Board.h'
  991. /*  Board.h
  992.  *
  993.  *  Copyright (c) 1992 by Tim Casey and Chien-Min Wang.
  994.  *  All rights reserved.
  995.  */
  996.  
  997. #ifndef Board_h
  998. #define Board_h
  999.  
  1000. #define INDEX_TO_CHAR(n) ( (n) >= 8 ? (n) + 'A' + 1 : (n) + 'A')
  1001.  
  1002. #define XtNboardFont "boardFont"
  1003. #define XtCBoardFont "BoardFont"
  1004.  
  1005. #define XtNboardSize "boardSize"
  1006. #define XtCBoardSize "BoardSize"
  1007.  
  1008. #define XtNdoText "doText"
  1009. #define XtCDoText "DoText"
  1010.  
  1011. #define XtNboardColor "boardColor"
  1012. #define XtCBoardColor "BoardColor"
  1013.  
  1014. #define XtNbuttonDown "buttonDown"
  1015. #define XtCButtonDown "ButtonDown"
  1016.  
  1017. #define XtNbuttonUp "buttonUp"
  1018. #define XtCButtonUp "ButtonUp"
  1019.  
  1020. #define XtNkeyUp "keyUp"
  1021. #define XtCKeyUp "KeyUp"
  1022.  
  1023. #define XtNkeyDown "keyDown"
  1024. #define XtCKeyDown "KeyDown"
  1025.  
  1026. typedef struct _BoardClassRec *BoardWidgetClass;
  1027. typedef struct _BoardRec *BoardWidget;
  1028.  
  1029. typedef enum {
  1030.     Empty, Black, White, Dame, BlackTerritory, WhiteTerritory
  1031. } BWPiece;
  1032.  
  1033. typedef enum {
  1034.     NoMark, SquareMark, TriangleMark, DiamondMark, XMark, HLineMark, VLineMark
  1035. } BWMark;
  1036.  
  1037. typedef struct {
  1038.     BWPiece p;
  1039.     BWMark m;
  1040.     char l;
  1041. } BWIntPiece;
  1042.  
  1043. extern WidgetClass boardWidgetClass;
  1044.  
  1045. extern Pixmap BoardPix(/*w*/);
  1046. extern GC BoardGC(/*w*/);
  1047. extern void GetBoardDimensions(/*  w, *i, *j  */);
  1048.  
  1049. extern void BWUpdateBoard( /* w */ );
  1050. extern void BWUpdatePos( /* w, i, j, p */ );
  1051. extern void BWClearBoard(/*w*/);
  1052. extern void BWReset( /* w */ );
  1053. extern void BWHighlightPiece( /* w, i, j */ );
  1054. extern void BWUnighlight( /* w */ );
  1055. extern void BWPutPiece( /* w, i, j, p */ );
  1056. extern void BWSetLetter( /* w, i, j, p */ );
  1057. extern void BWSetMark( /* w, i, j, p */ );
  1058. extern BWPiece BWGetPiece( /* w, i, j */ );
  1059.  
  1060. extern int resized;
  1061.  
  1062. #endif Board_h
  1063. SHAR_EOF
  1064. fi
  1065. if test -f 'BoardP.h'
  1066. then
  1067.     echo shar: "will not over-write existing file 'BoardP.h'"
  1068. else
  1069. cat << \SHAR_EOF > 'BoardP.h'
  1070. /*  BoardP.h
  1071.  *
  1072.  *  Copyright (c) 1992 by Tim Casey and Chien-Min Wang.
  1073.  *  All rights reserved.
  1074.  */
  1075.  
  1076. #ifndef BoardP_h
  1077. #define BoardP_h
  1078.  
  1079. #include "Board.h"
  1080. #include <X11/CoreP.h>
  1081.  
  1082. #define MAX_SIZE 21
  1083. #define X_ARC(n) (n * 64)
  1084.  
  1085.  
  1086. typedef struct {
  1087.     XtWidgetProc buttonProc;
  1088.     XtTranslations translations;
  1089. } BoardClassPart;
  1090.  
  1091. typedef struct _BoardClassRec {
  1092.     CoreClassPart    core_class;
  1093.     BoardClassPart    board_class;
  1094. } BoardClassRec;
  1095.  
  1096. extern BoardClassRec boardClassRec;
  1097.  
  1098. typedef struct {
  1099.     /* resources */
  1100.     Pixel foreground, boardcolor;
  1101.     XFontStruct *font;
  1102.     XtCallbackList Bup, Bdown, Kdown;
  1103.     int boardsize;
  1104.  
  1105.     /* private state info */
  1106.     Pixmap board, backing, white, black, dame, bterr, wterr, last, bhi, whi;
  1107.     GC gc;
  1108.     int htinc, wdinc, length;
  1109.     BWIntPiece pieces[19][19];
  1110.     int curhx, curhy;
  1111. } BoardPart;
  1112.  
  1113. typedef struct _BoardRec {
  1114.     CorePart core;
  1115.     BoardPart board;
  1116. } BoardRec;
  1117.  
  1118. #endif BoardP_h
  1119.  
  1120. SHAR_EOF
  1121. fi
  1122. if test -f 'DirMgr.c'
  1123. then
  1124.     echo shar: "will not over-write existing file 'DirMgr.c'"
  1125. else
  1126. cat << \SHAR_EOF > 'DirMgr.c'
  1127. /****************************************************************************
  1128.  
  1129.     DirMgr.c
  1130.  
  1131.     This file contains the C code to implement the DirectoryMgr system.
  1132.  
  1133.     This system is intended to manage filtered and sorted directory
  1134.     lists.
  1135.  
  1136.  ****************************************************************************/
  1137.  
  1138. /*
  1139.  * Author:
  1140.  *     Brian Totty
  1141.  *     Department of Computer Science
  1142.  *     University Of Illinois at Urbana-Champaign
  1143.  *    1304 West Springfield Avenue
  1144.  *     Urbana, IL 61801
  1145.  * 
  1146.  *     totty@cs.uiuc.edu
  1147.  *     
  1148.  */ 
  1149.  
  1150. #include "DirMgr.h"
  1151.  
  1152. #ifndef NO_REGEXP
  1153. #include "RegExp.h"
  1154. #endif
  1155.  
  1156. #define    DIR_MGR_FSM_SIZE 1024
  1157.  
  1158. /*---------------------------------------------------------------------------*
  1159.  
  1160.                    S I M P L E    I N T E R F A C E
  1161.  
  1162.  *---------------------------------------------------------------------------*/
  1163.  
  1164. DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern)
  1165. char *path;
  1166. int sort_type;
  1167. char *pattern;
  1168. {
  1169.     DirectoryMgr *dm;
  1170.     PFI f_func,s_func;
  1171.     char *f_data;
  1172.  
  1173.     if (pattern == NULL) pattern = "*";
  1174.     if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
  1175.     {
  1176.         return(NULL);
  1177.     }
  1178.     if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func))
  1179.     {
  1180.         free(f_data);
  1181.         return(NULL);
  1182.     }
  1183.     dm = DirectoryMgrOpen(path,s_func,f_func,f_data,TRUE);
  1184.     return(dm);
  1185. } /* End DirectoryMgrSimpleOpen */
  1186.  
  1187.  
  1188. int DirectoryMgrSimpleRefilter(dm,pattern)
  1189. DirectoryMgr *dm;
  1190. char *pattern;
  1191. {
  1192.     PFI f_func;
  1193.     char *f_data;
  1194.  
  1195.     if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
  1196.     {
  1197.         return(FALSE);
  1198.     }
  1199.     DirectoryMgrRefilter(dm,f_func,f_data,TRUE);
  1200.     return(TRUE);
  1201. } /* End DirectoryMgrSimpleRefilter */
  1202.  
  1203.  
  1204. int DirectoryMgrSimpleResort(dm,sort_type)
  1205. DirectoryMgr *dm;
  1206. int sort_type;
  1207. {
  1208.     PFI c_func;
  1209.  
  1210.     if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func))
  1211.     {
  1212.         return(FALSE);
  1213.     }
  1214.     DirectoryMgrResort(dm,c_func);
  1215.     return(TRUE);
  1216. } /* End DirectoryMgrSimpleResort */
  1217.  
  1218.  
  1219. /*---------------------------------------------------------------------------*
  1220.  
  1221.                     N O R M A L    I N T E R F A C E
  1222.  
  1223.  *---------------------------------------------------------------------------*/
  1224.  
  1225. DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data)
  1226. char *path;
  1227. PFI c_func,f_func;
  1228. char *f_data;
  1229. int free_data;
  1230. {
  1231.     DirectoryMgr *dm;
  1232.  
  1233.     dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr));
  1234.     if (dm == NULL)
  1235.     {
  1236.         if (free_data && f_data) free(f_data);
  1237.         return(NULL);
  1238.     }
  1239.     if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE)
  1240.     {
  1241.         free(dm);
  1242.         if (free_data && f_data) free(f_data);
  1243.         return(NULL);
  1244.     }
  1245.     DirectoryMgrCompFunc(dm) = c_func;
  1246.     DirectoryMgrRefilter(dm,f_func,f_data,free_data);
  1247.     return(dm);
  1248. } /* End DirectoryMgrOpen */
  1249.  
  1250.  
  1251. void DirectoryMgrClose(dm)
  1252. DirectoryMgr *dm;
  1253. {
  1254.     free(DirectoryMgrData(dm));
  1255.     free(DirectoryMgrSortedPtrs(dm));
  1256.     if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
  1257.     {
  1258.         free(DirectoryMgrFilterData(dm));
  1259.     }
  1260.     DirectoryClose(DirectoryMgrDir(dm));
  1261.     free(dm);
  1262. } /* End DirectoryMgrClose */
  1263.  
  1264.  
  1265. int DirectoryMgrRefilter(dm,f_func,f_data,f_free)
  1266. DirectoryMgr *dm;
  1267. PFI f_func;
  1268. char *f_data;
  1269. int f_free;
  1270. {
  1271.     if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
  1272.     {
  1273.         free(DirectoryMgrFilterData(dm));
  1274.     }
  1275.     DirectoryMgrFilterFunc(dm) = f_func;
  1276.     DirectoryMgrFilterData(dm) = f_data;
  1277.     DirectoryMgrFreeFilterData(dm) = f_free;
  1278.     DirectoryMgrRefresh(dm);
  1279. } /* End DirectoryMgrRefilter */
  1280.  
  1281.  
  1282. int DirectoryMgrRefresh(dm)
  1283. DirectoryMgr *dm;
  1284. {
  1285.     int err,data_size,ptrs_size,i;
  1286.     DirEntryCons *head,*tail,*cons;
  1287.     DirEntry *dm_data,**dm_ptrs;
  1288.     PFI f_func;
  1289.     char *f_data;
  1290.  
  1291.     DirectoryMgrTotalCount(dm) = 0;
  1292.     DirectoryMgrFilteredCount(dm) = 0;
  1293.     DirectoryRestart(DirectoryMgrDir(dm));
  1294.     if (DirectoryMgrData(dm)) free(DirectoryMgrData(dm));
  1295.     if (DirectoryMgrSortedPtrs(dm)) free(DirectoryMgrSortedPtrs(dm));
  1296.     head = NULL;
  1297.     f_func = DirectoryMgrFilterFunc(dm);
  1298.     f_data = DirectoryMgrFilterData(dm);
  1299.     while (1)
  1300.     {
  1301.         cons = (DirEntryCons *)malloc(sizeof(DirEntryCons));
  1302.         if (cons == NULL)
  1303.         {
  1304.             fprintf(stderr,
  1305.                 "DirectoryMgrRefresh: Can't Alloc Cons\n");
  1306.             exit(-1);
  1307.         }
  1308.         err = DirectoryReadNextEntry(DirectoryMgrDir(dm),
  1309.                          &(cons->dir_entry));
  1310.         if (err == FALSE)
  1311.         {
  1312.             free(cons);
  1313.             break;
  1314.         }
  1315.         ++ DirectoryMgrTotalCount(dm);
  1316.         if ((f_func == NULL) ||
  1317.             (f_func && f_func(&(cons->dir_entry),f_data)))
  1318.         {
  1319.             cons->next = NULL;
  1320.             if (head == NULL)
  1321.                 head = cons;
  1322.                 else
  1323.                 tail->next = cons;
  1324.             tail = cons;
  1325.             ++ DirectoryMgrFilteredCount(dm);
  1326.         }
  1327.             else            /* Filter Failed */
  1328.         {
  1329.             free(cons);
  1330.         }
  1331.     }
  1332.  
  1333.     data_size = sizeof(DirEntry) * DirectoryMgrFilteredCount(dm);
  1334.     ptrs_size = sizeof(DirEntry *) * DirectoryMgrFilteredCount(dm);
  1335.     dm_data = (DirEntry *)malloc(data_size);
  1336.     dm_ptrs = (DirEntry **)malloc(ptrs_size);
  1337.     if ((dm_data == NULL) || (dm_ptrs == NULL))
  1338.     {
  1339.         fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n");
  1340.         exit(1);
  1341.     }
  1342.     DirectoryMgrData(dm) = dm_data;
  1343.     DirectoryMgrSortedPtrs(dm) = dm_ptrs;
  1344.  
  1345.     for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
  1346.     {
  1347.         DirectoryMgrData(dm)[i] = head->dir_entry;
  1348.         DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]);
  1349.         cons = head->next;
  1350.         free(head);
  1351.         head = cons;
  1352.     }
  1353.  
  1354.     DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm));
  1355.     DirectoryMgrRestart(dm);
  1356.     return(TRUE);
  1357. } /* End DirectoryMgrRefresh */
  1358.  
  1359.  
  1360. void DirectoryMgrResort(dm,c_func)
  1361. DirectoryMgr *dm;
  1362. PFI c_func;
  1363. {
  1364.     DirectoryMgrCompFunc(dm) = c_func;
  1365.     if (c_func != NULL)
  1366.     {
  1367.         qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm),
  1368.               sizeof(DirEntry *),DirectoryMgrCompFunc(dm));
  1369.     }
  1370.     DirectoryMgrRestart(dm);
  1371. } /* End DirectoryMgrResort */
  1372.  
  1373. /*---------------------------------------------------------------------------*
  1374.  
  1375.                   I T E R A T I O N    C O M M A N D S
  1376.  
  1377.  *---------------------------------------------------------------------------*/
  1378.  
  1379. int DirectoryMgrGotoItem(dm,i)
  1380. DirectoryMgr *dm;
  1381. int i;
  1382. {
  1383.     if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE);
  1384.     DirectoryMgrCurrentIndex(dm) = i;
  1385.     return(TRUE);
  1386. } /* End DirectoryMgrGotoItem */
  1387.  
  1388.  
  1389. int DirectoryMgrGotoNamedItem(dm,name)
  1390. DirectoryMgr *dm;
  1391. char *name;
  1392. {
  1393.     int i;
  1394.     DirEntry *entry;
  1395.  
  1396.     for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
  1397.     {
  1398.         entry = DirectoryMgrSortedPtrs(dm)[i];
  1399.         if (strcmp(DirEntryFileName(entry),name) == 0)
  1400.         {
  1401.             DirectoryMgrCurrentIndex(dm) = i;
  1402.             return(TRUE);
  1403.         }
  1404.     }
  1405.     return(FALSE);
  1406. } /* End DirectoryMgrGotoNamedItem */
  1407.  
  1408.  
  1409. void DirectoryMgrRestart(dm)
  1410. DirectoryMgr *dm;
  1411. {
  1412.     DirectoryMgrCurrentIndex(dm) = 0;
  1413. } /* End DirectoryMgrRestart */
  1414.  
  1415.  
  1416. DirEntry *DirectoryMgrCurrentEntry(dm)
  1417. DirectoryMgr *dm;
  1418. {
  1419.     int index;
  1420.  
  1421.     index = DirectoryMgrCurrentIndex(dm);
  1422.     if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL);
  1423.     return(DirectoryMgrSortedPtrs(dm)[index]);
  1424. } /* End DirectoryMgrCurrentEntry */
  1425.  
  1426.  
  1427. DirEntry *DirectoryMgrNextEntry(dm)
  1428. DirectoryMgr *dm;
  1429. {
  1430.     int index;
  1431.  
  1432.     index = DirectoryMgrCurrentIndex(dm);
  1433.     if (index >= DirectoryMgrFilteredCount(dm)) return(NULL);
  1434.     ++ DirectoryMgrCurrentIndex(dm);
  1435.     return(DirectoryMgrSortedPtrs(dm)[index]);
  1436. } /* End DirectoryMgrNextEntry */
  1437.  
  1438.  
  1439. DirEntry *DirectoryMgrPrevEntry(dm)
  1440. DirectoryMgr *dm;
  1441. {
  1442.     int index;
  1443.  
  1444.     index = DirectoryMgrCurrentIndex(dm) - 1;
  1445.     if (index < 0) return(NULL);
  1446.     -- DirectoryMgrCurrentIndex(dm);
  1447.     return(DirectoryMgrSortedPtrs(dm)[index]);
  1448. } /* End DirectoryMgrPrevEntry */
  1449.  
  1450. /*---------------------------------------------------------------------------*
  1451.  
  1452.                    U T I L I T Y    F U N C T I O N S
  1453.  
  1454.  *---------------------------------------------------------------------------*/
  1455.  
  1456. int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr)
  1457. char *pattern;
  1458. PFI *ff_ptr;
  1459. char **fd_ptr;
  1460. {
  1461. #ifndef    NO_REGEXP
  1462.     char regexp[2048];
  1463.  
  1464.     *ff_ptr = DirectoryMgrFilterName;
  1465.     *fd_ptr = (char *)malloc(sizeof(char) * DIR_MGR_FSM_SIZE);
  1466.     if (*fd_ptr == NULL) return(FALSE);
  1467.     RegExpPatternToRegExp(pattern,regexp);
  1468.     RegExpCompile(regexp,*fd_ptr,DIR_MGR_FSM_SIZE);
  1469. #endif
  1470.     return(TRUE);
  1471. } /* End DirectoryMgrSimpleFilterFunc */
  1472.  
  1473.  
  1474. int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr)
  1475. int sort_type;
  1476. PFI *sf_ptr;
  1477. {
  1478.     *sf_ptr = NULL;
  1479.     switch (sort_type)
  1480.     {
  1481.         case DIR_MGR_SORT_NONE:
  1482.         break;
  1483.         case DIR_MGR_SORT_NAME:
  1484.         *sf_ptr = DirectoryMgrCompareName;
  1485.         break;
  1486.         case DIR_MGR_SORT_SIZE_ASCENDING:
  1487.         *sf_ptr = DirectoryMgrCompareSizeAscending;
  1488.         break;
  1489.         case DIR_MGR_SORT_SIZE_DESCENDING:
  1490.         *sf_ptr = DirectoryMgrCompareSizeDescending;
  1491.         break;
  1492.         case DIR_MGR_SORT_NAME_DIRS_FIRST:
  1493.         *sf_ptr = DirectoryMgrCompareNameDirsFirst;
  1494.         break;
  1495.         case DIR_MGR_SORT_ACCESS_ASCENDING:
  1496.         *sf_ptr = DirectoryMgrCompareLastAccessAscending;
  1497.         break;
  1498.         case DIR_MGR_SORT_ACCESS_DESCENDING:
  1499.         *sf_ptr = DirectoryMgrCompareLastAccessDescending;
  1500.         break;
  1501.         default:
  1502.         fprintf(stderr,"Bad sort type %d\n",sort_type);
  1503.         return(FALSE);
  1504.     }
  1505.     return(TRUE);
  1506. } /* End DirectoryMgrSimpleSortingFunc */
  1507.  
  1508. /*---------------------------------------------------------------------------*
  1509.  
  1510.                     S O R T I N G    R O U T I N E S
  1511.  
  1512.  *---------------------------------------------------------------------------*/
  1513.  
  1514. int DirectoryMgrCompareName(e1p,e2p)
  1515. DirEntry **e1p,**e2p;
  1516. {
  1517.     return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
  1518. } /* End DirectoryMgrCompareName */
  1519.  
  1520.  
  1521. int DirectoryMgrCompareNameDirsFirst(e1p,e2p)
  1522. DirEntry **e1p,**e2p;
  1523. {
  1524.     if (DirEntryLeadsToDir(*e1p))
  1525.     {
  1526.         if (!DirEntryLeadsToDir(*e2p)) return(-1);
  1527.     }
  1528.         else if (DirEntryLeadsToDir(*e2p))
  1529.     {
  1530.         return(1);
  1531.     }
  1532.     return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
  1533. } /* End DirectoryMgrCompareNameDirsFirst */
  1534.  
  1535.  
  1536. int DirectoryMgrCompareSizeAscending(e1p,e2p)
  1537. DirEntry **e1p,**e2p;
  1538. {
  1539.     if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p))
  1540.         return (-1);
  1541.         else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
  1542.         return (0);
  1543.         else
  1544.         return (1);
  1545. } /* End DirectoryMgrCompareSizeAscending */
  1546.  
  1547.  
  1548. int DirectoryMgrCompareSizeDescending(e1p,e2p)
  1549. DirEntry **e1p,**e2p;
  1550. {
  1551.     if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p))
  1552.         return (-1);
  1553.         else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
  1554.         return (0);
  1555.         else
  1556.         return (1);
  1557. } /* End DirectoryMgrCompareSizeDescending */
  1558.  
  1559.  
  1560. int DirectoryMgrCompareLastAccessAscending(e1p,e2p)
  1561. DirEntry **e1p,**e2p;
  1562. {
  1563.     return((long)DirEntryLastAccess(*e1p) >
  1564.            (long)DirEntryLastAccess(*e2p));
  1565. } /* End DirectoryMgrCompareLastAccessAscending */
  1566.  
  1567.  
  1568. int DirectoryMgrCompareLastAccessDescending(e1p,e2p)
  1569. DirEntry **e1p,**e2p;
  1570. {
  1571.     return((long)DirEntryLastAccess(*e1p) <
  1572.            (long)DirEntryLastAccess(*e2p));
  1573. } /* End DirectoryMgrCompareLastAccessDescending */
  1574.  
  1575. /*---------------------------------------------------------------------------*
  1576.  
  1577.                      F I L T E R    R O U T I N E S
  1578.  
  1579.  *---------------------------------------------------------------------------*/
  1580.  
  1581. int DirectoryMgrFilterName(de,fsm)
  1582. DirEntry *de;
  1583. char *fsm;
  1584. {
  1585. #ifndef    NO_REGEXP
  1586.     return(RegExpMatch(DirEntryFileName(de),fsm));
  1587. #else
  1588.     return(TRUE);
  1589. #endif
  1590. } /* End DirectoryMgrFilterName */
  1591. SHAR_EOF
  1592. fi
  1593. if test -f 'DirMgr.h'
  1594. then
  1595.     echo shar: "will not over-write existing file 'DirMgr.h'"
  1596. else
  1597. cat << \SHAR_EOF > 'DirMgr.h'
  1598. /****************************************************************************
  1599.  
  1600.     DirMgr.h
  1601.  
  1602.     This file contains the C declarations and definitions for the
  1603.     DirectoryMgr system.
  1604.  
  1605.     This system is intended to managed filtered and sorted directory
  1606.     lists.
  1607.  
  1608.  ****************************************************************************/
  1609.  
  1610. /*
  1611.  * Author:
  1612.  *     Brian Totty
  1613.  *     Department of Computer Science
  1614.  *     University Of Illinois at Urbana-Champaign
  1615.  *    1304 West Springfield Avenue
  1616.  *     Urbana, IL 61801
  1617.  * 
  1618.  *     totty@cs.uiuc.edu
  1619.  *     
  1620.  */ 
  1621.  
  1622. #ifndef _DIRECTORY_MGR_H_
  1623. #define    _DIRECTORY_MGR_H_
  1624.  
  1625. #include "Directory.h"
  1626.  
  1627. /*---------------------------------------------------------------------------*
  1628.  
  1629.         Simple DirectoryMgr Interface
  1630.  
  1631.         DirectoryMgrSimpleOpen();
  1632.         DirectoryMgrSimpleRefilter();
  1633.         DirectoryMgrSimpleResort();
  1634.  
  1635.     Standard DirectoryMgr Interface
  1636.  
  1637.         DirectoryMgrOpen();
  1638.         DirectoryMgrClose();
  1639.         DirectoryMgrRefilter();
  1640.         DirectoryMgrRefresh();
  1641.         DirectoryMgrResort();
  1642.  
  1643.     Moving Around Items
  1644.  
  1645.         DirectoryMgrGotoItem();
  1646.         DirectoryMgrGotoNamedItem();
  1647.         DirectoryMgrRestart();
  1648.         DirectoryMgrGetIndex();
  1649.         DirectoryMgrCurrentEntry();
  1650.         DirectoryMgrNextEntry();
  1651.         DirectoryMgrPrevEntry();
  1652.  
  1653.     Utility Functions
  1654.  
  1655.         DirectoryMgrSimpleFilterFunc();
  1656.         DirectoryMgrSimpleSortingFunc();
  1657.  
  1658.     Comparison Functions
  1659.  
  1660.         DirectoryMgrCompareName();
  1661.         DirectoryMgrCompareSizeAscending();
  1662.         DirectoryMgrCompareSizeDescending();
  1663.  
  1664.     Macros
  1665.  
  1666.         DirectoryMgrDir();
  1667.         DirectoryMgrData();
  1668.         DirectoryMgrSortedPtrs();
  1669.         DirectoryMgrFilterFunc();
  1670.         DirectoryMgrCompFunc();
  1671.         DirectoryMgrFilterData();
  1672.         DirectoryMgrFreeFilterData();
  1673.         DirectoryMgrTotalCount();
  1674.         DirectoryMgrFilteredCount();
  1675.         DirectoryMgrCurrentIndex();
  1676.  
  1677.  
  1678.  *---------------------------------------------------------------------------*/
  1679.  
  1680. #ifndef PFI
  1681. typedef int (*PFI)();
  1682. #endif
  1683.  
  1684. typedef struct entry_cons
  1685. {
  1686.     DIR_ENTRY dir_entry;
  1687.     struct entry_cons *next;
  1688. } DIR_ENTRY_CONS;
  1689.  
  1690. typedef    DIR_ENTRY_CONS DirEntryCons;
  1691.  
  1692. typedef struct
  1693. {
  1694.     DIRECTORY dir;
  1695.     DIR_ENTRY *data;
  1696.     DIR_ENTRY **sorted_ptrs;
  1697.     int total_count;
  1698.     int filtered_count;
  1699.     PFI filter_func;
  1700.     char *filter_data;
  1701.     int free_filter_data;
  1702.     PFI comp_func;
  1703.     int current_index;
  1704. } DIRECTORY_MGR;
  1705.  
  1706. typedef    DIRECTORY_MGR DirectoryMgr;
  1707.  
  1708. #define    DIR_MGR_SORT_NONE            0
  1709. #define    DIR_MGR_SORT_NAME            1
  1710. #define    DIR_MGR_SORT_NAME_DIRS_FIRST        2
  1711. #define DIR_MGR_SORT_SIZE_ASCENDING        3
  1712. #define DIR_MGR_SORT_SIZE_DESCENDING        4
  1713. #define    DIR_MGR_SORT_ACCESS_ASCENDING        5
  1714. #define    DIR_MGR_SORT_ACCESS_DESCENDING        6
  1715.  
  1716. #define    DirectoryMgrDir(dm)        (&((dm)->dir))
  1717. #define    DirectoryMgrData(dm)        ((dm)->data)
  1718. #define    DirectoryMgrSortedPtrs(dm)    ((dm)->sorted_ptrs)
  1719. #define    DirectoryMgrFilterFunc(dm)    ((dm)->filter_func)
  1720. #define    DirectoryMgrCompFunc(dm)    ((dm)->comp_func)
  1721. #define    DirectoryMgrFilterData(dm)    ((dm)->filter_data)
  1722. #define    DirectoryMgrFreeFilterData(dm)    ((dm)->free_filter_data)
  1723. #define    DirectoryMgrTotalCount(dm)    ((dm)->total_count)
  1724. #define    DirectoryMgrFilteredCount(dm)    ((dm)->filtered_count)
  1725. #define    DirectoryMgrCurrentIndex(dm)    ((dm)->current_index)
  1726.  
  1727. #if (!NeedFunctionPrototypes)
  1728.  
  1729. DirectoryMgr *    DirectoryMgrSimpleOpen();
  1730. int        DirectoryMgrSimpleRefilter();
  1731. int        DirectoryMgrSimpleResort();
  1732.  
  1733. DirectoryMgr *    DirectoryMgrOpen();
  1734. void        DirectoryMgrClose();
  1735. int        DirectoryMgrRefilter();
  1736. int        DirectoryMgrRefresh();
  1737. void        DirectoryMgrResort();
  1738.  
  1739. int        DirectoryMgrGotoItem();
  1740. int        DirectoryMgrGotoNamedItem();
  1741. void        DirectoryMgrRestart();
  1742. int        DirectoryMgrGetIndex();
  1743. DirEntry *    DirectoryMgrCurrentEntry();
  1744. DirEntry *    DirectoryMgrNextEntry();
  1745. DirEntry *    DirectoryMgrPrevEntry();
  1746.  
  1747. int        DirectoryMgrSimpleFilterFunc();
  1748. int        DirectoryMgrSimpleSortingFunc();
  1749.  
  1750. int        DirectoryMgrCompareName();
  1751. int        DirectoryMgrCompareNameDirsFirst();
  1752. int        DirectoryMgrCompareSizeAscending();
  1753. int        DirectoryMgrCompareSizeDescending();
  1754. int        DirectoryMgrCompareLastAccessAscending();
  1755. int        DirectoryMgrCompareLastAccessDescending();
  1756.  
  1757. int        DirectoryMgrFilterName();
  1758.  
  1759. #else
  1760.  
  1761. DirectoryMgr *    DirectoryMgrSimpleOpen(char *path, int sort_type,
  1762.             char *pattern);
  1763. int        DirectoryMgrSimpleRefilter(DirectoryMgr *dm, char *pattern);
  1764. int        DirectoryMgrSimpleResort(DirectoryMgr *dm, int sort_type);
  1765.  
  1766. DirectoryMgr *    DirectoryMgrOpen(char *path, PFI c_func, PFI f_func,
  1767.             char *f_data, int free_data);
  1768. void        DirectoryMgrClose(DirectoryMgr *dm);
  1769. int        DirectoryMgrRefilter(DirectoryMgr *dm, PFI f_func,
  1770.             char *f_data, int f_free);
  1771. int        DirectoryMgrRefresh(DirectoryMgr *dm);
  1772. void        DirectoryMgrResort(DirectoryMgr *dm, PFI c_func);
  1773.  
  1774. int        DirectoryMgrGotoItem(DirectoryMgr *dm, int i);
  1775. int        DirectoryMgrGotoNamedItem(DirectoryMgr *dm, char *name);
  1776. void        DirectoryMgrRestart(DirectoryMgr *dm);
  1777. DirEntry *    DirectoryMgrCurrentEntry(DirectoryMgr *dm);
  1778. DirEntry *    DirectoryMgrNextEntry(DirectoryMgr *dm);
  1779. DirEntry *    DirectoryMgrPrevEntry(DirectoryMgr *dm);
  1780.  
  1781. int        DirectoryMgrSimpleFilterFunc(char *pattern, PFI *ff_ptr,
  1782.             char **fd_ptr);
  1783. int        DirectoryMgrSimpleSortingFunc(int sort_type, PFI *sf_ptr);
  1784.  
  1785. int        DirectoryMgrCompareName(DirEntry **e1p, DirEntry **e2p);
  1786. int        DirectoryMgrCompareNameDirsFirst(DirEntry **e1p,
  1787.             DirEntry **e2p);
  1788. int        DirectoryMgrCompareSizeAscending(DirEntry **e1p,
  1789.             DirEntry **e2p);
  1790. int        DirectoryMgrCompareSizeDescending(DirEntry **e1p,
  1791.             DirEntry **e2p);
  1792. int        DirectoryMgrCompareLastAccessAscending(DirEntry **e1p,
  1793.             DirEntry **e2p);
  1794. int        DirectoryMgrCompareLastAccessDescending(DirEntry **e1p,
  1795.             DirEntry **e2p);
  1796.  
  1797. int        DirectoryMgrFilterName(DirEntry *de, char *fsm);
  1798.  
  1799. #endif
  1800.  
  1801. #endif
  1802. SHAR_EOF
  1803. fi
  1804. if test -f 'Directory.c'
  1805. then
  1806.     echo shar: "will not over-write existing file 'Directory.c'"
  1807. else
  1808. cat << \SHAR_EOF > 'Directory.c'
  1809. /****************************************************************************
  1810.  
  1811.         Directory.c
  1812.  
  1813.     This file contains the C code that implements the directory
  1814.     iteration and file information subsystem.
  1815.  
  1816.     This code is intended to be used as a convenient, machine
  1817.     independent interface to iterate through the contents of a
  1818.     directory.
  1819.  
  1820.  ****************************************************************************/
  1821.  
  1822. /*
  1823.  * Author:
  1824.  *     Brian Totty
  1825.  *     Department of Computer Science
  1826.  *     University Of Illinois at Urbana-Champaign
  1827.  *    1304 West Springfield Avenue
  1828.  *     Urbana, IL 61801
  1829.  * 
  1830.  *     totty@cs.uiuc.edu
  1831.  *     
  1832.  */ 
  1833.  
  1834. #include "Directory.h"
  1835. #include "RegExp.h"
  1836.  
  1837. /*--------------------------------------------------------------------------*
  1838.  
  1839.         L O W    L E V E L    D I R E C T O R Y    I N T E R F A C E
  1840.  
  1841.  *--------------------------------------------------------------------------*/
  1842.  
  1843. int DirectoryOpen(dir_name,dp)
  1844. char *dir_name;
  1845. Directory *dp;
  1846. {
  1847.     DirectoryDir(dp) = opendir(dir_name);
  1848.     if (DirectoryDir(dp) == NULL) return(FALSE);
  1849.     if (DirectoryPathExpand(dir_name,DirectoryPath(dp)) == NULL)
  1850.     {
  1851.         closedir(DirectoryDir(dp));
  1852.         return(FALSE);
  1853.     }
  1854.     return(TRUE);
  1855. } /* End DirectoryOpen */
  1856.  
  1857.  
  1858. void DirectoryRestart(dp)
  1859. Directory *dp;
  1860. {
  1861.     rewinddir(DirectoryDir(dp));
  1862. } /* End DirectoryRestart */
  1863.  
  1864.  
  1865. void DirectoryClose(dp)
  1866. Directory *dp;
  1867. {
  1868.     closedir(DirectoryDir(dp));
  1869. } /* End DirectoryClose */
  1870.  
  1871.  
  1872. long DirectoryTellPosition(dp)
  1873. Directory *dp;
  1874. {
  1875.     return(telldir(DirectoryDir(dp)));
  1876. } /* End DirectoryTellPosition */
  1877.  
  1878.  
  1879. void DirectorySetPosition(dp,pos)
  1880. Directory *dp;
  1881. long pos;
  1882. {
  1883.     seekdir(dp,pos);
  1884. } /* End DirectorySetPosition */
  1885.  
  1886.  
  1887. int DirectoryReadNextEntry(dp,de)
  1888. Directory *dp;
  1889. DirEntry *de;
  1890. {
  1891.     u_short orig_file_type;
  1892.     static struct dirent *_ep;
  1893.     static struct stat _lstats,_stats;
  1894.     char full_path[MAXPATHLEN + 2];
  1895.  
  1896.     _ep = readdir(DirectoryDir(dp));
  1897.     if (_ep == NULL) return(FALSE);
  1898.     strcpy(DirEntryFileName(de),_ep->d_name);
  1899.     strcpy(full_path,DirectoryPath(dp));
  1900.     strcat(full_path,DirEntryFileName(de));
  1901.  
  1902.     if (lstat(full_path,&_lstats) != 0) return(FALSE);
  1903.  
  1904.     orig_file_type = _lstats.st_mode & S_IFMT;
  1905.     switch (orig_file_type)
  1906.     {
  1907.         case S_IFDIR:
  1908.         DirEntryType(de) = F_TYPE_DIR;
  1909.         break;
  1910.         case S_IFREG:
  1911.         DirEntryType(de) = F_TYPE_FILE;
  1912.         break;
  1913.         case S_IFCHR:
  1914.         DirEntryType(de) = F_TYPE_CHAR_SPECIAL;
  1915.         break;
  1916.         case S_IFBLK:
  1917.         DirEntryType(de) = F_TYPE_BLOCK_SPECIAL;
  1918.         break;
  1919.         case S_IFLNK:
  1920.         DirEntryType(de) = F_TYPE_SYM_LINK;
  1921.         break;
  1922.         case S_IFSOCK:
  1923.         DirEntryType(de) = F_TYPE_SOCKET;
  1924.         break;
  1925. #ifdef S_IFIFO
  1926.         case S_IFIFO:
  1927.         DirEntryType(de) = F_TYPE_FIFO;
  1928.         break;
  1929. #endif
  1930.         default:
  1931.         DirEntryType(de) = orig_file_type;
  1932.         break;
  1933.     }
  1934.  
  1935.     DirEntryIsBrokenLink(de) = FALSE;
  1936.     DirEntryIsDirectoryLink(de) = FALSE;
  1937.     if (DirEntryIsSymLink(de))            /* Symbolic Link */
  1938.     {
  1939.         if (stat(full_path,&_stats) != 0)    /* Can't Stat File */
  1940.         {
  1941.             DirEntryIsBrokenLink(de) = TRUE;
  1942.             _stats = _lstats;
  1943.         }
  1944.             else                /* Link Not Broken */
  1945.         {
  1946. #ifdef SLOW_DIRLINK_TEST
  1947.             char temp_path[MAXPATHLEN + 2];
  1948.  
  1949.             if (DirectoryPathExpand(full_path,temp_path) != NULL)
  1950.             {
  1951. #else
  1952.             if ((_stats.st_mode & S_IFMT) == S_IFDIR)
  1953.             {
  1954. #endif
  1955.                 DirEntryIsDirectoryLink(de) = TRUE;
  1956.             }
  1957.  
  1958.         }
  1959.     }
  1960.         else                    /* Not Symbolic Link */
  1961.     {
  1962.         _stats = _lstats;
  1963.     }
  1964.  
  1965.     FileInfoOrigMode(DirEntrySelfInfo(de)) = _lstats.st_mode;
  1966.     FileInfoProt(DirEntrySelfInfo(de)) = _lstats.st_mode & 0777;
  1967.     FileInfoUserID(DirEntrySelfInfo(de)) = _lstats.st_uid;
  1968.     FileInfoGroupID(DirEntrySelfInfo(de)) = _lstats.st_gid;
  1969.     FileInfoFileSize(DirEntrySelfInfo(de)) = _lstats.st_size;
  1970.     FileInfoLastAccess(DirEntrySelfInfo(de)) = _lstats.st_atime;
  1971.     FileInfoLastModify(DirEntrySelfInfo(de)) = _lstats.st_mtime;
  1972.     FileInfoLastStatusChange(DirEntrySelfInfo(de)) = _lstats.st_ctime;
  1973.  
  1974.     FileInfoOrigMode(DirEntryActualInfo(de)) = _stats.st_mode;
  1975.     FileInfoProt(DirEntryActualInfo(de)) = _stats.st_mode & 0777;
  1976.     FileInfoUserID(DirEntryActualInfo(de)) = _stats.st_uid;
  1977.     FileInfoGroupID(DirEntryActualInfo(de)) = _stats.st_gid;
  1978.     FileInfoFileSize(DirEntryActualInfo(de)) = _stats.st_size;
  1979.     FileInfoLastAccess(DirEntryActualInfo(de)) = _stats.st_atime;
  1980.     FileInfoLastModify(DirEntryActualInfo(de)) = _stats.st_mtime;
  1981.     FileInfoLastStatusChange(DirEntryActualInfo(de)) = _stats.st_ctime;
  1982.  
  1983.     return(TRUE);
  1984. } /* End DirectoryReadNextEntry */
  1985.  
  1986.  
  1987. char *DirectoryPathExpand(old_path,new_path)
  1988. char *old_path,*new_path;
  1989. {
  1990.     register char *p;
  1991.     char path[MAXPATHLEN + 2];
  1992.  
  1993.     if (getwd(path) == NULL) return(NULL);
  1994.     if (chdir(old_path) != 0) return(NULL);
  1995.     if (getwd(new_path) == NULL) strcpy(new_path,old_path);
  1996.     if (chdir(path) != 0) return(NULL);
  1997.     for (p = new_path; *p != '\0'; p++);
  1998.     if ((p != new_path) && *(p - 1) != '/')
  1999.     {
  2000.         *p++ = '/';
  2001.         *p = '\0';
  2002.     }
  2003.     return(new_path);
  2004. } /* End DirectoryPathExpand */
  2005.  
  2006.  
  2007. /*---------------------------------------------------------------------------*
  2008.  
  2009.              D I R E C T O R Y    E N T R Y    R O U T I N E S
  2010.  
  2011.  *---------------------------------------------------------------------------*/
  2012.  
  2013. void DirEntryDump(fp,de)
  2014. FILE *fp;
  2015. DirEntry *de;
  2016. {
  2017.     fprintf(fp,"%20s, Size %7d, Prot %3o\n",
  2018.         DirEntryFileName(de),DirEntryFileSize(de),DirEntryProt(de));
  2019. } /* End DirEntryDump */
  2020. SHAR_EOF
  2021. fi
  2022. if test -f 'Directory.h'
  2023. then
  2024.     echo shar: "will not over-write existing file 'Directory.h'"
  2025. else
  2026. cat << \SHAR_EOF > 'Directory.h'
  2027. /****************************************************************************
  2028.  
  2029.     Directory.h
  2030.  
  2031.     This file contains the C definitions and declarations for the
  2032.     Directory.c directory iteration code.
  2033.  
  2034.     This code is intended to be used as a convenient, machine
  2035.     independent interface to iterate through the contents of a
  2036.     directory.
  2037.  
  2038.  ****************************************************************************/
  2039.  
  2040. /*
  2041.  * Author:
  2042.  *     Brian Totty
  2043.  *     Department of Computer Science
  2044.  *     University Of Illinois at Urbana-Champaign
  2045.  *    1304 West Springfield Avenue
  2046.  *     Urbana, IL 61801
  2047.  * 
  2048.  *     totty@cs.uiuc.edu
  2049.  *     
  2050.  */ 
  2051.  
  2052. #ifndef _DIRECTORY_H_
  2053. #define _DIRECTORY_H_
  2054.  
  2055. #include <stdio.h>
  2056. #include <string.h>
  2057. #include <sys/param.h>
  2058. #include <sys/types.h>
  2059. #include <sys/stat.h>
  2060.  
  2061. #ifdef SYSV
  2062. #define getwd(path) getcwd(path, MAXPATHLEN)
  2063. #endif
  2064.  
  2065. #ifndef    NO_DIRENT
  2066. #include <dirent.h>
  2067. #else
  2068. #include <sys/dir.h>
  2069. #define    dirent direct
  2070. #endif
  2071.  
  2072. #ifndef _SYS_NAME_MAX
  2073. #ifndef MAXNAMLEN
  2074. ERROR, ONE OF THESE MUST BE DEFINED
  2075. #else
  2076. #define    MAX_NAME_LENGTH    MAXNAMLEN
  2077. #endif
  2078. #else
  2079. #define    MAX_NAME_LENGTH    _SYS_NAME_MAX
  2080. #endif
  2081.  
  2082. #ifndef TRUE
  2083. #define TRUE                1
  2084. #endif
  2085.  
  2086. #ifndef FALSE
  2087. #define    FALSE                0
  2088. #endif
  2089.  
  2090. #define    PERM_READ            4
  2091. #define    PERM_WRITE            2    
  2092. #define    PERM_EXECUTE            1
  2093.  
  2094. #define    F_TYPE_DIR            1
  2095. #define    F_TYPE_FILE            2
  2096. #define    F_TYPE_CHAR_SPECIAL        3
  2097. #define    F_TYPE_BLOCK_SPECIAL        4
  2098. #define    F_TYPE_SYM_LINK            5
  2099. #define    F_TYPE_SOCKET            6
  2100. #define    F_TYPE_FIFO            7
  2101.  
  2102. /*--------------------------------------------------------------------------*
  2103.  
  2104.             D A T A    T Y P E    A C C E S S    M A C R O S
  2105.  
  2106.  *--------------------------------------------------------------------------*/
  2107.  
  2108.     /* Directory: Directory Iterator */
  2109.  
  2110. #define    DirectoryDir(dp)        ((dp)->filep)
  2111. #define    DirectoryPath(dp)        ((dp)->path)
  2112.  
  2113.     /* FileInfo: Information About A File Or Link */
  2114.  
  2115. #define    FileInfoProt(fi)        ((fi)->protections)
  2116. #define FileInfoOrigMode(fi)        ((fi)->orig_mode)
  2117. #define    FileInfoUserID(fi)        ((fi)->user_id)
  2118. #define    FileInfoGroupID(fi)        ((fi)->group_id)
  2119. #define    FileInfoFileSize(fi)        ((fi)->size)
  2120. #define    FileInfoLastAccess(fi)        ((fi)->last_access)
  2121. #define    FileInfoLastModify(fi)        ((fi)->last_modify)
  2122. #define    FileInfoLastStatusChange(fi)    ((fi)->last_status_change)
  2123.  
  2124. #define    FIProt(fi)            FileInfoProt(fi)
  2125. #define FIOrigMode(fi)            FileInfoOrigMode(fi)
  2126. #define    FIUserID(fi)            FileInfoUserID(fi)
  2127. #define    FIGroupID(fi)            FileInfoGroupID(fi)
  2128. #define    FIFileSize(fi)            FileInfoFileSize(fi)
  2129. #define    FILastAccess(fi)        FileInfoLastAccess(fi)
  2130. #define    FILastModify(fi)        FileInfoLastModify(fi)
  2131. #define    FILastStatusChange(fi)        FileInfoLastStatusChange(fi)
  2132.  
  2133.     /* FType: File Type Macros */
  2134.  
  2135. #define    FTypeIsDir(ft)            ((ft) == F_TYPE_DIR)
  2136. #define    FTypeIsFile(ft)            ((ft) == F_TYPE_FILE)
  2137. #define    FTypeIsCharSpecial(ft)        ((ft) == F_TYPE_CHAR_SPECIAL)
  2138. #define    FTypeIsBlockSpecial(ft)        ((ft) == F_TYPE_BLOCK_SPECIAL)
  2139. #define    FTypeIsSymLink(ft)        ((ft) == F_TYPE_SYM_LINK)
  2140. #define    FTypeIsSocket(ft)        ((ft) == F_TYPE_SOCKET)
  2141. #define    FTypeIsFifo(ft)            ((ft) == F_TYPE_FIFO)
  2142.  
  2143.     /* DirEntry: Information About A Item In A Directory */
  2144.  
  2145. #define    DirEntryFileName(fi)        ((fi)->filename)
  2146. #define    DirEntryType(fi)        ((fi)->file_type)
  2147. #define    DirEntrySelfInfo(fi)        (&((fi)->self_info))
  2148. #define    DirEntryActualInfo(fi)        (&((fi)->actual_info))
  2149.  
  2150. #define    DirEntryIsBrokenLink(fi)    ((fi)->broken_link)
  2151. #define    DirEntryIsDirectoryLink(fi)    ((fi)->directory_link)
  2152. #define    DirEntryIsDir(fi)        (FTypeIsDir(DirEntryType(fi)))
  2153. #define    DirEntryIsFile(fi)        (FTypeIsFile(DirEntryType(fi)))
  2154. #define    DirEntryIsCharSpecial(fi)    (FTypeIsCharSpecial(DirEntryType(fi)))
  2155. #define    DirEntryIsBlockSpecial(fi)    (FTypeIsBlockSpecial(DirEntryType(fi)))
  2156. #define    DirEntryIsSymLink(fi)        (FTypeIsSymLink(DirEntryType(fi)))
  2157. #define    DirEntryIsSocket(fi)        (FTypeIsSocket(DirEntryType(fi)))
  2158. #define    DirEntryIsFifo(fi)        (FTypeIsFifo(DirEntryType(fi)))
  2159. #define    DirEntryLeadsToDir(fi)        (DirEntryIsDir(fi) ||        \
  2160.                      DirEntryIsDirectoryLink(fi))
  2161.  
  2162. #define    DirEntryProt(d)            FIProt(DirEntrySelfInfo(d))
  2163. #define DirEntryOrigMode(d)        FIOrigMode(DirEntrySelfInfo(d))
  2164. #define    DirEntryUserID(d)        FIUserID(DirEntrySelfInfo(d))
  2165. #define    DirEntryGroupID(d)        FIGroupID(DirEntrySelfInfo(d))
  2166. #define    DirEntryFileSize(d)        FIFileSize(DirEntrySelfInfo(d))
  2167. #define    DirEntryLastAccess(d)        FILastAccess(DirEntrySelfInfo(d))
  2168. #define    DirEntryLastModify(d)        FILastModify(DirEntrySelfInfo(d))
  2169. #define    DirEntryLastStatusChange(d)    FILastStatusChange(DirEntrySelfInfo(d))
  2170.  
  2171. /*--------------------------------------------------------------------------*
  2172.  
  2173.              D A T A    T Y P E    D E F I N I T I O N S
  2174.  
  2175.  *--------------------------------------------------------------------------*/
  2176.  
  2177.     /* Directory: Directory Iterator */
  2178.  
  2179. typedef struct
  2180. {
  2181.     DIR *filep;
  2182.     char path[MAXPATHLEN + 2];
  2183. } DIRECTORY;
  2184.  
  2185. typedef DIRECTORY Directory;
  2186.  
  2187.     /* FileInfo: Information About A File Or Link */
  2188.  
  2189. typedef struct
  2190. {
  2191.     short protections;
  2192.     short orig_mode;
  2193.     short user_id;
  2194.     short group_id;
  2195.     long size;
  2196.     time_t last_access;
  2197.     time_t last_modify;
  2198.     time_t last_status_change;
  2199. } FILE_INFO;
  2200.  
  2201. typedef    FILE_INFO FileInfo;
  2202.  
  2203.     /* DirEntry: Information About A Item In A Directory */
  2204.  
  2205. typedef struct
  2206. {
  2207.     char filename[MAX_NAME_LENGTH + 1];
  2208.     short file_type;
  2209.     short broken_link;
  2210.     short directory_link;
  2211.     FileInfo self_info;
  2212.     FileInfo actual_info;
  2213. } DIR_ENTRY;
  2214.  
  2215. typedef DIR_ENTRY DirEntry;
  2216.  
  2217. /*--------------------------------------------------------------------------*
  2218.  
  2219.         L O W    L E V E L    D I R E C T O R Y    I N T E R F A C E
  2220.  
  2221.  *--------------------------------------------------------------------------*/
  2222.  
  2223. #if (!NeedFunctionPrototypes)
  2224.  
  2225. int    DirectoryOpen();
  2226. void    DirectoryRestart();
  2227. void    DirectoryClose();
  2228. long    DirectoryTellPosition();
  2229. void    DirectorySetPosition();
  2230. int    DirectoryReadNextEntry();
  2231. char *    DirectoryPathExpand();
  2232. void    DirEntryDump();
  2233.  
  2234. #else
  2235.  
  2236. int    DirectoryOpen(char *dir_name, Directory *dp);
  2237. void    DirectoryRestart(Directory *dp);
  2238. void    DirectoryClose(Directory *dp);
  2239. long    DirectoryTellPosition(Directory *dp);
  2240. void    DirectorySetPosition(Directory *dp, long int pos);
  2241. int    DirectoryReadNextEntry(Directory *dp, DirEntry *de);
  2242. char *    DirectoryPathExpand(char *old_path, char *new_path);
  2243. void    DirEntryDump(FILE *fp, DirEntry *de);
  2244.  
  2245. #endif
  2246.  
  2247. #endif
  2248.  
  2249.  
  2250. SHAR_EOF
  2251. fi
  2252. if test -f 'FileSel.c'
  2253. then
  2254.     echo shar: "will not over-write existing file 'FileSel.c'"
  2255. else
  2256. cat << \SHAR_EOF > 'FileSel.c'
  2257. /*****************************************************************************
  2258.  
  2259.     FileSelector.c
  2260.  
  2261.     This file contains the C code for the FileSelector widget, which
  2262.     is intended to be used as a hierarchical Unix file selector box.
  2263.  
  2264. ******************************************************************************/
  2265.  
  2266. /*
  2267.  * Author:
  2268.  *     Brian Totty
  2269.  *     Department of Computer Science
  2270.  *     University Of Illinois at Urbana-Champaign
  2271.  *    1304 West Springfield Avenue
  2272.  *     Urbana, IL 61801
  2273.  * 
  2274.  *     totty@cs.uiuc.edu
  2275.  *     
  2276.  */ 
  2277.  
  2278. #include <stdio.h>
  2279. #include <X11/Xos.h>
  2280. #include <X11/Xlib.h>
  2281. #include <X11/StringDefs.h>
  2282. #include <X11/IntrinsicP.h>
  2283. #include <X11/Intrinsic.h>
  2284. #include <X11/CompositeP.h>
  2285. #include <X11/Composite.h>
  2286. #include <X11/cursorfont.h>
  2287. #include <X11/Xaw/SimpleP.h>
  2288. #include <X11/Xaw/Simple.h>
  2289. #include <X11/Xaw/LabelP.h>
  2290. #include <X11/Xaw/Label.h>
  2291. #include <X11/Xaw/CommandP.h>
  2292. #include <X11/Xaw/Command.h>
  2293. #include <X11/Xaw/AsciiTextP.h>
  2294. #include <X11/Xaw/AsciiText.h>
  2295. #include <X11/Xaw/FormP.h>
  2296. #include <X11/Xaw/Form.h>
  2297.  
  2298. #include "ScrListP.h"
  2299. #include "ScrList.h"
  2300. #include "FileSelP.h"
  2301. #include "FileSel.h"
  2302.  
  2303. #ifdef X11R3
  2304. #define asciiTextWidgetClass    asciiStringWidgetClass
  2305. #define    XawtextEdit        XttextEdit
  2306. #define    XtNtype            "type"
  2307. #define    XawAsciiString        NULL
  2308. #define    XtNautoFill        "autoFill"
  2309. typedef    char *            XtPointer;
  2310. #endif
  2311.  
  2312. #define    NO_BUSY_GRAB
  2313.  
  2314. /*---------------------------------------------------------------------------*
  2315.  
  2316.                        D E C L A R A T I O N S
  2317.  
  2318.  *---------------------------------------------------------------------------*/
  2319.  
  2320. #define    SUPERCLASS        (&compositeClassRec)
  2321.  
  2322. #ifndef abs
  2323. #define abs(a)            ((a) < 0 ? -(a) : (a))
  2324. #endif
  2325.  
  2326. #define max(a,b)        ((a) > (b) ? (a) : (b))
  2327. #define min(a,b)        ((a) < (b) ? (a) : (b))
  2328. #define XtStrlen(s)        ((s) ? strlen(s) : 0)
  2329.  
  2330. #define    StrCopy(s)        ((char*)strcpy((char *)malloc((strlen(s)+1) * \
  2331.                     sizeof(char)),((char *)(s))))
  2332.  
  2333. #define FSFieldOffset(field)    XtOffset(XfwfFileSelectorWidget,    \
  2334.                      fileSelector.field)
  2335. #define CoreFieldOffset(field)    XtOffset(Widget,core.field)
  2336.  
  2337. /*---------------------------------------------------------------------------*
  2338.  
  2339.                    I N T E R N A L    R O U T I N E S
  2340.  
  2341.  *---------------------------------------------------------------------------*/
  2342.  
  2343. #if (!NeedFunctionPrototypes)
  2344.  
  2345. static void        Initialize();
  2346. static void        Realize();
  2347. static void        Destroy();
  2348. static void        Resize();
  2349. static Boolean        SetValues();
  2350. static XtGeometryResult    GeometryManager();
  2351. static void        ChildrenCreate();
  2352. static void        ChildrenRealize();
  2353. static void        ChildrenRecalculate();
  2354. static void        ChildrenUpdate();
  2355. static void        ButtonUp();
  2356. static void        ButtonOk();
  2357. static void        ButtonCancel();
  2358. static void        ButtonGoto();
  2359. static void        ButtonSelect();
  2360. static char *        GetFileBoxText();
  2361. static void        ClickOnPathList();
  2362. static void        ClickOnFileList();
  2363. static void        SelectFileByIndex();
  2364. static Boolean        SelectFileByName();
  2365. static void        UnselectAll();
  2366. static void        NotifySelectionChange();
  2367. static void        GotoDeepestLegalDirectory();
  2368. static void        UpdateLists();
  2369. static void        UpdateTextLines();
  2370. static void        Chdir();
  2371. static void        DoBusyCursor();
  2372. static void        UndoBusyCursor();
  2373. static void        TextWidgetSetText();
  2374.  
  2375. #else
  2376.  
  2377. static void        Initialize(Widget request, Widget new);
  2378. static void        Realize(Widget gw, XtValueMask *valueMask,
  2379.                 XSetWindowAttributes *attrs);
  2380. static void        Destroy(XfwfFileSelectorWidget fsw);
  2381. static void        Resize(Widget gw);
  2382. static Boolean        SetValues(Widget gcurrent, Widget grequest,
  2383.                 Widget gnew);
  2384. static XtGeometryResult    GeometryManager(Widget w,
  2385.                 XtWidgetGeometry *request,
  2386.                 XtWidgetGeometry *reply);
  2387. static void        ChildrenCreate(XfwfFileSelectorWidget fsw);
  2388. static void        ChildrenRealize(XfwfFileSelectorWidget fsw);
  2389. static void        ChildrenRecalculate(XfwfFileSelectorWidget fsw);
  2390. static void        ChildrenUpdate(XfwfFileSelectorWidget fsw);
  2391. static void        ButtonUp(Widget w, XfwfFileSelectorWidget fsw,
  2392.                 XtPointer call_data);
  2393. static void        ButtonOk(Widget w, XfwfFileSelectorWidget fsw,
  2394.                 XtPointer call_data);
  2395. static void        ButtonCancel(Widget w, XfwfFileSelectorWidget fsw,
  2396.                 XtPointer call_data);
  2397. static void        ButtonGoto(Widget w, XfwfFileSelectorWidget fsw,
  2398.                 XtPointer call_data);
  2399. static void        ButtonSelect(Widget w, XfwfFileSelectorWidget fsw,
  2400.                 XtPointer call_data);
  2401. static char *        GetFileBoxText(XfwfFileSelectorWidget fsw);
  2402. static void        ClickOnPathList(Widget w, XfwfFileSelectorWidget fsw,
  2403.                 XtPointer call_data);
  2404. static void        ClickOnFileList(Widget w, XfwfFileSelectorWidget fsw,
  2405.                 XtPointer call_data);
  2406. static void        SelectFileByIndex(XfwfFileSelectorWidget fsw,
  2407.                 int strchr);
  2408. static Boolean        SelectFileByName(XfwfFileSelectorWidget fsw,
  2409.                 char *name);
  2410. static void        UnselectAll(XfwfFileSelectorWidget fsw);
  2411. static void        NotifySelectionChange(XfwfFileSelectorWidget fsw);
  2412. static void        GotoDeepestLegalDirectory(XfwfFileSelectorWidget fsw);
  2413. static void        UpdateLists(XfwfFileSelectorWidget fsw);
  2414. static void        UpdateTextLines(XfwfFileSelectorWidget fsw);
  2415. static void        Chdir(XfwfFileSelectorWidget fsw);
  2416. static void        DoBusyCursor(Widget w);
  2417. static void        UndoBusyCursor(Widget w);
  2418. static void        TextWidgetSetText(Widget tw, char *text);
  2419.  
  2420. #endif
  2421.  
  2422. /*---------------------------------------------------------------------------*
  2423.  
  2424.               R E S O U R C E    I N I T I A L I Z A T I O N
  2425.  
  2426.  *---------------------------------------------------------------------------*/
  2427.  
  2428. static XtResource resources[] =
  2429. {
  2430.     {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  2431.         CoreFieldOffset(width), XtRString, "500"},
  2432.     {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  2433.         CoreFieldOffset(height), XtRString, "250"},
  2434.     {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  2435.         CoreFieldOffset(background_pixel), XtRString, "white"},
  2436.  
  2437.     {XtNokButtonCallback, XtCCallback, XtRCallback,
  2438.         sizeof(XtCallbackList), FSFieldOffset(ok_button_callbacks),
  2439.         XtRCallback, NULL},
  2440.     {XtNcancelButtonCallback, XtCCallback, XtRCallback,
  2441.         sizeof(XtCallbackList), FSFieldOffset(cancel_button_callbacks),
  2442.         XtRCallback, NULL},
  2443.     {XtNselectionChangeCallback, XtCCallback, XtRCallback,
  2444.         sizeof(XtCallbackList), FSFieldOffset(sel_change_callbacks),
  2445.         XtRCallback, NULL},
  2446.  
  2447.     {XtNshowOkButton, XtCBoolean, XtRBoolean, sizeof(Boolean),
  2448.         FSFieldOffset(show_ok_button), XtRString, "True"},
  2449.     {XtNshowCancelButton, XtCBoolean, XtRBoolean, sizeof(Boolean),
  2450.         FSFieldOffset(show_cancel_button), XtRString, "True"},
  2451.     {XtNflagLinks, XtCBoolean, XtRBoolean, sizeof(Boolean),
  2452.         FSFieldOffset(flag_links), XtRString, "False"},
  2453.     {XtNcheckExistence, XtCBoolean, XtRBoolean, sizeof(Boolean),
  2454.         FSFieldOffset(check_existence), XtRString, "True"},
  2455.  
  2456.     {XtNfileSelected, XtCBoolean, XtRBoolean, sizeof(Boolean),
  2457.         FSFieldOffset(file_selected), XtRString, "False"},
  2458.  
  2459.     {XtNcurrentDirectory, XtCPathname, XtRString, sizeof(String),
  2460.         FSFieldOffset(current_directory), XtRString, NULL},
  2461.     {XtNcurrentFile, XtCFilename, XtRString, sizeof(String),
  2462.         FSFieldOffset(current_file), XtRString, NULL},
  2463.     {XtNtitle, XtCLabel, XtRString, sizeof(String),
  2464.         FSFieldOffset(title), XtRString, "File Selector"},
  2465.     {XtNsortMode, XtCValue, XtRInt, sizeof(int),
  2466.         FSFieldOffset(sort_mode), XtRString, "2"},
  2467.     {XtNpattern, XtCFile, XtRString, sizeof(String),
  2468.         FSFieldOffset(pattern), XtRString, NULL},
  2469. };
  2470.  
  2471. #undef FSFieldOffset
  2472. #undef CoreFieldOffset
  2473.  
  2474. /*---------------------------------------------------------------------------*
  2475.  
  2476.                     C L A S S    A L L O C A T I O N
  2477.  
  2478.  *---------------------------------------------------------------------------*/
  2479.  
  2480. XfwfFileSelectorClassRec xfwfFileSelectorClassRec =
  2481. {
  2482.     {
  2483.         /* superclass        */    (WidgetClass)SUPERCLASS,
  2484.         /* class_name        */    "XfwfFileSelector",
  2485.         /* widget_size        */    sizeof(XfwfFileSelectorRec),
  2486.         /* class_initialize    */    NULL,
  2487.         /* class_part_initialize*/    NULL,
  2488.         /* class_inited        */    FALSE,
  2489.         /* initialize        */    (XtInitProc)Initialize,
  2490.         /* initialize_hook    */    NULL,
  2491.         /* realize        */    (XtRealizeProc)Realize,
  2492.         /* actions        */    NULL,
  2493.         /* num_actions        */    0,
  2494.         /* resources        */    resources,
  2495.         /* resource_count    */    XtNumber(resources),
  2496.         /* xrm_class        */    NULLQUARK,
  2497.         /* compress_motion    */    TRUE,
  2498.         /* compress_exposure    */    TRUE,
  2499.         /* compress_enterleave    */    TRUE,
  2500.         /* visible_interest    */    FALSE,
  2501.         /* destroy        */    (XtWidgetProc)Destroy,
  2502.         /* resize        */    (XtWidgetProc)Resize,
  2503.         /* expose        */    XtInheritExpose,
  2504.         /* set_values        */    (XtSetValuesFunc)SetValues,
  2505.         /* set_values_hook    */    NULL,
  2506.         /* set_values_almost    */    XtInheritSetValuesAlmost,
  2507.         /* get_values_hook    */    NULL,
  2508.         /* accept_focus        */    NULL,
  2509.         /* version        */    XtVersion,
  2510.         /* callback_private    */    NULL,
  2511.         /* tm_table        */    NULL,
  2512.         /* query_geometry       */    XtInheritQueryGeometry,
  2513.         /* display_accelerator  */    XtInheritDisplayAccelerator,
  2514.         /* extension            */    NULL
  2515.     }, /* Core Part */
  2516.     {
  2517.         /* geometry_manager     */    GeometryManager,
  2518.         /* change_managed       */    XtInheritChangeManaged,
  2519.         /* insert_child         */    XtInheritInsertChild,
  2520.         /* delete_child         */    XtInheritDeleteChild,
  2521.         /* extension            */    NULL
  2522.     }, /* Composite Part */        
  2523.     {
  2524.         /* no extra class data  */    0
  2525.     }  /* FileSelector Part */
  2526. };
  2527.  
  2528. WidgetClass xfwfFileSelectorWidgetClass =
  2529.     (WidgetClass)&xfwfFileSelectorClassRec;
  2530.  
  2531. /*---------------------------------------------------------------------------*
  2532.  
  2533.                     E X P O R T E D    M E T H O D S
  2534.  
  2535.  *---------------------------------------------------------------------------*/
  2536.  
  2537.  
  2538. /*---------------------------------------------------------------------------*
  2539.  
  2540.     Initialize()
  2541.  
  2542.     This procedure is called by the X toolkit to initialize
  2543.     the widget instance.  The hook to this routine is in the
  2544.     initialize part of the core part of the class.
  2545.  
  2546.  *---------------------------------------------------------------------------*/
  2547.  
  2548. /* ARGSUSED */
  2549. static void Initialize(request,new)
  2550. Widget request,new;
  2551. {
  2552.     int i;
  2553.     XfwfFileSelectorWidget fsw;
  2554.     char *str,*initial_file,path[MAXPATHLEN + 2];
  2555.     static char *star = "*";
  2556.  
  2557.     fsw = (XfwfFileSelectorWidget)new;
  2558.     FSHandCursor(fsw) = XCreateFontCursor(XtDisplay(fsw),XC_hand1);
  2559.     FSBusyCursor(fsw) = XCreateFontCursor(XtDisplay(fsw),XC_watch);
  2560.  
  2561.     for (i = 0; i < FS_NUM_CHILDREN; i++) FSNthWidget(fsw,i) = NULL;
  2562.  
  2563.     FSDirMgr(fsw) = NULL;
  2564.     FSPathList(fsw) = NULL;
  2565.     FSPathListCount(fsw) = 0;
  2566.     FSFileList(fsw) = NULL;
  2567.     FSFileListCount(fsw) = 0;
  2568.  
  2569.     str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char));
  2570.     if (FSCurrentDirectory(fsw) != NULL)    /* User Specified Path */
  2571.     {
  2572.         strcpy(str,FSCurrentDirectory(fsw));
  2573.     }
  2574.         else
  2575.     {
  2576.         getwd(path);
  2577.         strcpy(str,path);
  2578.     }
  2579.     FSCurrentDirectory(fsw) = str;
  2580.  
  2581.     str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char));
  2582.     initial_file = FSCurrentFile(fsw);
  2583.     FSCurrentFile(fsw) = str;
  2584.  
  2585.     if (FSPattern(fsw) == NULL) FSPattern(fsw) = star;
  2586.     FSPattern(fsw) = StrCopy(FSPattern(fsw));
  2587.  
  2588.     if (FSCorePart(request)->width <= 0) FSCorePart(new)->width = 500;
  2589.     if (FSCorePart(request)->height <= 0) FSCorePart(new)->height = 200;
  2590.  
  2591.     ChildrenCreate(fsw);
  2592.     GotoDeepestLegalDirectory(fsw);
  2593.     if (initial_file) SelectFileByName(fsw,initial_file);
  2594. } /* End Initialize */
  2595.  
  2596.  
  2597. /*---------------------------------------------------------------------------*
  2598.  
  2599.     Realize()
  2600.  
  2601.     This function is called to realize a FileSelector widget.
  2602.  
  2603.  *---------------------------------------------------------------------------*/
  2604.  
  2605. static void Realize(gw,valueMask,attrs)
  2606. Widget gw;
  2607. XtValueMask *valueMask;
  2608. XSetWindowAttributes *attrs;
  2609. {
  2610.     XfwfFileSelectorWidget fsw;
  2611.  
  2612.     fsw = (XfwfFileSelectorWidget)gw;
  2613.     XtCreateWindow(gw,InputOutput,(Visual *)CopyFromParent,
  2614.         *valueMask,attrs);
  2615.  
  2616.     ChildrenRealize(fsw);
  2617.     ChildrenUpdate(fsw);
  2618.  
  2619.     Resize(gw);
  2620.     NotifySelectionChange(fsw);
  2621. } /* End Realize */
  2622.  
  2623.  
  2624.  
  2625. /*---------------------------------------------------------------------------*
  2626.  
  2627.     Destroy()
  2628.  
  2629.     This function is called to destroy a fileSelector widget.
  2630.  
  2631.  *---------------------------------------------------------------------------*/
  2632.  
  2633. static void Destroy(fsw)
  2634. XfwfFileSelectorWidget fsw;
  2635. {
  2636.     XtFree(FSCurrentDirectory(fsw));
  2637.     XtFree(FSCurrentFile(fsw));
  2638. } /* End Destroy */
  2639.  
  2640.  
  2641.  
  2642. /*---------------------------------------------------------------------------*
  2643.  
  2644.     Resize()
  2645.  
  2646.     This function is called to resize a fileSelector widget.
  2647.  
  2648.  *---------------------------------------------------------------------------*/
  2649.  
  2650. static void Resize(gw) 
  2651. Widget gw;
  2652. {
  2653.     XfwfFileSelectorWidget w;
  2654.  
  2655.     w = (XfwfFileSelectorWidget)gw;
  2656.     ChildrenUpdate(w);
  2657. } /* End Resize */
  2658.  
  2659.  
  2660. /*---------------------------------------------------------------------------*
  2661.  
  2662.     SetValues(gcurrent,grequest,gnew)
  2663.  
  2664.     This function is the external interface for setting resources.
  2665.  
  2666.  *---------------------------------------------------------------------------*/
  2667.  
  2668. /* ARGSUSED */
  2669. static Boolean SetValues(gcurrent,grequest,gnew)
  2670. Widget gcurrent,grequest,gnew;
  2671. {
  2672.     XfwfFileSelectorWidget current,new;
  2673.  
  2674.     current = (XfwfFileSelectorWidget)gcurrent;
  2675.     new = (XfwfFileSelectorWidget)gnew;
  2676.  
  2677.     if (FSPattern(current) != FSPattern(new))
  2678.     {
  2679.         XtWarning("Pattern Change Not Supported");
  2680.         FSPattern(new) = FSPattern(current);
  2681.     }
  2682.     if (FSSortMode(current) != FSSortMode(new))
  2683.     {
  2684.         XtWarning("Sort Mode Change Not Supported");
  2685.         FSSortMode(new) = FSSortMode(current);
  2686.     }
  2687.     if (FSTitle(current) != FSTitle(new))
  2688.     {
  2689.         XtWarning("Title Change Not Supported");
  2690.         FSTitle(new) = FSTitle(current);
  2691.     }
  2692.     if (FSFileSelected(current) != FSFileSelected(new))
  2693.     {
  2694.         XtWarning("Can't Change XtNfileSelected Resource");
  2695.         FSFileSelected(new) = FSFileSelected(current);
  2696.     }
  2697.     if (FSCheckExistence(current) != FSCheckExistence(new))
  2698.     {
  2699.         if (!FSCheckExistence(new))
  2700.         {
  2701.             XtSetSensitive(FSNthWidget(new,FS_I_OK_BUTTON),True);
  2702.         }
  2703.             else
  2704.         {
  2705.             Chdir(new);
  2706.         }                
  2707.     }
  2708.     if (FSShowOkButton(current) != FSShowOkButton(new))
  2709.     {
  2710.         if (FSShowOkButton(new) == True)
  2711.             XtManageChild(FSNthWidget(new,FS_I_OK_BUTTON));
  2712.             else
  2713.             XtUnmanageChild(FSNthWidget(new,FS_I_OK_BUTTON));
  2714.     }
  2715.     if (FSShowCancelButton(current) != FSShowCancelButton(new))
  2716.     {
  2717.         if (FSShowCancelButton(new) == True)
  2718.             XtManageChild(FSNthWidget(new,FS_I_CANCEL_BUTTON));
  2719.             else
  2720.             XtUnmanageChild(FSNthWidget(new,FS_I_CANCEL_BUTTON));
  2721.     }
  2722.     if (FSCurrentDirectory(current) != FSCurrentDirectory(new))
  2723.     {
  2724.         strcpy(FSCurrentDirectory(current),FSCurrentDirectory(new));
  2725.         FSCurrentDirectory(new) = FSCurrentDirectory(current);
  2726.         Chdir(new);
  2727.     }
  2728.     if (FSCurrentFile(current) != FSCurrentFile(new))
  2729.     {
  2730.         char *new_name;
  2731.  
  2732.         new_name = FSCurrentFile(new);
  2733.         FSCurrentFile(new) = FSCurrentFile(current);
  2734.         SelectFileByName(new,new_name);
  2735.     }
  2736.     return(False);
  2737. } /* End SetValues */
  2738.  
  2739.  
  2740.  
  2741. /*---------------------------------------------------------------------------*
  2742.  
  2743.     GeometryManager(w,request,reply)
  2744.  
  2745.     This routine acts as the geometry_manager method for the
  2746.     FileSelector widget.  It is called when a child wants to
  2747.     resize/reposition itself.
  2748.  
  2749.     Currently, we allow all requests.
  2750.  
  2751.  *---------------------------------------------------------------------------*/
  2752.  
  2753. /* ARGSUSED */
  2754. static XtGeometryResult GeometryManager(w,request,reply)
  2755. Widget w;
  2756. XtWidgetGeometry *request;
  2757. XtWidgetGeometry *reply;
  2758. {
  2759.     return(XtGeometryYes);
  2760. } /* End GeometryManager */
  2761.  
  2762. /*---------------------------------------------------------------------------*
  2763.  
  2764.                      L O C A L    R O U T I N E S
  2765.  
  2766.  *---------------------------------------------------------------------------*/
  2767.  
  2768. /*---------------------------------------------------------------------------*
  2769.  
  2770.     ChildrenCreate(fsw)
  2771.  
  2772.     This routine creates the initial child widgets for the
  2773.     file selector widget and places them in the widget fsw.
  2774.     No placement or resizing is done.  That is done by
  2775.     ChildrenUpdate().
  2776.  
  2777.  *---------------------------------------------------------------------------*/
  2778.  
  2779. static void ChildrenCreate(fsw)
  2780. XfwfFileSelectorWidget fsw;
  2781. {
  2782.     Arg args[10];
  2783.     static char *dummy_string_list[] = { NULL };
  2784.     static char *text_box_translations = "#override\n<Key>Return: no-op()";
  2785.  
  2786.  
  2787.         /* Title */
  2788.  
  2789.     XtSetArg(args[0],XtNlabel,FSTitle(fsw));
  2790.     XtSetArg(args[1],XtNborderWidth,0);
  2791.     FSNthWidget(fsw,FS_I_TITLE) = XtCreateManagedWidget("title",
  2792.         labelWidgetClass,(Widget)fsw,args,2);
  2793.  
  2794.         /* Current Directory Line */
  2795.  
  2796.     XtSetArg(args[0],XtNtype,XawAsciiString);
  2797.     XtSetArg(args[1],XtNeditType,XawtextEdit);
  2798.     XtSetArg(args[2],XtNstring,"");
  2799.     XtSetArg(args[3],XtNautoFill,True);
  2800.     XtSetArg(args[4],XtNtranslations,text_box_translations);
  2801.     FSNthWidget(fsw,FS_I_CUR_DIR_TEXT) =
  2802.         XtCreateManagedWidget("cur_dir_text",
  2803.                       asciiTextWidgetClass,(Widget)fsw,args,4);
  2804.  
  2805.         /* Current File Line */
  2806.  
  2807.     XtSetArg(args[0],XtNtype,XawAsciiString);
  2808.     XtSetArg(args[1],XtNeditType,XawtextEdit);
  2809.     XtSetArg(args[2],XtNstring,"");
  2810.     XtSetArg(args[3],XtNautoFill,True);
  2811.     XtSetArg(args[4],XtNtranslations,text_box_translations);
  2812.     FSNthWidget(fsw,FS_I_CUR_FILE_TEXT) =
  2813.         XtCreateManagedWidget("cur_file_text",
  2814.                       asciiTextWidgetClass,(Widget)fsw,args,4);
  2815.  
  2816.         /* Path From Root Title */
  2817.  
  2818.     XtSetArg(args[0],XtNlabel,"Path From Root");
  2819.     XtSetArg(args[1],XtNborderWidth,0);
  2820.     FSNthWidget(fsw,FS_I_PATH_LIST_TITLE) =
  2821.         XtCreateManagedWidget("path_list_title",
  2822.                       labelWidgetClass,(Widget)fsw,args,2);
  2823.  
  2824.         /* Directory List */
  2825.  
  2826.     XtSetArg(args[0],XtNlist,dummy_string_list);
  2827.     XtSetArg(args[1],XtNnumberStrings,0);
  2828.     FSNthWidget(fsw,FS_I_PATH_LIST) =
  2829.         XtCreateManagedWidget("path_list",
  2830.             xfwfScrolledListWidgetClass,(Widget)fsw,args,2);
  2831.     XtAddCallback(FSNthWidget(fsw,FS_I_PATH_LIST),
  2832.               XtNcallback,(XtCallbackProc)ClickOnPathList,fsw);
  2833.  
  2834.         /* File List Title */
  2835.  
  2836.     XtSetArg(args[0],XtNlabel,"Directory Contents");
  2837.     XtSetArg(args[1],XtNborderWidth,0);
  2838.     FSNthWidget(fsw,FS_I_FILE_LIST_TITLE) =
  2839.         XtCreateManagedWidget("file_list_title",
  2840.                       labelWidgetClass,(Widget)fsw,args,2);
  2841.  
  2842.         /* File List */
  2843.  
  2844.     XtSetArg(args[0],XtNlist,dummy_string_list);
  2845.     XtSetArg(args[1],XtNnumberStrings,0);
  2846.     FSNthWidget(fsw,FS_I_FILE_LIST) =
  2847.         XtCreateManagedWidget("file_list",
  2848.             xfwfScrolledListWidgetClass,(Widget)fsw,args,2);
  2849.     XtAddCallback(FSNthWidget(fsw,FS_I_FILE_LIST),
  2850.               XtNcallback,(XtCallbackProc)ClickOnFileList,fsw);
  2851.  
  2852.         /* Goto Button */
  2853.  
  2854.     XtSetArg(args[0],XtNlabel,"Goto");
  2855. /*    XtSetArg(args[1],XtNborderWidth,2); */
  2856.     FSNthWidget(fsw,FS_I_GOTO_BUTTON) =
  2857.         XtCreateManagedWidget("goto_button",
  2858.                       commandWidgetClass,(Widget)fsw,args,1);
  2859.     XtAddCallback(FSNthWidget(fsw,FS_I_GOTO_BUTTON),
  2860.               XtNcallback,(XtCallbackProc)ButtonGoto,fsw);
  2861.  
  2862.         /* Select Button */
  2863.  
  2864.     XtSetArg(args[0],XtNlabel,"Select");
  2865. /*    XtSetArg(args[1],XtNborderWidth,2); */
  2866.     FSNthWidget(fsw,FS_I_SELECT_BUTTON) =
  2867.         XtCreateManagedWidget("select_button",
  2868.                       commandWidgetClass,(Widget)fsw,args,1);
  2869.     XtAddCallback(FSNthWidget(fsw,FS_I_SELECT_BUTTON),
  2870.               XtNcallback,(XtCallbackProc)ButtonSelect,fsw);
  2871.  
  2872.         /* Up Button */
  2873.  
  2874.     XtSetArg(args[0],XtNlabel,"Up");
  2875. /*    XtSetArg(args[1],XtNborderWidth,2); */
  2876.     FSNthWidget(fsw,FS_I_UP_BUTTON) = XtCreateManagedWidget("up_button",
  2877.         commandWidgetClass,(Widget)fsw,args,1);
  2878.     XtAddCallback(FSNthWidget(fsw,FS_I_UP_BUTTON),
  2879.               XtNcallback,(XtCallbackProc)ButtonUp,fsw);
  2880.  
  2881.         /* OK Button */
  2882.  
  2883.     XtSetArg(args[0],XtNlabel,"OK");
  2884. /*    XtSetArg(args[1],XtNborderWidth,2); */
  2885.     FSNthWidget(fsw,FS_I_OK_BUTTON) = XtCreateManagedWidget("ok_button",
  2886.         commandWidgetClass,(Widget)fsw,args,1);
  2887.     XtAddCallback(FSNthWidget(fsw,FS_I_OK_BUTTON),
  2888.               XtNcallback,(XtCallbackProc)ButtonOk,fsw);
  2889.  
  2890.         /* Cancel Button */
  2891.  
  2892.     XtSetArg(args[0],XtNlabel,"Cancel");
  2893. /*    XtSetArg(args[1],XtNborderWidth,2); */
  2894.     FSNthWidget(fsw,FS_I_CANCEL_BUTTON) =
  2895.         XtCreateManagedWidget("cancel_button",
  2896.                       commandWidgetClass,(Widget)fsw,args,1);
  2897.     XtAddCallback(FSNthWidget(fsw,FS_I_CANCEL_BUTTON),
  2898.               XtNcallback,(XtCallbackProc)ButtonCancel,fsw);
  2899. } /* End ChildrenCreate */    
  2900.  
  2901.  
  2902. /*---------------------------------------------------------------------------*
  2903.  
  2904.     ChildrenRealize(fsw)
  2905.  
  2906.     This routine realizes the child widgets.  The widgets must
  2907.     already have been created and initialized.  Their coordinates
  2908.     should already have been set.
  2909.  
  2910.  *---------------------------------------------------------------------------*/
  2911.  
  2912. static void ChildrenRealize(fsw)
  2913. XfwfFileSelectorWidget fsw;
  2914. {
  2915.     int i;
  2916.     Widget widget;
  2917.  
  2918.     for (i = 0; i < FS_NUM_CHILDREN; i++)
  2919.     {
  2920.         if (FSNthWidget(fsw,i) != NULL)
  2921.         {
  2922.             widget = FSNthWidget(fsw,i);
  2923.             XtRealizeWidget(widget);
  2924.             if ((i == FS_I_OK_BUTTON &&
  2925.                  !FSShowOkButton(fsw)) ||
  2926.                 (i == FS_I_CANCEL_BUTTON &&
  2927.                  !FSShowCancelButton(fsw)))
  2928.             {
  2929.                 XtUnmanageChild(widget);
  2930.             }
  2931.         }
  2932.     }
  2933. } /* End ChildrenRealize */
  2934.  
  2935.  
  2936. /*---------------------------------------------------------------------------*
  2937.  
  2938.         ChildrenRecalculate(fsw)
  2939.  
  2940.     This routine takes a file selector widget and recalculates
  2941.     the coordinates and sizes of the constituent components
  2942.     based on the current size of the file selector.
  2943.  
  2944.     This function does not actually change the child widgets, it
  2945.     just calculates the coordinates and caches the coordinates in
  2946.     the FileSelector widget.
  2947.  
  2948.  *---------------------------------------------------------------------------*/
  2949.  
  2950. static void ChildrenRecalculate(fsw)
  2951. XfwfFileSelectorWidget fsw;
  2952. {
  2953.     BOX *coords;
  2954.     Widget widget;
  2955.     int i,w,h,empty_space,gap,orig_path_list_h,orig_file_list_h,top;
  2956.     XtWidgetGeometry parent_idea,child_idea;
  2957.  
  2958.     w = FSCorePart(fsw)->width;
  2959.     h = FSCorePart(fsw)->height;
  2960.  
  2961.     /* Get The Child Widgets Current Widths And Heights */
  2962.  
  2963.     for (i = 0; i < FS_NUM_CHILDREN; i++)
  2964.     {
  2965.         if (FSNthWidget(fsw,i) != NULL)
  2966.         {
  2967.             widget = FSNthWidget(fsw,i);
  2968.             coords = FSNthCoords(fsw,i);
  2969.             BoxW(coords) = CoreWidth(widget);
  2970.             BoxH(coords) = CoreHeight(widget);
  2971.         }
  2972.     }
  2973.  
  2974.         /* Adjust Widths */
  2975.  
  2976.     BoxW(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) = .7 * w;
  2977.     BoxW(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) = .7 * w;
  2978.     BoxW(FSNthCoords(fsw,FS_I_GOTO_BUTTON)) = .15 * w;
  2979.     BoxW(FSNthCoords(fsw,FS_I_SELECT_BUTTON)) = .15 * w;
  2980.  
  2981.     BoxW(FSNthCoords(fsw,FS_I_PATH_LIST)) = .45 * w;
  2982.     BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)) = .45 * w;
  2983.     BoxW(FSNthCoords(fsw,FS_I_UP_BUTTON)) =
  2984.         BoxW(FSNthCoords(fsw,FS_I_PATH_LIST)) * .35;
  2985.     BoxW(FSNthCoords(fsw,FS_I_OK_BUTTON)) =
  2986.         BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)) * .35;
  2987.     BoxW(FSNthCoords(fsw,FS_I_CANCEL_BUTTON)) =
  2988.         BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)) * .35;
  2989.  
  2990.         /* Adjust Heights */
  2991.  
  2992.     BoxH(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) =
  2993.         max(BoxH(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)),
  2994.             BoxH(FSNthCoords(fsw,FS_I_GOTO_BUTTON)));
  2995.     BoxH(FSNthCoords(fsw,FS_I_GOTO_BUTTON)) =
  2996.         BoxH(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT));
  2997.  
  2998.     BoxH(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) =
  2999.         max(BoxH(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)),
  3000.             BoxH(FSNthCoords(fsw,FS_I_SELECT_BUTTON)));
  3001.     BoxH(FSNthCoords(fsw,FS_I_SELECT_BUTTON)) =
  3002.         BoxH(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT));
  3003.  
  3004.     empty_space = h - (BoxH(FSNthCoords(fsw,FS_I_TITLE)) +
  3005.                BoxH(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) +
  3006.                BoxH(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) +
  3007.                BoxH(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE)) +
  3008.                BoxH(FSNthCoords(fsw,FS_I_OK_BUTTON)));
  3009.     gap = .025 * h;
  3010.     BoxH(FSNthCoords(fsw,FS_I_PATH_LIST)) = empty_space - 8 * gap;
  3011.     BoxH(FSNthCoords(fsw,FS_I_FILE_LIST)) = empty_space - 8 * gap;
  3012.     orig_path_list_h = BoxH(FSNthCoords(fsw,FS_I_PATH_LIST));
  3013.     orig_file_list_h = BoxH(FSNthCoords(fsw,FS_I_FILE_LIST));
  3014.  
  3015.         /* Listen To Child Height Requests For Lists */
  3016.  
  3017.     parent_idea.request_mode = CWWidth | CWHeight;
  3018.     parent_idea.width = BoxW(FSNthCoords(fsw,FS_I_PATH_LIST));
  3019.     parent_idea.height = BoxH(FSNthCoords(fsw,FS_I_PATH_LIST));
  3020.     XtQueryGeometry(FSNthWidget(fsw,FS_I_PATH_LIST),
  3021.             &parent_idea,&child_idea);
  3022.     if ((child_idea.request_mode & CWHeight) &&
  3023.         (child_idea.height < parent_idea.height))
  3024.     {
  3025.         BoxH(FSNthCoords(fsw,FS_I_PATH_LIST)) = child_idea.height;
  3026.     }
  3027.  
  3028.     parent_idea.request_mode = CWWidth | CWHeight;
  3029.     parent_idea.width = BoxW(FSNthCoords(fsw,FS_I_FILE_LIST));
  3030.     parent_idea.height = BoxH(FSNthCoords(fsw,FS_I_FILE_LIST));
  3031.     XtQueryGeometry(FSNthWidget(fsw,FS_I_FILE_LIST),
  3032.             &parent_idea,&child_idea);
  3033.     if ((child_idea.request_mode & CWHeight) &&
  3034.         (child_idea.height < parent_idea.height))
  3035.     {
  3036.         BoxH(FSNthCoords(fsw,FS_I_FILE_LIST)) = child_idea.height;
  3037.     }
  3038.  
  3039.         /* Make Sure Both Lists Have Same Minimum Height */
  3040.  
  3041.     BoxH(FSNthCoords(fsw,FS_I_PATH_LIST)) =
  3042.         min(BoxH(FSNthCoords(fsw,FS_I_PATH_LIST)),
  3043.             BoxH(FSNthCoords(fsw,FS_I_FILE_LIST)));
  3044.     BoxH(FSNthCoords(fsw,FS_I_FILE_LIST)) =
  3045.         min(BoxH(FSNthCoords(fsw,FS_I_PATH_LIST)),
  3046.             BoxH(FSNthCoords(fsw,FS_I_FILE_LIST)));
  3047.  
  3048.         /* Vertical Positions */
  3049.  
  3050.     BoxY(FSNthCoords(fsw,FS_I_TITLE)) = gap;
  3051.  
  3052.     BoxY(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) =
  3053.         (BoxY(FSNthCoords(fsw,FS_I_TITLE)) +
  3054.          BoxH(FSNthCoords(fsw,FS_I_TITLE))) + gap;
  3055.     BoxY(FSNthCoords(fsw,FS_I_GOTO_BUTTON)) =
  3056.         BoxY(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT));
  3057.  
  3058.     BoxY(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) =
  3059.         (BoxY(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) +
  3060.          BoxH(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT))) + gap;
  3061.     BoxY(FSNthCoords(fsw,FS_I_SELECT_BUTTON)) =
  3062.         BoxY(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT));
  3063.  
  3064.     BoxY(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE)) =
  3065.         (BoxY(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) +
  3066.          BoxH(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT))) + gap;
  3067.     BoxY(FSNthCoords(fsw,FS_I_FILE_LIST_TITLE)) =
  3068.         BoxY(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE));
  3069.  
  3070.     BoxY(FSNthCoords(fsw,FS_I_PATH_LIST)) =
  3071.         (BoxY(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE)) +
  3072.          BoxH(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE))) + gap +
  3073.         (orig_path_list_h - BoxH(FSNthCoords(fsw,FS_I_PATH_LIST))) / 2;
  3074.     BoxY(FSNthCoords(fsw,FS_I_FILE_LIST)) =
  3075.         BoxY(FSNthCoords(fsw,FS_I_PATH_LIST));
  3076.  
  3077.     top = BoxY(FSNthCoords(fsw,FS_I_PATH_LIST)) +
  3078.         BoxH(FSNthCoords(fsw,FS_I_PATH_LIST));
  3079.     empty_space = h - top;
  3080.     BoxY(FSNthCoords(fsw,FS_I_UP_BUTTON)) = top +
  3081.         (h - top - BoxH(FSNthCoords(fsw,FS_I_UP_BUTTON))) / 2;
  3082.     BoxY(FSNthCoords(fsw,FS_I_OK_BUTTON)) = top +
  3083.         (h - top - BoxH(FSNthCoords(fsw,FS_I_OK_BUTTON))) / 2;
  3084.     BoxY(FSNthCoords(fsw,FS_I_CANCEL_BUTTON)) = top +
  3085.         (h - top - BoxH(FSNthCoords(fsw,FS_I_CANCEL_BUTTON))) / 2;
  3086.  
  3087.         /* Horizontal Positions */
  3088.  
  3089.     BoxX(FSNthCoords(fsw,FS_I_TITLE)) =
  3090.         (w - BoxW(FSNthCoords(fsw,FS_I_TITLE))) / 2;
  3091.  
  3092.     empty_space = w - (BoxW(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) +
  3093.                BoxW(FSNthCoords(fsw,FS_I_GOTO_BUTTON)));
  3094.     gap = empty_space / 3;
  3095.     BoxX(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) = gap;
  3096.     BoxX(FSNthCoords(fsw,FS_I_GOTO_BUTTON)) =
  3097.         (BoxX(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT)) +
  3098.          BoxW(FSNthCoords(fsw,FS_I_CUR_DIR_TEXT))) + gap;
  3099.  
  3100.     empty_space = w - (BoxW(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) +
  3101.                BoxW(FSNthCoords(fsw,FS_I_SELECT_BUTTON)));
  3102.     gap = empty_space / 3;
  3103.     BoxX(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) = gap;
  3104.     BoxX(FSNthCoords(fsw,FS_I_SELECT_BUTTON)) =
  3105.         (BoxX(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT)) +
  3106.          BoxW(FSNthCoords(fsw,FS_I_CUR_FILE_TEXT))) + gap;
  3107.  
  3108.     empty_space = w - (BoxW(FSNthCoords(fsw,FS_I_PATH_LIST)) +
  3109.                BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)));
  3110.     gap = empty_space / 3;
  3111.     BoxX(FSNthCoords(fsw,FS_I_PATH_LIST)) = gap;
  3112.     BoxX(FSNthCoords(fsw,FS_I_FILE_LIST)) =
  3113.         (BoxX(FSNthCoords(fsw,FS_I_PATH_LIST)) +
  3114.          BoxW(FSNthCoords(fsw,FS_I_PATH_LIST))) + gap;
  3115.  
  3116.     BoxX(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE)) =
  3117.         (BoxX(FSNthCoords(fsw,FS_I_PATH_LIST)) +
  3118.          (BoxW(FSNthCoords(fsw,FS_I_PATH_LIST)) -
  3119.           BoxW(FSNthCoords(fsw,FS_I_PATH_LIST_TITLE))) / 2);
  3120.  
  3121.     BoxX(FSNthCoords(fsw,FS_I_FILE_LIST_TITLE)) =
  3122.         (BoxX(FSNthCoords(fsw,FS_I_FILE_LIST)) +
  3123.          (BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)) -
  3124.           BoxW(FSNthCoords(fsw,FS_I_FILE_LIST_TITLE))) / 2);
  3125.  
  3126.     empty_space = BoxW(FSNthCoords(fsw,FS_I_PATH_LIST)) -
  3127.         BoxW(FSNthCoords(fsw,FS_I_UP_BUTTON));
  3128.     gap = empty_space / 2;
  3129.     BoxX(FSNthCoords(fsw,FS_I_UP_BUTTON)) =
  3130.         BoxX(FSNthCoords(fsw,FS_I_PATH_LIST)) + gap;
  3131.  
  3132.     empty_space = BoxW(FSNthCoords(fsw,FS_I_FILE_LIST)) -
  3133.         (BoxW(FSNthCoords(fsw,FS_I_OK_BUTTON)) +
  3134.          BoxW(FSNthCoords(fsw,FS_I_CANCEL_BUTTON)));
  3135.     gap = empty_space / 3;
  3136.     BoxX(FSNthCoords(fsw,FS_I_OK_BUTTON)) =
  3137.         BoxX(FSNthCoords(fsw,FS_I_FILE_LIST)) + gap;
  3138.     BoxX(FSNthCoords(fsw,FS_I_CANCEL_BUTTON)) =
  3139.         (BoxX(FSNthCoords(fsw,FS_I_OK_BUTTON)) +
  3140.          BoxW(FSNthCoords(fsw,FS_I_OK_BUTTON))) + gap;
  3141. } /* End ChildrenRecalculate */
  3142.  
  3143.  
  3144. /*---------------------------------------------------------------------------*
  3145.  
  3146.     ChildrenUpdate(fsw)
  3147.  
  3148.     This routine takes a File Selector widget <fsw> and updates
  3149.     the child widgets by recalculating their coordinates and
  3150.     setting the appropriate resources.   
  3151.  
  3152.  *---------------------------------------------------------------------------*/
  3153.  
  3154. static void ChildrenUpdate(fsw)
  3155. XfwfFileSelectorWidget fsw;
  3156. {
  3157.     int i;
  3158.     Widget widget;
  3159.     BOX *coords;
  3160.     Boolean not_at_root;
  3161.     XfwfScrolledListWidget file_list;
  3162.  
  3163.     ChildrenRecalculate(fsw);
  3164.  
  3165.     for (i = 0; i < FS_NUM_CHILDREN; i++)
  3166.     {
  3167.         if (FSNthWidget(fsw,i) != NULL)
  3168.         {
  3169.             widget = FSNthWidget(fsw,i);
  3170.             coords = FSNthCoords(fsw,i);
  3171.             XtMoveWidget(widget,BoxX(coords),BoxY(coords));
  3172.             XtResizeWidget(widget,BoxW(coords),BoxH(coords),
  3173.                        CoreBorderWidth(widget));
  3174.         }
  3175.     }
  3176.  
  3177.     file_list = (XfwfScrolledListWidget)
  3178.         FSNthWidget(fsw,FS_I_FILE_LIST);
  3179.  
  3180.     if (FSPathListCount(fsw) != 1)
  3181.         not_at_root = True;
  3182.         else
  3183.         not_at_root = False;
  3184.  
  3185.     XtSetSensitive(FSNthWidget(fsw,FS_I_UP_BUTTON),not_at_root);
  3186. } /* End ChildrenUpdate */
  3187.  
  3188.  
  3189. /*---------------------------------------------------------------------------*
  3190.  
  3191.                  I N T E R N A L    C A L L B A C K S
  3192.  
  3193.  *---------------------------------------------------------------------------*/
  3194.  
  3195. static void ButtonUp(w,fsw,call_data)
  3196. Widget w;
  3197. XfwfFileSelectorWidget fsw;
  3198. XtPointer call_data;
  3199. {
  3200.     strcat(FSCurrentDirectory(fsw),"..");
  3201.     Chdir(fsw);
  3202. } /* End ButtonUp */
  3203.  
  3204.  
  3205. static void ButtonOk(w,fsw,call_data)
  3206. Widget w;
  3207. XfwfFileSelectorWidget fsw;
  3208. XtPointer call_data;
  3209. {
  3210.     XfwfFileSelectorOkButtonReturnStruct ret;
  3211.  
  3212.     ret.path = FSCurrentDirectory(fsw);
  3213.     ret.file = FSCurrentFile(fsw);
  3214.     ret.file_box_text = GetFileBoxText(fsw);
  3215.     XtCallCallbacks((Widget)fsw,XtNokButtonCallback,(XtPointer)&ret);
  3216. } /* End ButtonOk */
  3217.  
  3218.  
  3219. static void ButtonCancel(w,fsw,call_data)
  3220. Widget w;
  3221. XfwfFileSelectorWidget fsw;
  3222. XtPointer call_data;
  3223. {
  3224.     XtCallCallbacks((Widget)fsw,XtNcancelButtonCallback,NULL);
  3225. } /* End ButtonCancel */
  3226.  
  3227.  
  3228. static void ButtonGoto(w,fsw,call_data)
  3229. Widget w;
  3230. XfwfFileSelectorWidget fsw;
  3231. XtPointer call_data;
  3232. {
  3233.     Widget cur_dir_text;
  3234.     Arg args[10];
  3235.     String path;
  3236.  
  3237.     XtSetArg(args[0],XtNstring,(XtArgVal)(&path));
  3238.     cur_dir_text = FSNthWidget(fsw,FS_I_CUR_DIR_TEXT);
  3239.     XtGetValues(cur_dir_text,args,1);
  3240.     strcpy(FSCurrentDirectory(fsw),path);
  3241.     Chdir(fsw);
  3242. } /* End ButtonGoto */
  3243.  
  3244.  
  3245. static void ButtonSelect(w,fsw,call_data)
  3246. Widget w;
  3247. XfwfFileSelectorWidget fsw;
  3248. XtPointer call_data;
  3249. {
  3250.     String file;
  3251.  
  3252.     file = GetFileBoxText(fsw);
  3253.     if (SelectFileByName(fsw,file) == False) XBell(XtDisplay(fsw),0);
  3254.     UpdateTextLines(fsw);
  3255. } /* End ButtonSelect */
  3256.  
  3257.  
  3258. static char *GetFileBoxText(fsw)
  3259. XfwfFileSelectorWidget fsw;
  3260. {
  3261.     char *text;
  3262.     Arg args[1];
  3263.     Widget file_box_widget;
  3264.  
  3265.     XtSetArg(args[0],XtNstring,(XtArgVal)(&text));
  3266.     file_box_widget = FSNthWidget(fsw,FS_I_CUR_FILE_TEXT);
  3267.     XtGetValues(file_box_widget,args,1);
  3268.     return(text);
  3269. } /* End GetFileBoxText */
  3270.  
  3271.  
  3272. static void ClickOnPathList(w,fsw,call_data)
  3273. Widget w;
  3274. XfwfFileSelectorWidget fsw;
  3275. XtPointer call_data;
  3276. {
  3277.     int i;
  3278.     XfwfScrolledListReturnStruct *ret;
  3279.     
  3280.     ret = (XfwfScrolledListReturnStruct *)call_data;
  3281.     if (ret->index == -1)
  3282.     {
  3283.         UnselectAll(fsw);        /* Click On Blank Space */
  3284.         return;
  3285.     }
  3286.     strcpy(FSCurrentDirectory(fsw),"/");
  3287.     for (i = 1; i <= ret->index; i++)
  3288.     {
  3289.         strcat(FSCurrentDirectory(fsw),FSPathList(fsw)[i]);
  3290.         strcat(FSCurrentDirectory(fsw),"/");
  3291.     }
  3292.     Chdir(fsw);
  3293. } /* End ClickOnPathList */
  3294.  
  3295.  
  3296. static void ClickOnFileList(w,fsw,call_data)
  3297. Widget w;
  3298. XfwfFileSelectorWidget fsw;
  3299. XtPointer call_data;
  3300. {
  3301.     XfwfScrolledListReturnStruct *ret;
  3302.  
  3303.     ret = (XfwfScrolledListReturnStruct *)call_data;
  3304.     if (ret->index == -1)
  3305.         UnselectAll(fsw);        /* Click On Blank Space */
  3306.         else
  3307.         SelectFileByIndex(fsw,ret->index);
  3308. } /* End ClickOnFileList */
  3309.  
  3310.  
  3311. /*---------------------------------------------------------------------------*
  3312.  
  3313.              I N T E R N A L    S U P P O R T    R O U T I N E S
  3314.  
  3315.  *---------------------------------------------------------------------------*/
  3316.  
  3317. static void SelectFileByIndex(fsw,index)
  3318. XfwfFileSelectorWidget fsw;
  3319. int index;
  3320. {
  3321.     DirEntry *dir_entry;
  3322.  
  3323.     DirectoryMgrGotoItem(FSDirMgr(fsw),index);
  3324.     dir_entry = DirectoryMgrCurrentEntry(FSDirMgr(fsw));
  3325.     if (dir_entry == NULL)
  3326.     {
  3327.         fprintf(stderr,"SelectFileByIndex: Entry %d invalid\n",index);
  3328.         exit(-1);
  3329.     }
  3330.     if (DirEntryIsDir(dir_entry) || DirEntryIsDirectoryLink(dir_entry))
  3331.     {
  3332.         strcat(FSCurrentDirectory(fsw),DirEntryFileName(dir_entry));
  3333.         Chdir(fsw);
  3334.     }
  3335.         else if (!DirEntryIsBrokenLink(dir_entry))    /* File */
  3336.     {
  3337.         strcpy(FSCurrentFile(fsw),DirEntryFileName(dir_entry));
  3338.         if (FSCheckExistence(fsw))
  3339.         {
  3340.             XtSetSensitive(FSNthWidget(fsw,FS_I_OK_BUTTON),True);
  3341.         }
  3342.         FSFileSelected(fsw) = True;
  3343.         TextWidgetSetText(FSNthWidget(fsw,FS_I_CUR_FILE_TEXT),
  3344.                   FSCurrentFile(fsw));
  3345.         XfwfScrolledListHighlightItem(FSNthWidget(fsw,FS_I_FILE_LIST),
  3346.                       index);
  3347.         NotifySelectionChange(fsw);
  3348.     }
  3349.         else                    /* Broken Link */
  3350.     {
  3351.         XBell(XtDisplay(fsw),0);
  3352.         UnselectAll(fsw);
  3353.     }
  3354. } /* End SelectFileByIndex */
  3355.  
  3356.  
  3357. static Boolean SelectFileByName(fsw,name)
  3358. XfwfFileSelectorWidget fsw;
  3359. char *name;
  3360. {
  3361.     if (DirectoryMgrGotoNamedItem(FSDirMgr(fsw),name) == FALSE)
  3362.     {
  3363.         return(False);
  3364.     }
  3365.     SelectFileByIndex(fsw,DirectoryMgrCurrentIndex(FSDirMgr(fsw)));
  3366.     return(True);
  3367. } /* End SelectFileByName */
  3368.  
  3369.  
  3370. static void UnselectAll(fsw)
  3371. XfwfFileSelectorWidget fsw;
  3372. {
  3373.     Boolean old_file_selected_flag;
  3374.  
  3375.     old_file_selected_flag = FSFileSelected(fsw);
  3376.     if (FSCheckExistence(fsw))
  3377.     {
  3378.         XtSetSensitive(FSNthWidget(fsw,FS_I_OK_BUTTON),False);
  3379.     }
  3380.     FSCurrentFile(fsw)[0] = '\0';
  3381.     FSFileSelected(fsw) = False;
  3382.     TextWidgetSetText(FSNthWidget(fsw,FS_I_CUR_FILE_TEXT),
  3383.               FSCurrentFile(fsw));
  3384.     XfwfScrolledListUnhighlightAll(FSNthWidget(fsw,FS_I_FILE_LIST));
  3385.     if (old_file_selected_flag) NotifySelectionChange(fsw);
  3386. } /* End UnselectAll */
  3387.  
  3388.  
  3389. static void NotifySelectionChange(fsw)
  3390. XfwfFileSelectorWidget fsw;
  3391. {
  3392.     XfwfFileSelectorSelectionChangeReturnStruct ret;
  3393.  
  3394.     if (FSFileSelected(fsw) == True)
  3395.     {
  3396.         ret.file_selected = True;
  3397.         ret.path = FSCurrentDirectory(fsw);
  3398.         ret.file = FSCurrentFile(fsw);
  3399.     }
  3400.         else
  3401.     {
  3402.         ret.file_selected = False;
  3403.         ret.path = NULL;
  3404.         ret.file = NULL;
  3405.     }
  3406.     XtCallCallbacks((Widget)fsw,XtNselectionChangeCallback,
  3407.             (XtPointer)&ret);
  3408. } /* End NotifySelectionChange */
  3409.  
  3410.  
  3411. /*---------------------------------------------------------------------------*
  3412.  
  3413.     GotoDeepestLegalDirectory(fsw)
  3414.  
  3415.     This function takes a FileSelector widget <fsw> and modifies the
  3416.     directory string in FSCurrentDirectory(fsw) to be the deepest
  3417.     legal directory above the string.  Partial or incorrect directory
  3418.     names are stripped starting at the end.
  3419.  
  3420.     This routine takes a File Selector widget <fsw> and updates
  3421.     the child widgets by recalculating their coordinates and
  3422.     setting the appropriate resources.  The old directory manager
  3423.     is closed and a new one is opened for this directory.  The
  3424.     file and path lists are deallocated, reallocated, and loaded
  3425.     with the path and file data lists.  The lists are then reset
  3426.     in the scrolled list widgets.
  3427.  
  3428.     This routine requires that all the child widgets have already
  3429.     been created.
  3430.  
  3431.  *---------------------------------------------------------------------------*/
  3432.  
  3433. static void GotoDeepestLegalDirectory(fsw)
  3434. XfwfFileSelectorWidget fsw;
  3435. {
  3436.     char *dir,*end_of_dir;
  3437.     char temp[MAXPATHLEN + 2];
  3438.  
  3439.     dir = FSCurrentDirectory(fsw);
  3440.     for (end_of_dir = dir; *end_of_dir != '\0'; ++ end_of_dir);
  3441.     while (1)
  3442.     {
  3443.         if (DirectoryPathExpand(dir,temp) == NULL)
  3444.         {
  3445.             XBell(XtDisplay(fsw), 0);
  3446.             while (*end_of_dir != '/' && end_of_dir != dir)
  3447.             {
  3448.                 -- end_of_dir;
  3449.             }
  3450.             *end_of_dir = '\0';
  3451.         }
  3452.             else
  3453.         {
  3454.             strcpy(FSCurrentDirectory(fsw),temp);
  3455.             break;
  3456.         }
  3457.     }
  3458.     UnselectAll(fsw);
  3459.     UpdateLists(fsw);
  3460. } /* End GotoDeepestLegalDirectory */
  3461.  
  3462.  
  3463. /*---------------------------------------------------------------------------*
  3464.  
  3465.     UpdateLists(fsw)
  3466.  
  3467.     This routine takes a FileSelector widget and builds new path
  3468.     and file lists from the current directory, sort mode, and pattern
  3469.     strings.  The lists and text items are then changed.
  3470.  
  3471.  *---------------------------------------------------------------------------*/
  3472.  
  3473. static void UpdateLists(fsw)
  3474. XfwfFileSelectorWidget fsw;
  3475. {
  3476.     int i,count;
  3477.     char *dir,*start;
  3478.     DirEntry *dir_entry;
  3479.     DirectoryMgr *dir_mgr;
  3480.     char temp[MAXPATHLEN + 2];
  3481.  
  3482.     if (FSDirMgr(fsw)) DirectoryMgrClose(FSDirMgr(fsw));
  3483.     dir_mgr = DirectoryMgrSimpleOpen(FSCurrentDirectory(fsw),
  3484.                      FSSortMode(fsw),
  3485.                      FSPattern(fsw));
  3486.     FSDirMgr(fsw) = dir_mgr;
  3487.     if (FSPathList(fsw) != NULL)
  3488.     {
  3489.         for (i = 0; i < FSPathListCount(fsw); i++)
  3490.             free(FSPathList(fsw)[i]);
  3491.         free(FSPathList(fsw));
  3492.     }
  3493.     if (FSFileList(fsw) != NULL)
  3494.     {
  3495.         for (i = 0; i < FSFileListCount(fsw); i++)
  3496.             free(FSFileList(fsw)[i]);
  3497.         free(FSFileList(fsw));
  3498.     }
  3499.  
  3500.     FSFileListCount(fsw) = DirectoryMgrFilteredCount(FSDirMgr(fsw));
  3501.     FSPathListCount(fsw) = 1;
  3502.     for (dir = FSCurrentDirectory(fsw) + 1; *dir != '\0'; dir++)
  3503.     {
  3504.         if (*dir == '/') ++ FSPathListCount(fsw);
  3505.     }
  3506.  
  3507.     FSFileList(fsw) = (char **)malloc(sizeof(char *) *
  3508.                       (FSFileListCount(fsw) + 1));
  3509.     if (FSFileList(fsw) == NULL)
  3510.     {
  3511.         fprintf(stderr,"UpdateLists: Out Of Memory\n");
  3512.         exit(-1);
  3513.     }
  3514.  
  3515.     for (i = 0; i < FSFileListCount(fsw); i++)
  3516.     {
  3517.         dir_entry = DirectoryMgrNextEntry(FSDirMgr(fsw));
  3518.         if (dir_entry == NULL) XtError("Inconsistent Directory");
  3519.         strcpy(temp,DirEntryFileName(dir_entry));
  3520.         if (DirEntryIsDir(dir_entry))
  3521.             strcat(temp,"/");
  3522.             else if (DirEntryIsBrokenLink(dir_entry))
  3523.             strcat(temp," X");
  3524.             else if (DirEntryIsDirectoryLink(dir_entry))
  3525.             strcat(temp,"/");
  3526.             else if (DirEntryIsSymLink(dir_entry) && FSFlagLinks(fsw))
  3527.             strcat(temp," @");
  3528.  
  3529.         FSFileList(fsw)[i] = StrCopy(temp);
  3530.     }
  3531.     FSFileList(fsw)[i] = NULL;
  3532.  
  3533.     FSPathList(fsw) = (char **)malloc(sizeof(char *) *
  3534.                       (FSPathListCount(fsw) + 1));
  3535.     start = FSCurrentDirectory(fsw);
  3536.     FSPathList(fsw)[0] = StrCopy("/");
  3537.     for (i = 1; i < FSPathListCount(fsw); i++)
  3538.     {
  3539.         while (*start != '\0' && *start == '/') ++start;
  3540.         count = 0;
  3541.         while (*start != '\0' && *start != '/')
  3542.             temp[count++] = *start++;
  3543.         temp[count++] = '\0';
  3544.         FSPathList(fsw)[i] = StrCopy(temp);
  3545.     }
  3546.     FSPathList(fsw)[i] = NULL;
  3547.  
  3548.     XfwfScrolledListSetList(FSNthWidget(fsw,FS_I_PATH_LIST),
  3549.                 FSPathList(fsw),FSPathListCount(fsw),True,NULL);
  3550.     XfwfScrolledListSetList(FSNthWidget(fsw,FS_I_FILE_LIST),
  3551.                 FSFileList(fsw),FSFileListCount(fsw),True,NULL);
  3552.     UpdateTextLines(fsw);
  3553. } /* End UpdateLists */
  3554.  
  3555.  
  3556. static void UpdateTextLines(fsw)
  3557. XfwfFileSelectorWidget fsw;
  3558. {
  3559.     TextWidgetSetText(FSNthWidget(fsw,FS_I_CUR_DIR_TEXT),
  3560.               FSCurrentDirectory(fsw));
  3561.     TextWidgetSetText(FSNthWidget(fsw,FS_I_CUR_FILE_TEXT),
  3562.               FSCurrentFile(fsw));
  3563. } /* End UpdateTextLines */
  3564.  
  3565.  
  3566. static void Chdir(fsw)
  3567. XfwfFileSelectorWidget fsw;
  3568. {
  3569.     DoBusyCursor((Widget)fsw);
  3570.     GotoDeepestLegalDirectory(fsw);
  3571.     ChildrenUpdate(fsw);
  3572.     UndoBusyCursor((Widget)fsw);
  3573. } /* End Chdir */
  3574.  
  3575.  
  3576. static void DoBusyCursor(w)
  3577. Widget w;
  3578. {
  3579. #ifndef NO_BUSY_GRAB
  3580.     if (XtIsRealized(w))
  3581.     {
  3582.         XGrabPointer(XtDisplay(w),XtWindow(w),True,None,
  3583.                  GrabModeSync,GrabModeSync,None,FSBusyCursor(w),
  3584.                  CurrentTime);
  3585.     }
  3586. #endif
  3587. } /* End DoBusyCursor */
  3588.  
  3589.  
  3590. static void UndoBusyCursor(w)
  3591. Widget w;
  3592. {
  3593. #ifndef NO_BUSY_GRAB
  3594.     if (XtIsRealized(w))
  3595.     {
  3596.         XUngrabPointer(XtDisplay(w),CurrentTime);
  3597.     }
  3598. #endif
  3599. } /* End UndoBusyCursor */
  3600.  
  3601.  
  3602. static void TextWidgetSetText(tw,text)
  3603. Widget tw;
  3604. char *text;
  3605. {
  3606.     Arg args[3];
  3607.     int length,insert_position;
  3608. #ifdef X11R3
  3609.     static char text_widget_storage[MAXPATHLEN + 2];
  3610. #endif
  3611.  
  3612.     length = strlen(text);
  3613.     insert_position = max(length,0);
  3614. #ifdef X11R3
  3615.     /*
  3616.     XtTextSetInsertionPoint(tw,insert_position);
  3617.     XtSetArg(args[0],XtNstring,text);
  3618.     XtSetValues(tw,args,1);
  3619.     {
  3620.         XtTextBlock block;
  3621.  
  3622.         block.firstPos = 0;
  3623.         block.length = length + 1;
  3624.         block.ptr = text;
  3625.         block.format = FMT8BIT;
  3626.         XtTextReplace(fsw,0,block.length - 1,&block);
  3627.     }
  3628.     */
  3629. #else
  3630.     XtSetArg(args[0],XtNstring,text);
  3631.     XtSetValues(tw,args,1);
  3632.     XawTextSetInsertionPoint(tw,insert_position);
  3633. #endif
  3634. } /* End TextWidgetSetText */
  3635.  
  3636. /*---------------------------------------------------------------------------*
  3637.  
  3638.                     E X T E R N A L    R O U T I N E S
  3639.  
  3640.  *---------------------------------------------------------------------------*/
  3641.  
  3642. void XfwfFileSelectorChangeDirectory(fsw,dir)
  3643. XfwfFileSelectorWidget fsw;
  3644. char *dir;
  3645. {
  3646.     strcpy(FSCurrentDirectory(fsw),dir);
  3647.     Chdir(fsw);
  3648. } /* End XfwfFileSelectorChangeDirectory */
  3649.  
  3650.  
  3651. void XfwfFileSelectorRefresh(fsw)
  3652. XfwfFileSelectorWidget fsw;
  3653. {
  3654.     XfwfFileSelectorChangeDirectory(fsw,".");
  3655. } /* End XfwfFileSelectorRefresh */
  3656.  
  3657.  
  3658. void XfwfFileSelectorGetStatus(fsw,ssp)
  3659. XfwfFileSelectorWidget fsw;
  3660. XfwfFileSelectorStatusStruct *ssp;
  3661. {    
  3662.     ssp->file_selected = FSFileSelected(fsw);
  3663.     ssp->path = FSCurrentDirectory(fsw);
  3664.     ssp->file = FSCurrentFile(fsw);
  3665.     ssp->file_box_text = GetFileBoxText(fsw);
  3666. } /* End XfwfFileSelectorGetStatus */
  3667. SHAR_EOF
  3668. fi
  3669. if test -f 'FileSel.h'
  3670. then
  3671.     echo shar: "will not over-write existing file 'FileSel.h'"
  3672. else
  3673. cat << \SHAR_EOF > 'FileSel.h'
  3674. /*****************************************************************************
  3675.  
  3676.     FileSelector.h
  3677.  
  3678.     This file contains the user includes for the FileSelector widget.
  3679.  
  3680. ******************************************************************************/
  3681.  
  3682. /*
  3683.  * Author:
  3684.  *     Brian Totty
  3685.  *     Department of Computer Science
  3686.  *     University Of Illinois at Urbana-Champaign
  3687.  *    1304 West Springfield Avenue
  3688.  *     Urbana, IL 61801
  3689.  * 
  3690.  *     totty@cs.uiuc.edu
  3691.  *     
  3692.  */ 
  3693.  
  3694. #ifndef _FILESELECTOR_H_
  3695. #define _FILESELECTOR_H_
  3696.  
  3697. #include "ScrList.h"
  3698. #include "DirMgr.h"
  3699.  
  3700. extern WidgetClass    xfwfFileSelectorWidgetClass;
  3701.  
  3702. typedef struct _XfwfFileSelectorClassRec *XfwfFileSelectorWidgetClass;
  3703. typedef struct _XfwfFileSelectorRec      *XfwfFileSelectorWidget;
  3704.  
  3705. #define    XtNpathname XtNcurrentDirectory        /* For Compatibility */
  3706.  
  3707. #ifndef XtNtitle
  3708. #define    XtNtitle            "title"
  3709. #endif
  3710.  
  3711. #define    XtNcurrentDirectory        "currentDirectory"
  3712. #define    XtNcurrentFile            "currentFile"
  3713. #define    XtNsortMode            "sortMode"
  3714. #define    XtNpattern            "pattern"
  3715. #define    XtNokButtonCallback        "okButtonCallback"
  3716. #define    XtNcancelButtonCallback        "cancelButtonCallback"
  3717. #define    XtNselectionChangeCallback    "selectionChangeCallback"
  3718. #define    XtNshowOkButton            "showOkButton"
  3719. #define    XtNshowCancelButton        "showCancelButton"
  3720. #define    XtNfileSelected            "fileSelected"
  3721. #define    XtNflagLinks            "flagLinks"
  3722. #define    XtNcheckExistence        "checkExistence"
  3723.  
  3724. #define    XtCPathname            "Pathname"
  3725. #define    XtCFilename            "Filename"
  3726.  
  3727. typedef struct _XfwfFileSelectorOkButtonReturnStruct
  3728. {
  3729.     char *path;
  3730.     char *file;
  3731.     char *file_box_text;
  3732. } XfwfFileSelectorOkButtonReturnStruct;
  3733.  
  3734. typedef struct _XfwfFileSelectorSelectionChangeReturnStruct
  3735. {
  3736.     Boolean file_selected;
  3737.     char *path;
  3738.     char *file;
  3739. } XfwfFileSelectorSelectionChangeReturnStruct;
  3740.  
  3741. typedef struct _XfwfFileSelectorStatusStruct
  3742. {
  3743.     Boolean file_selected;
  3744.     char *path;
  3745.     char *file;
  3746.     char *file_box_text;
  3747. } XfwfFileSelectorStatusStruct;
  3748.  
  3749. /*---------------------------------------------------------------------------*
  3750.  
  3751.                   E X T E R N A L    F U N C T I O N S
  3752.  
  3753.  *---------------------------------------------------------------------------*/
  3754.  
  3755. #if (!NeedFunctionPrototypes)
  3756.  
  3757. void    XfwfFileSelectorChangeDirectory();
  3758. void    XfwfFileSelectorRefresh();
  3759. void    XfwfFileSelectorGetStatus();
  3760.  
  3761. #else
  3762.  
  3763. void    XfwfFileSelectorChangeDirectory(XfwfFileSelectorWidget fsw, char *dir);
  3764. void    XfwfFileSelectorRefresh(XfwfFileSelectorWidget fsw);
  3765. void    XfwfFileSelectorGetStatus(XfwfFileSelectorWidget fsw,
  3766.                   XfwfFileSelectorStatusStruct *ssp);
  3767.  
  3768. #endif
  3769. #endif
  3770. SHAR_EOF
  3771. fi
  3772. if test -f 'FileSelP.h'
  3773. then
  3774.     echo shar: "will not over-write existing file 'FileSelP.h'"
  3775. else
  3776. cat << \SHAR_EOF > 'FileSelP.h'
  3777. /****************************************************************************
  3778.  
  3779.     FileSelectorP.h
  3780.  
  3781.     This file is the private definition file for the File Selector
  3782.     Widget.
  3783.  
  3784.  ****************************************************************************/
  3785.  
  3786. /*
  3787.  * Author:
  3788.  *     Brian Totty
  3789.  *     Department of Computer Science
  3790.  *     University Of Illinois at Urbana-Champaign
  3791.  *    1304 West Springfield Avenue
  3792.  *     Urbana, IL 61801
  3793.  * 
  3794.  *     totty@cs.uiuc.edu
  3795.  *     
  3796.  */ 
  3797.  
  3798. #ifndef    _FILESELECTORP_H_
  3799. #define _FILESELECTORP_H_
  3800.  
  3801. #include "DirMgr.h"
  3802.  
  3803. #include <X11/Xaw/Cardinals.h>
  3804. #include <X11/CoreP.h>
  3805. #include <X11/Core.h>
  3806.  
  3807. /*---------------------------------------------------------------------------*
  3808.  
  3809.                             C O N S T A N T S
  3810.  
  3811.  *---------------------------------------------------------------------------*/
  3812.  
  3813. #define    FS_DIR_STRING_SIZE    512
  3814.  
  3815. /* The following indices are used to find the appropriate widget
  3816.    data from the arrays that the data items are stored in.        */
  3817.  
  3818. #define    FS_I_TITLE        0    /* Title Index */
  3819. #define    FS_I_CUR_DIR_TEXT    1    /* Current Directory Label Index */
  3820. #define    FS_I_PATH_LIST_TITLE    2    /* Path From Root List Title Index */
  3821. #define    FS_I_FILE_LIST_TITLE    3    /* File List Title Index */
  3822. #define    FS_I_PATH_LIST        4    /* Path From Root List Index */
  3823. #define    FS_I_FILE_LIST        5    /* File List Index */
  3824. #define    FS_I_OK_BUTTON        6    /* OK Button Index */
  3825. #define    FS_I_CANCEL_BUTTON    7    /* Cancel Button Index */
  3826. #define    FS_I_UP_BUTTON        8    /* Go Up Directory Button */
  3827. #define    FS_I_GOTO_BUTTON    9    /* Go To Directory Button */
  3828. #define    FS_I_CUR_FILE_TEXT    10    /* Filename Text Line */
  3829. #define    FS_I_SELECT_BUTTON    11    /* Select Filename Button */
  3830.  
  3831. #define    FS_NUM_CHILDREN        12    /* Count Of Above Indices */
  3832.  
  3833. /*---------------------------------------------------------------------------*
  3834.  
  3835.       S T R U C T U R E   &   W I D G E T    A C C E S S    M A C R O S
  3836.  
  3837.  *---------------------------------------------------------------------------*/
  3838.  
  3839. #define    BoxX(b)            ((b)->x)
  3840. #define    BoxY(b)            ((b)->y)
  3841. #define    BoxW(b)            ((b)->w)
  3842. #define    BoxH(b)            ((b)->h)
  3843.  
  3844. #define    ChildInfoCoords(ci)    (&((ci)->coords))
  3845. #define    ChildInfoWidget(ci)    ((ci)->widget)
  3846.  
  3847. #define    FSCorePart(w)        (&((w)->core))
  3848. #define    FSCompositePart(w)    (&((w)->composite))
  3849. #define    FSMyPart(w)        (&((w)->fileSelector))
  3850.  
  3851. #define    FSDirMgr(w)        (FSMyPart(w)->dir_mgr)
  3852. #define    FSChildren(w)        (FSMyPart(w)->children)
  3853. #define    FSCurrentDirectory(w)    (FSMyPart(w)->current_directory)
  3854. #define    FSCurrentFile(w)    (FSMyPart(w)->current_file)
  3855. #define    FSTitle(w)        (FSMyPart(w)->title)
  3856. #define    FSPathList(w)        (FSMyPart(w)->path_list)
  3857. #define    FSFileList(w)        (FSMyPart(w)->file_list)
  3858. #define    FSSortMode(w)        (FSMyPart(w)->sort_mode)
  3859. #define    FSPattern(w)        (FSMyPart(w)->pattern)
  3860. #define    FSPathListCount(w)    (FSMyPart(w)->path_list_count)
  3861. #define    FSFileListCount(w)    (FSMyPart(w)->file_list_count)
  3862. #define    FSOkCallbacks(w)    (FSMyPart(w)->ok_button_callbacks)
  3863. #define    FSCancelCallbacks(w)    (FSMyPart(w)->cancel_button_callbacks)
  3864. #define    FSSelChangeCallbacks(w)    (FSMyPart(w)->sel_change_callbacks)
  3865. #define    FSShowOkButton(w)    (FSMyPart(w)->show_ok_button)
  3866. #define    FSShowCancelButton(w)    (FSMyPart(w)->show_cancel_button)
  3867. #define    FSFileSelected(w)    (FSMyPart(w)->file_selected)
  3868. #define    FSBusyCursor(w)        (FSMyPart(w)->busy_cursor)
  3869. #define    FSHandCursor(w)        (FSMyPart(w)->hand_cursor)
  3870. #define    FSFlagLinks(w)        (FSMyPart(w)->flag_links)
  3871. #define    FSCheckExistence(w)    (FSMyPart(w)->check_existence)
  3872.  
  3873. #define    FSNthChildInfo(w,n)    (&(FSChildren(w)[n]))
  3874.  
  3875. #define    FSNthCoords(w,n)    (ChildInfoCoords(FSNthChildInfo(w,n)))
  3876. #define    FSNthWidget(w,n)    (ChildInfoWidget(FSNthChildInfo(w,n)))
  3877.  
  3878. #define    CoreWidth(w)        ((w)->core.width)
  3879. #define    CoreHeight(w)        ((w)->core.height)
  3880. #define    CoreBorderWidth(w)    ((w)->core.border_width)
  3881.  
  3882. /*---------------------------------------------------------------------------*
  3883.  
  3884.                       T Y P E    D E F I N I T I O N S
  3885.  
  3886.  *---------------------------------------------------------------------------*/
  3887.  
  3888. typedef struct
  3889. {
  3890.     int x;
  3891.     int y;
  3892.     int w;
  3893.     int h;
  3894. } BOX;    
  3895.  
  3896. /*---------------------------------------------------------------------------*
  3897.  
  3898.            W I D G E T    S T R U C T U R E    D E F I N I T I O N
  3899.  
  3900.  *---------------------------------------------------------------------------*/
  3901.  
  3902. typedef struct
  3903. {
  3904.     BOX                coords;
  3905.     Widget                widget;
  3906. } XfwfFileSelectorChildInfo;
  3907.  
  3908. typedef struct
  3909. {
  3910.     XtCallbackList            ok_button_callbacks;
  3911.     XtCallbackList            cancel_button_callbacks;
  3912.     XtCallbackList            sel_change_callbacks;
  3913.     Boolean                show_ok_button;
  3914.     Boolean                show_cancel_button;
  3915.     Boolean                file_selected;
  3916.     Boolean                flag_links;
  3917.     Boolean                check_existence;
  3918.     char                *title;
  3919.     int                sort_mode;
  3920.     char                *pattern;
  3921.     DIRECTORY_MGR            *dir_mgr;
  3922.     XfwfFileSelectorChildInfo    children[FS_NUM_CHILDREN];
  3923.     char                *current_directory;
  3924.     char                *current_file;
  3925.     char                **path_list;
  3926.     char                **file_list;
  3927.     int                path_list_count;
  3928.     int                file_list_count;
  3929.     Cursor                busy_cursor;
  3930.     Cursor                hand_cursor;
  3931. } XfwfFileSelectorPart;
  3932.  
  3933. typedef struct _XfwfFileSelectorClassPart
  3934. {
  3935.     int    empty;
  3936. } XfwfFileSelectorClassPart;
  3937.  
  3938.  
  3939.  
  3940. typedef struct _XfwfFileSelectorClassRec
  3941. {
  3942.     CoreClassPart            core_class;
  3943.     CompositeClassPart        composite_class;
  3944.     XfwfFileSelectorClassPart    fileSelector_class;
  3945. } XfwfFileSelectorClassRec;
  3946.  
  3947.     /* This Is What A Widget Instance Points To */
  3948.  
  3949. typedef struct _XfwfFileSelectorRec
  3950. {
  3951.     CorePart            core;
  3952.     CompositePart            composite;
  3953.     XfwfFileSelectorPart        fileSelector;
  3954. } XfwfFileSelectorRec;
  3955.  
  3956. extern XfwfFileSelectorClassRec xfwfFileSelectorClassRec;
  3957.  
  3958. #endif
  3959. SHAR_EOF
  3960. fi
  3961. if test -f 'Makefile.1'
  3962. then
  3963.     echo shar: "will not over-write existing file 'Makefile.1'"
  3964. else
  3965. cat << \SHAR_EOF > 'Makefile.1'
  3966. CFLAGS= -g -I/usr/local/X11R4/include  -I/usr/local/X11R4/include  -DXMGT_HFS 
  3967.  
  3968.             SRCS = help.c  build.c comment.c doit.c edit.c \
  3969.               mgt.c parse.c play.c tree.c Board.c x11.4.c xutil.c \
  3970.               advunix.c goserver.c DirMgr.c Directory.c \
  3971.           FileSel.c MultiList.c RegExp.c ScrList.c
  3972.  
  3973.             OBJS = help.o build.o comment.o doit.o edit.o \
  3974.               mgt.o parse.o play.o tree.o Board.o x11.4.o xutil.o \
  3975.               advunix.o goserver.o DirMgr.o Directory.o \
  3976.           FileSel.o MultiList.o RegExp.o ScrList.o
  3977.  
  3978. xmgt: $(OBJS)
  3979.     rm -f xmgt
  3980.     cc -o xmgt $(OBJS) -lXaw -lXmu -lXt -lXext -lX11 -lm
  3981.  
  3982. SHAR_EOF
  3983. fi
  3984. if test -f 'MultiList.c'
  3985. then
  3986.     echo shar: "will not over-write existing file 'MultiList.c'"
  3987. else
  3988. cat << \SHAR_EOF > 'MultiList.c'
  3989. /****************************************************************************
  3990.  
  3991.     MultiList.c
  3992.  
  3993.     This file contains the implementation of the Picasso List
  3994.     widget.  Its functionality is intended to be similar to
  3995.     The Athena List widget, with some extra features added.
  3996.  
  3997.     This code is loosely based on the Athena List source which
  3998.     is why the MIT copyright notice appears below.
  3999.  
  4000.     The code was changed substantially in V3.4 to change the
  4001.     action/callback interface which was unnecessarily ugly.  Code
  4002.     using some features of the old interface may need to be changed.
  4003.     Hope the changes don't make people's lives too miserable.
  4004.  
  4005.  ****************************************************************************/
  4006.  
  4007. /*
  4008.  * Author:
  4009.  *     Brian Totty
  4010.  *     Department of Computer Science
  4011.  *     University Of Illinois at Urbana-Champaign
  4012.  *    1304 West Springfield Avenue
  4013.  *     Urbana, IL 61801
  4014.  * 
  4015.  *     totty@cs.uiuc.edu
  4016.  *     
  4017.  */ 
  4018.  
  4019. /*
  4020.  * Copyright 1989 Massachusetts Institute of Technology
  4021.  *
  4022.  * Permission to use, copy, modify, distribute, and sell this software and its
  4023.  * documentation for any purpose is hereby granted without fee, provided that
  4024.  * the above copyright notice appear in all copies and that both that
  4025.  * copyright notice and this permission notice appear in supporting
  4026.  * documentation, and that the name of M.I.T. not be used in advertising or
  4027.  * publicity pertaining to distribution of the software without specific,
  4028.  * written prior permission.  M.I.T. makes no representations about the
  4029.  * suitability of this software for any purpose.  It is provided "as is"
  4030.  * without express or implied warranty.
  4031.  *
  4032.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  4033.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  4034.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  4035.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  4036.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  4037.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  4038.  *
  4039.  * Original Athena Author:  Chris D. Peterson, MIT X Consortium
  4040.  */
  4041.  
  4042. #include <stdio.h>
  4043. #include <ctype.h>
  4044.  
  4045. #include <X11/IntrinsicP.h>
  4046. #include <X11/StringDefs.h>
  4047.  
  4048. #include "MultiListP.h"
  4049.  
  4050. /*===========================================================================*
  4051.  
  4052.           D E C L A R A T I O N S    A N D    D E F I N I T I O N S
  4053.  
  4054.  *===========================================================================*/
  4055.  
  4056. Pixmap XmuCreateStippledPixmap();
  4057. extern void XawInitializeWidgetSet();
  4058.  
  4059. #define    SUPERCLASS    &(simpleClassRec)
  4060.  
  4061. #define    FontAscent(f)    ((f)->max_bounds.ascent)
  4062. #define    FontDescent(f)    ((f)->max_bounds.descent)
  4063. #define    FontH(f)    (FontAscent(f) + FontDescent(f) + 2)
  4064. #define    FontW(f,s)    (XTextWidth(f,s,strlen(s)) + 1)
  4065. #define    FontMaxCharW(f)    ((f)->max_bounds.rbearing-(f)->min_bounds.lbearing+1)
  4066.  
  4067. #ifndef abs
  4068. #define abs(a)            ((a) < 0 ? -(a) : (a))
  4069. #endif
  4070.  
  4071. #define max(a,b)        ((a) > (b) ? (a) : (b))
  4072. #define min(a,b)        ((a) < (b) ? (a) : (b))
  4073. #define XtStrlen(s)        ((s) ? strlen(s) : 0)
  4074.  
  4075. #define    TypeAlloc(t,n)        (t *)malloc(sizeof(t) * n)
  4076. #define    StrCopy(s)        strcpy(TypeAlloc(char,strlen(s)+1),s)
  4077. #define    StrCopyRetLength(s,lp)    strcpy(TypeAlloc(char,(*lp=(strlen(s)+1))),s)
  4078.  
  4079. #define CoreFieldOffset(f)    XtOffset(Widget,core.f)
  4080. #define    SimpleFieldOffset(f)    XtOffset(XfwfMultiListWidget,simple.f)
  4081. #define MultiListFieldOffset(f)    XtOffset(XfwfMultiListWidget,multiList.f)
  4082.  
  4083. /*===========================================================================*
  4084.  
  4085.         I N T E R N A L    P R O C E D U R E    D E C L A R A T I O N S
  4086.  
  4087.  *===========================================================================*/
  4088.  
  4089. #if (!NeedFunctionPrototypes)
  4090.  
  4091. static void            Initialize();
  4092. static void            Redisplay();
  4093. static XtGeometryResult        PreferredGeometry();
  4094. static void            Resize();
  4095. static Boolean            SetValues();
  4096.  
  4097. static void            DestroyOldData();
  4098. static void            InitializeNewData();
  4099. static void            CreateNewGCs();
  4100.  
  4101. static void            RecalcCoords();
  4102. static void            NegotiateSizeChange();
  4103. static Boolean            Layout();
  4104.  
  4105. static void            RedrawAll();
  4106. static void            RedrawItem();
  4107. static void            RedrawRowColumn();
  4108.  
  4109. static void            PixelToRowColumn();
  4110. static void            RowColumnToPixels();
  4111. static Boolean            RowColumnToItem();
  4112. static Boolean            ItemToRowColumn();
  4113.  
  4114. static void            Select();
  4115. static void            Unselect();
  4116. static void            Toggle();
  4117. static void            Extend();
  4118. static void            Notify();
  4119.  
  4120. #else
  4121.  
  4122. static void        Initialize(Widget request, Widget new);
  4123. static void         Redisplay(XfwfMultiListWidget mlw,
  4124.                 XEvent *event, Region rectangle_union);
  4125. static XtGeometryResult PreferredGeometry(XfwfMultiListWidget mlw,
  4126.                 XtWidgetGeometry *parent_idea,
  4127.                 XtWidgetGeometry *our_idea);
  4128. static void        Resize(XfwfMultiListWidget mlw);
  4129. static Boolean        SetValues(XfwfMultiListWidget cpl,
  4130.                 XfwfMultiListWidget rpl,
  4131.             XfwfMultiListWidget npl);
  4132. static void        DestroyOldData(XfwfMultiListWidget mlw);
  4133. static void        InitializeNewData(XfwfMultiListWidget mlw);
  4134. static void        CreateNewGCs(XfwfMultiListWidget mlw);
  4135. static void        RecalcCoords(XfwfMultiListWidget mlw,
  4136.                 int width_changeable,
  4137.                 int height_changeable);
  4138. static void        NegotiateSizeChange(XfwfMultiListWidget mlw,
  4139.                 int width, int height);
  4140. static Boolean        Layout(XfwfMultiListWidget mlw,
  4141.                 int w_changeable, int h_changeable,
  4142.                 Dimension *w_ptr, Dimension *h_ptr);
  4143. static void        RedrawAll(XfwfMultiListWidget mlw);
  4144. static void        RedrawItem(XfwfMultiListWidget mlw, int item_index);
  4145. static void        RedrawRowColumn(XfwfMultiListWidget mlw,
  4146.                 int row, int column);
  4147. static void        PixelToRowColumn(XfwfMultiListWidget mlw,
  4148.                 int x, int y, int *row_ptr, int *column_ptr);
  4149. static void        RowColumnToPixels(XfwfMultiListWidget mlw,
  4150.                 int row, int col, int *x_ptr, int *y_ptr,
  4151.                 int *w_ptr, int *h_ptr);
  4152. static Boolean        RowColumnToItem(XfwfMultiListWidget mlw,
  4153.                 int row, int column, int *item_ptr);
  4154. static Boolean        ItemToRowColumn(XfwfMultiListWidget mlw,
  4155.                 int item_index, int *row_ptr, int *column_ptr);
  4156. static void        Select(XfwfMultiListWidget mlw, XEvent *event,
  4157.                 String *params, Cardinal *num_params);
  4158. static void        Unselect(XfwfMultiListWidget mlw, XEvent *event,
  4159.                 String *params, Cardinal *num_params);
  4160. static void        Toggle(XfwfMultiListWidget mlw, XEvent *event,
  4161.                 String *params, Cardinal *num_params);
  4162. static void        Extend(XfwfMultiListWidget mlw, XEvent *event,
  4163.                 String *params, Cardinal *num_params);
  4164. static void        Notify(XfwfMultiListWidget mlw, XEvent *event,
  4165.                 String *params, Cardinal *num_params);
  4166. #endif
  4167.  
  4168. /*===========================================================================*
  4169.  
  4170.               R E S O U R C E    I N I T I A L I Z A T I O N
  4171.  
  4172.  *===========================================================================*/
  4173.  
  4174. static XtResource resources[] =
  4175. {
  4176.     {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  4177.         CoreFieldOffset(width), XtRString, "0"},
  4178.     {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  4179.         CoreFieldOffset(height), XtRString, "0"},
  4180.     {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
  4181.         CoreFieldOffset(background_pixel),XtRString,"XtDefaultBackground"},
  4182.  
  4183.     {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
  4184.         SimpleFieldOffset(cursor), XtRString, "left_ptr"},
  4185.  
  4186.     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  4187.         MultiListFieldOffset(foreground), XtRString,"XtDefaultForeground"},
  4188.     {XtNhighlightForeground, XtCHForeground, XtRPixel, sizeof(Pixel),
  4189.         MultiListFieldOffset(highlight_fg), XtRString, "XtDefaultBackground"},
  4190.     {XtNhighlightBackground, XtCHBackground, XtRPixel, sizeof(Pixel),
  4191.         MultiListFieldOffset(highlight_bg), XtRString, "XtDefaultForeground"},
  4192.     {XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
  4193.         MultiListFieldOffset(column_space), XtRImmediate, (caddr_t)8},
  4194.     {XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
  4195.         MultiListFieldOffset(row_space), XtRImmediate, (caddr_t)0},
  4196.     {XtNdefaultColumns, XtCColumns, XtRInt,  sizeof(int),
  4197.         MultiListFieldOffset(default_cols), XtRImmediate, (caddr_t)1},
  4198.     {XtNforceColumns, XtCColumns, XtRBoolean, sizeof(Boolean),
  4199.         MultiListFieldOffset(force_cols), XtRString, (caddr_t) "False"},
  4200.     {XtNpasteBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
  4201.         MultiListFieldOffset(paste), XtRString, (caddr_t) "False"},
  4202.     {XtNverticalList, XtCBoolean, XtRBoolean,  sizeof(Boolean),
  4203.         MultiListFieldOffset(row_major), XtRString, (caddr_t) "False"},
  4204.     {XtNlongest, XtCLongest, XtRInt,  sizeof(int),
  4205.         MultiListFieldOffset(longest), XtRImmediate, (caddr_t)0},
  4206.     {XtNnumberStrings, XtCNumberStrings, XtRInt,  sizeof(int),
  4207.         MultiListFieldOffset(nitems), XtRImmediate, (caddr_t)0},
  4208.     {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  4209.         MultiListFieldOffset(font),XtRString, "XtDefaultFont"},
  4210.     {XtNlist, XtCList, XtRPointer, sizeof(char **),
  4211.         MultiListFieldOffset(list), XtRString, NULL},
  4212.     {XtNsensitiveArray, XtCList, XtRPointer, sizeof(Boolean *),
  4213.         MultiListFieldOffset(sensitive_array), XtRString, NULL},
  4214.     {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
  4215.         MultiListFieldOffset(callback), XtRCallback, NULL},
  4216.     {XtNmaxSelectable, XtCValue, XtRInt, sizeof(int),
  4217.         MultiListFieldOffset(max_selectable), XtRImmediate, (caddr_t) 1},
  4218.  
  4219.     {XtNshadeSurplus, XtCBoolean, XtRBoolean, sizeof(Boolean),
  4220.         MultiListFieldOffset(shade_surplus), XtRString, "True"},
  4221.  
  4222.     {XtNcolumnWidth, XtCValue, XtRDimension, sizeof(Dimension),
  4223.         MultiListFieldOffset(col_width), XtRImmediate, (caddr_t)0},
  4224.     {XtNrowHeight, XtCValue, XtRDimension, sizeof(Dimension),
  4225.         MultiListFieldOffset(row_height), XtRImmediate, (caddr_t)0},
  4226. };
  4227.  
  4228. /*===========================================================================*
  4229.  
  4230.         A C T I O N    A N D    T R A N S L A T I O N    T A B L E S
  4231.  
  4232.  *===========================================================================*/
  4233.  
  4234.  
  4235. static char defaultTranslations[] =
  4236. "    Shift <Btn1Down>:            Toggle()\n\
  4237.     Ctrl <Btn1Down>:            Unselect()\n\
  4238.     <Btn1Down>:                Select()\n\
  4239.     Button1 <Btn1Motion>:            Extend()\n\
  4240.     <Btn1Up>:                Notify()";
  4241.  
  4242. static XtActionsRec actions[] =
  4243. {
  4244.     {"Select",                (XtActionProc)Select},
  4245.     {"Unselect",                (XtActionProc)Unselect},
  4246.     {"Toggle",                (XtActionProc)Toggle},
  4247.     {"Extend",                (XtActionProc)Extend},
  4248.     {"Notify",                (XtActionProc)Notify},
  4249.     {NULL,                    (XtActionProc)NULL}
  4250. };
  4251.  
  4252. /*===========================================================================*
  4253.  
  4254.                     C L A S S    A L L O C A T I O N
  4255.  
  4256.  *===========================================================================*/
  4257.  
  4258. XfwfMultiListClassRec xfwfMultiListClassRec =
  4259. {
  4260.     {
  4261.         /* superclass        */    (WidgetClass)SUPERCLASS,
  4262.         /* class_name        */    "XfwfMultiList",
  4263.         /* widget_size        */    sizeof(XfwfMultiListRec),
  4264.         /* class_initialize    */    NULL,
  4265.         /* class_part_initialize*/    NULL,
  4266.         /* class_inited        */    FALSE,
  4267.         /* initialize        */    (XtInitProc)Initialize,
  4268.         /* initialize_hook    */    NULL,
  4269.         /* realize        */    XtInheritRealize,
  4270.         /* actions        */    actions,
  4271.         /* num_actions        */    XtNumber(actions),
  4272.         /* resources        */    resources,
  4273.         /* resource_count    */    XtNumber(resources),
  4274.         /* xrm_class        */    NULLQUARK,
  4275.         /* compress_motion    */    TRUE,
  4276.         /* compress_exposure    */    FALSE,
  4277.         /* compress_enterleave    */    TRUE,
  4278.         /* visible_interest    */    FALSE,
  4279.         /* destroy        */    NULL,
  4280.         /* resize        */    (XtWidgetProc)Resize,
  4281.         /* expose        */    (XtExposeProc)Redisplay,
  4282.         /* set_values        */    (XtSetValuesFunc)SetValues,
  4283.         /* set_values_hook    */    NULL,
  4284.         /* set_values_almost    */    XtInheritSetValuesAlmost,
  4285.         /* get_values_hook    */    NULL,
  4286.         /* accept_focus        */    NULL,
  4287.         /* version        */    XtVersion,
  4288.         /* callback_private    */    NULL,
  4289.         /* tm_table        */    defaultTranslations,
  4290.         /* query_geometry       */    (XtGeometryHandler)
  4291.                             PreferredGeometry,
  4292.         /* display_accelerator  */    XtInheritDisplayAccelerator,
  4293.         /* extension            */    NULL
  4294.     }, /* Core Part */
  4295.     {
  4296.         /* change_sensitive     */    XtInheritChangeSensitive
  4297.     }
  4298. };
  4299.  
  4300. WidgetClass xfwfMultiListWidgetClass = (WidgetClass)&xfwfMultiListClassRec;
  4301.  
  4302. /*===========================================================================*
  4303.  
  4304.                        T O O L K I T    M E T H O D S
  4305.  
  4306.  *===========================================================================*/
  4307.  
  4308. /*---------------------------------------------------------------------------*
  4309.  
  4310.     Initialize()
  4311.  
  4312.     This procedure is called by the X toolkit to initialize
  4313.     the widget instance.  The hook to this routine is in the
  4314.     initialize part of the core part of the class.
  4315.  
  4316.  *---------------------------------------------------------------------------*/
  4317.  
  4318. /* ARGSUSED */
  4319. static void Initialize(request,new)
  4320. Widget request,new;
  4321. {
  4322.     XfwfMultiListWidget mlw;
  4323.  
  4324.     mlw = (XfwfMultiListWidget)new;
  4325.     CreateNewGCs(mlw);
  4326.     InitializeNewData(mlw);
  4327.     RecalcCoords(mlw,(MultiListWidth(mlw) == 0),
  4328.              (MultiListHeight(mlw) == 0));
  4329. } /* Initialize */
  4330.  
  4331.  
  4332. /*---------------------------------------------------------------------------*
  4333.  
  4334.     Redisplay(mlw,event,rectangle_union)
  4335.  
  4336.     This routine redraws the MultiList widget <mlw> based on the exposure
  4337.     region requested in <event>.
  4338.  
  4339.  *---------------------------------------------------------------------------*/
  4340.  
  4341. /* ARGSUSED */
  4342. static void Redisplay(mlw,event,rectangle_union)
  4343. XfwfMultiListWidget mlw;
  4344. XEvent *event;
  4345. Region rectangle_union;
  4346. {
  4347.     GC shade_gc;
  4348.     int i,x1,y1,w,h,x2,y2,row,col,ul_row,ul_col,lr_row,lr_col;
  4349.  
  4350.     if (MultiListShadeSurplus(mlw))
  4351.         shade_gc = MultiListGrayGC(mlw);
  4352.         else
  4353.         shade_gc = MultiListEraseGC(mlw);
  4354.     if (event == NULL)
  4355.     {
  4356.         XFillRectangle(XtDisplay(mlw),XtWindow(mlw),shade_gc,0,0,
  4357.                    MultiListWidth(mlw),MultiListHeight(mlw));
  4358.         for (i = 0; i < MultiListNumItems(mlw); i++) RedrawItem(mlw,i);
  4359.     }
  4360.         else
  4361.     {
  4362.         x1 = event->xexpose.x;
  4363.         y1 = event->xexpose.y;
  4364.         w = event->xexpose.width;
  4365.         h = event->xexpose.height;
  4366.         x2 = x1 + w;
  4367.         y2 = y1 + h;
  4368.         XFillRectangle(XtDisplay(mlw),XtWindow(mlw),
  4369.                    shade_gc,x1,y1,w,h);
  4370.         PixelToRowColumn(mlw,x1,y1,&ul_row,&ul_col);
  4371.         PixelToRowColumn(mlw,x2,y2,&lr_row,&lr_col);
  4372.         lr_row = min(lr_row,MultiListNumRows(mlw) - 1);
  4373.         lr_col = min(lr_col,MultiListNumCols(mlw) - 1);
  4374.         for (col = ul_col; col <= lr_col; col++)
  4375.         {
  4376.             for (row = ul_row; row <= lr_row; row++)
  4377.             {
  4378.                 RedrawRowColumn(mlw,row,col);
  4379.             }
  4380.         }
  4381.     }
  4382. } /* End Redisplay */
  4383.  
  4384.  
  4385. /*---------------------------------------------------------------------------*
  4386.  
  4387.     PreferredGeometry(mlw,parent_idea,our_idea)
  4388.  
  4389.     This routine is called by the parent to tell us about the
  4390.     parent's idea of our width and/or height.  We then suggest
  4391.     our preference through <our_idea> and return the information
  4392.     to the parent.
  4393.  
  4394.  *---------------------------------------------------------------------------*/
  4395.  
  4396. static XtGeometryResult PreferredGeometry(mlw,parent_idea,our_idea)
  4397. XfwfMultiListWidget mlw;
  4398. XtWidgetGeometry *parent_idea,*our_idea;
  4399. {
  4400.     Dimension nw,nh;
  4401.     Boolean parent_wants_w,parent_wants_h,we_changed_size;
  4402.     
  4403.     parent_wants_w = (parent_idea->request_mode) & CWWidth;
  4404.     parent_wants_h = (parent_idea->request_mode) & CWHeight;
  4405.  
  4406.     if (parent_wants_w)
  4407.         nw = parent_idea->width;
  4408.         else
  4409.         nw = MultiListWidth(mlw);
  4410.  
  4411.     if (parent_wants_h)
  4412.         nh = parent_idea->height;
  4413.         else
  4414.         nh = MultiListHeight(mlw);
  4415.  
  4416.     our_idea->request_mode = 0;
  4417.     if (!parent_wants_w && !parent_wants_h) return(XtGeometryYes);
  4418.  
  4419.     we_changed_size = Layout(mlw,!parent_wants_w,!parent_wants_h,&nw,&nh);
  4420.     our_idea->request_mode |= (CWWidth | CWHeight);
  4421.     our_idea->width = nw;
  4422.     our_idea->height = nh;
  4423.  
  4424.     if (we_changed_size)
  4425.         return(XtGeometryAlmost);
  4426.         else
  4427.         return(XtGeometryYes);
  4428. } /* End PreferredGeometry */
  4429.  
  4430.  
  4431. /*---------------------------------------------------------------------------*
  4432.  
  4433.     Resize(mlw)
  4434.  
  4435.     This function is called when the widget is being resized.  It
  4436.     recalculates the layout of the widget.
  4437.  
  4438.  *---------------------------------------------------------------------------*/
  4439.  
  4440. static void Resize(mlw)
  4441. XfwfMultiListWidget mlw;
  4442. {
  4443.     Dimension width,height;
  4444.  
  4445.     width = MultiListWidth(mlw);
  4446.     height = MultiListHeight(mlw);
  4447.     Layout(mlw,False,False,&width,&height);
  4448. } /* End Resize */
  4449.  
  4450.  
  4451. /*---------------------------------------------------------------------------*
  4452.  
  4453.     SetValues(cpl,rpl,npl)
  4454.  
  4455.     This routine is called when the user is changing resources.  <cpl>
  4456.     is the current widget before the user's changes have been instituted.
  4457.     <rpl> includes the original changes as requested by the user.  <npl>
  4458.     is the new resulting widget with the requested changes and with all
  4459.     superclass changes already made.
  4460.  
  4461.  *---------------------------------------------------------------------------*/
  4462.  
  4463. static Boolean SetValues(cpl,rpl,npl)
  4464. XfwfMultiListWidget cpl,rpl,npl;
  4465. {
  4466.     Boolean redraw,recalc;
  4467.  
  4468.     redraw = False;
  4469.     recalc = False;
  4470.  
  4471.         /* Graphic Context Changes */
  4472.  
  4473.     if ((MultiListFG(cpl) != MultiListFG(npl)) ||
  4474.         (MultiListBG(cpl) != MultiListBG(npl)) ||
  4475.         (MultiListHighlightFG(cpl) != MultiListHighlightFG(npl)) ||
  4476.         (MultiListHighlightBG(cpl) != MultiListHighlightBG(npl)) ||
  4477.         (MultiListFont(cpl) != MultiListFont(npl)))
  4478.     {
  4479.         XtDestroyGC(MultiListEraseGC(cpl));
  4480.         XtDestroyGC(MultiListDrawGC(cpl));
  4481.         XtDestroyGC(MultiListHighlightForeGC(cpl));
  4482.         XtDestroyGC(MultiListHighlightBackGC(cpl));
  4483.         XtDestroyGC(MultiListGrayGC(cpl));
  4484.         CreateNewGCs(npl);
  4485.         redraw = True;
  4486.     }
  4487.  
  4488.         /* Changes That Require Data Initialization */
  4489.  
  4490.     if ((MultiListList(cpl) != MultiListList(npl)) ||
  4491.         (MultiListSensitiveArray(cpl) != MultiListSensitiveArray(npl)) ||
  4492.         (MultiListSensitive(cpl) != MultiListSensitive(npl)) ||
  4493.         (MultiListAncesSensitive(cpl) != MultiListAncesSensitive(npl)) ||
  4494.         (MultiListNumItems(cpl) != MultiListNumItems(npl)) ||
  4495.         (MultiListMaxSelectable(cpl) != MultiListMaxSelectable(npl)))
  4496.     {
  4497.         DestroyOldData(cpl);
  4498.         InitializeNewData(npl);
  4499.         recalc = True;
  4500.         redraw = True;
  4501.     }
  4502.  
  4503.         /* Changes That Require Recalculating Coordinates */
  4504.  
  4505.     if ((MultiListWidth(cpl) != MultiListWidth(npl)) ||
  4506.         (MultiListHeight(cpl) != MultiListHeight(npl)) ||
  4507.         (MultiListColumnSpace(cpl) != MultiListColumnSpace(npl)) ||
  4508.         (MultiListRowSpace(cpl) != MultiListRowSpace(npl)) ||
  4509.         (MultiListDefaultCols(cpl) != MultiListDefaultCols(npl)) ||
  4510.         ((MultiListForceCols(cpl) != MultiListForceCols(npl)) &&
  4511.          (MultiListNumCols(cpl) != MultiListNumCols(npl))) ||
  4512.         (MultiListRowMajor(cpl) != MultiListRowMajor(npl)) ||
  4513.         (MultiListFont(cpl) != MultiListFont(npl)) ||
  4514.         (MultiListLongest(cpl) != MultiListLongest(npl)))
  4515.     {
  4516.         recalc = True;
  4517.         redraw = True;
  4518.     }
  4519.  
  4520.     if (MultiListColWidth(cpl) != MultiListColWidth(npl))
  4521.     {
  4522.         XtWarning("columnWidth Resource Is Read-Only");
  4523.         MultiListColWidth(npl) = MultiListColWidth(cpl);
  4524.     }
  4525.     if (MultiListRowHeight(cpl) != MultiListRowHeight(npl))
  4526.     {
  4527.         XtWarning("rowHeight Resource Is Read-Only");
  4528.         MultiListRowHeight(npl) = MultiListRowHeight(cpl);
  4529.     }
  4530.  
  4531.     if (recalc)
  4532.     {
  4533.         RecalcCoords(npl,!MultiListWidth(npl),!MultiListHeight(npl));
  4534.     }
  4535.     
  4536.     if (!XtIsRealized((Widget)cpl))
  4537.         return(False);
  4538.         else
  4539.         return(redraw);
  4540. } /* End SetValues */
  4541.  
  4542. /*===========================================================================*
  4543.  
  4544.                   D A T A    I N I T I A L I Z A T I O N
  4545.  
  4546.  *===========================================================================*/
  4547.  
  4548. /*---------------------------------------------------------------------------*
  4549.  
  4550.     DestroyOldData(mlw)
  4551.  
  4552.     This routine frees the internal list item array and sets the
  4553.     item count to 0.  This is normally done immediately before
  4554.     calling InitializeNewData() to rebuild the internal item
  4555.     array from new user specified arrays.
  4556.  
  4557.  *---------------------------------------------------------------------------*/
  4558.  
  4559. static void DestroyOldData(mlw)
  4560. XfwfMultiListWidget mlw;
  4561. {
  4562.     int i;
  4563.  
  4564.     if (MultiListItemArray(mlw) != NULL)    /* Free Old List */
  4565.     {
  4566.         for (i = 0; i < MultiListNumItems(mlw); i++)
  4567.         {
  4568.             free(MultiListItemString(MultiListNthItem(mlw,i)));
  4569.         }
  4570.         free(MultiListItemArray(mlw));
  4571.     }
  4572.     if (MultiListSelArray(mlw) != NULL) free(MultiListSelArray(mlw));
  4573.     MultiListSelArray(mlw) = NULL;
  4574.     MultiListNumSelected(mlw) = 0;
  4575.     MultiListItemArray(mlw) = NULL;
  4576.     MultiListNumItems(mlw) = 0;
  4577. } /* End DestroyOldData */
  4578.  
  4579.  
  4580. /*---------------------------------------------------------------------------*
  4581.  
  4582.     InitializeNewData(mlw)
  4583.  
  4584.     This routine takes a MultiList widget <mlw> and builds up new
  4585.     data item tables based on the string list and the sensitivity array.
  4586.     All previous data should have already been freed.  If the number
  4587.     of items is 0, they will be counted, so the array must be NULL
  4588.     terminated.  If the list of strings is NULL, this is treated as
  4589.     a list of 0 elements.  If the sensitivity array is NULL, all
  4590.     items are treated as sensitive.
  4591.  
  4592.     When this routine is done, the string list and sensitivity array
  4593.     fields will all be set to NULL, and the widget will not reference
  4594.     them again.
  4595.  
  4596.  *---------------------------------------------------------------------------*/
  4597.  
  4598. static void InitializeNewData(mlw)
  4599. XfwfMultiListWidget mlw;
  4600. {
  4601.     int i;
  4602.     XfwfMultiListItem *item;
  4603.     String *string_array;
  4604.  
  4605.     string_array = MultiListList(mlw);
  4606.     if (MultiListNumItems(mlw) == 0)        /* Count Elements */
  4607.     {
  4608.         if (MultiListList(mlw) == NULL)    /* No elements */
  4609.         {
  4610.             MultiListNumItems(mlw) = 0;
  4611.         }
  4612.             else
  4613.         {
  4614.             for (i = 0; string_array[i] != NULL; i++);
  4615.             MultiListNumItems(mlw) = i;
  4616.         }
  4617.     }
  4618.     if (MultiListNumItems(mlw) == 0)        /* No Items */
  4619.     {
  4620.         MultiListItemArray(mlw) = NULL;
  4621.     }
  4622.         else
  4623.     {
  4624.         MultiListItemArray(mlw) =
  4625.             TypeAlloc(XfwfMultiListItem,MultiListNumItems(mlw));
  4626.         for (i = 0; i < MultiListNumItems(mlw); i++)
  4627.         {
  4628.             item = MultiListNthItem(mlw,i);
  4629.             if (MultiListSensitiveArray(mlw) == NULL ||
  4630.                 (MultiListSensitiveArray(mlw)[i] == True))
  4631.             {
  4632.                 MultiListItemSensitive(item) = True;
  4633.             }
  4634.                 else
  4635.             {
  4636.                 MultiListItemSensitive(item) = False;
  4637.             }
  4638.             MultiListItemString(item) = StrCopy(string_array[i]);
  4639.             MultiListItemHighlighted(item) = False;
  4640.         }
  4641.     }
  4642.     if (MultiListMaxSelectable(mlw) == 0)
  4643.     {
  4644.         MultiListSelArray(mlw) = NULL;
  4645.         MultiListNumSelected(mlw) = 0;
  4646.     }
  4647.         else
  4648.     {
  4649.         MultiListSelArray(mlw) =
  4650.             TypeAlloc(int,MultiListMaxSelectable(mlw));
  4651.         MultiListNumSelected(mlw) = 0;
  4652.     }
  4653.  
  4654.     MultiListList(mlw) = NULL;
  4655.     MultiListSensitiveArray(mlw) = NULL;
  4656. } /* End InitializeNewData */
  4657.         
  4658.  
  4659. /*---------------------------------------------------------------------------*
  4660.  
  4661.     CreateNewGCs(mlw)
  4662.  
  4663.     This routine takes a MultiList widget <mlw> and creates a new set of
  4664.     graphic contexts for the widget based on the colors, fonts, etc.
  4665.     in the widget.  Any previous GCs are assumed to have already been
  4666.     destroyed.
  4667.  
  4668.  *---------------------------------------------------------------------------*/
  4669.  
  4670. static void CreateNewGCs(mlw)
  4671. XfwfMultiListWidget mlw;
  4672. {
  4673.     XGCValues values;
  4674.     unsigned int attribs;
  4675.  
  4676.     attribs = GCForeground | GCBackground | GCFont;
  4677.     values.foreground = MultiListFG(mlw);
  4678.     values.background = MultiListBG(mlw);
  4679.     values.font = MultiListFont(mlw)->fid;
  4680.     MultiListDrawGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);
  4681.  
  4682.     values.foreground = MultiListBG(mlw);
  4683.     MultiListEraseGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);
  4684.  
  4685.     values.foreground = MultiListHighlightFG(mlw);
  4686.     values.background = MultiListHighlightBG(mlw);
  4687.     MultiListHighlightForeGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);
  4688.  
  4689.     values.foreground = MultiListHighlightBG(mlw);
  4690.     values.background = MultiListHighlightBG(mlw);
  4691.     MultiListHighlightBackGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);
  4692.  
  4693.     attribs |= GCTile | GCFillStyle;
  4694.     values.foreground = MultiListFG(mlw);
  4695.     values.background = MultiListBG(mlw);
  4696.     values.fill_style = FillTiled;
  4697.     values.tile = XmuCreateStippledPixmap(XtScreen(mlw),MultiListFG(mlw),
  4698.                           MultiListBG(mlw),MultiListDepth(mlw));
  4699.  
  4700.     MultiListGrayGC(mlw) = XtGetGC((Widget)mlw,attribs,&values);
  4701. } /* End CreateNewGCs */
  4702.  
  4703. /*===========================================================================*
  4704.  
  4705.         L A Y O U T    A N D    G E O M E T R Y    M A N A G E M E N T
  4706.  
  4707.  *===========================================================================*/
  4708.  
  4709. /*---------------------------------------------------------------------------*
  4710.  
  4711.         RecalcCoords(mlw,width_changeable,height_changeable)
  4712.  
  4713.     This routine takes a MultiList widget <mlw> and recalculates
  4714.     the coordinates, and item placement based on the current
  4715.     width, height, and list of items.  The <width_changeable> and
  4716.     <height_changeable> indicate if the width and/or height can
  4717.     be arbitrarily set.
  4718.  
  4719.     This routine requires that the internal list data be initialized.
  4720.  
  4721.  *---------------------------------------------------------------------------*/
  4722.  
  4723. static void RecalcCoords(mlw,width_changeable,height_changeable)
  4724. XfwfMultiListWidget mlw;
  4725. Boolean width_changeable,height_changeable;
  4726. {
  4727.     String str;
  4728.     Dimension width,height;
  4729.     register int i,text_width;
  4730.  
  4731.     width = MultiListWidth(mlw);
  4732.     height = MultiListHeight(mlw);
  4733.     if (MultiListNumItems(mlw) != 0 && MultiListLongest(mlw) == 0)
  4734.     {
  4735.         for (i = 0; i < MultiListNumItems(mlw); i++)
  4736.         {
  4737.             str = MultiListItemString(MultiListNthItem(mlw,i));
  4738.             text_width = FontW(MultiListFont(mlw),str);
  4739.             MultiListLongest(mlw) = max(MultiListLongest(mlw),
  4740.                             text_width);
  4741.         }
  4742.     }
  4743.     if (Layout(mlw,width_changeable,height_changeable,&width,&height))
  4744.     {
  4745.         NegotiateSizeChange(mlw,width,height);
  4746.     }
  4747. } /* End RecalcCoords */
  4748.  
  4749.  
  4750. /*---------------------------------------------------------------------------*
  4751.  
  4752.         NegotiateSizeChange(mlw,width,height)
  4753.  
  4754.     This routine tries to change the MultiList widget <mlw> to have the
  4755.     new size <width> by <height>.  A negotiation will takes place
  4756.     to try to change the size.  The resulting size is not necessarily
  4757.     the requested size.
  4758.  
  4759.  *---------------------------------------------------------------------------*/
  4760.  
  4761. static void NegotiateSizeChange(mlw,width,height)
  4762. XfwfMultiListWidget mlw;
  4763. Dimension width,height;
  4764. {
  4765.     int attempt_number;
  4766.     Boolean w_fixed,h_fixed;
  4767.     Dimension *w_ptr,*h_ptr;
  4768.     
  4769.     XtWidgetGeometry request,reply;
  4770.  
  4771.     request.request_mode = CWWidth | CWHeight;
  4772.     request.width = width;
  4773.     request.height = height;
  4774.     
  4775.     for (attempt_number = 1; attempt_number <= 3; attempt_number++)
  4776.     {
  4777.         switch (XtMakeGeometryRequest((Widget)mlw,&request,&reply))
  4778.         {
  4779.             case XtGeometryYes:
  4780.             case XtGeometryNo:
  4781.             return;
  4782.             case XtGeometryAlmost:
  4783.             switch (attempt_number)
  4784.             {
  4785.                 case 1:
  4786.                 w_fixed = (request.width != reply.width);
  4787.                 h_fixed = (request.height != reply.height);
  4788.                 w_ptr = &(reply.width);
  4789.                 h_ptr = &(reply.height);
  4790.                 Layout(mlw,!w_fixed,!h_fixed,w_ptr,h_ptr);
  4791.                 break;
  4792.                 case 2:
  4793.                 w_ptr = &(reply.width);
  4794.                 h_ptr = &(reply.height);
  4795.                 Layout(mlw,False,False,w_ptr,h_ptr);
  4796.                 break;
  4797.                 case 3:
  4798.                 return;
  4799.             }
  4800.             break;
  4801.             default:
  4802.             XtAppWarning(XtWidgetToApplicationContext((Widget)mlw),
  4803.                 "MultiList Widget: Unknown geometry return.");
  4804.             break;
  4805.         }
  4806.         request = reply;
  4807.     }
  4808. } /* End NegotiateSizeChange */
  4809.  
  4810.  
  4811. /*---------------------------------------------------------------------------*
  4812.  
  4813.     Boolean Layout(mlw,w_changeable,h_changeable,w_ptr,h_ptr)
  4814.  
  4815.     This routine tries to generate a layout for the MultiList widget
  4816.     <mlw>.  The Layout routine is free to arbitrarily set the width
  4817.     or height if the corresponding variables <w_changeable> and
  4818.     <h_changeable> are set True.  Otherwise the original width or
  4819.     height in <w_ptr> and <h_ptr> are used as fixed values.  The
  4820.     resulting new width and height are stored back through the
  4821.     <w_ptr> and <h_ptr> pointers.  False is returned if no size
  4822.     change was done, True is returned otherwise.
  4823.  
  4824.  *---------------------------------------------------------------------------*/
  4825.  
  4826. static Boolean Layout(mlw,w_changeable,h_changeable,w_ptr,h_ptr)
  4827. XfwfMultiListWidget mlw;
  4828. Boolean w_changeable,h_changeable;
  4829. Dimension *w_ptr,*h_ptr;
  4830. {
  4831.     Boolean size_changed = False;
  4832.  
  4833.     /*
  4834.      * If force columns is set, then always use the number
  4835.      * of columns specified by default_cols.
  4836.      */
  4837.  
  4838.     MultiListColWidth(mlw) = MultiListLongest(mlw) +
  4839.         MultiListColumnSpace(mlw);
  4840.     MultiListRowHeight(mlw) = FontH(MultiListFont(mlw)) +
  4841.         MultiListRowSpace(mlw);
  4842.     if (MultiListForceCols(mlw))
  4843.     {
  4844.         MultiListNumCols(mlw) = max(MultiListDefaultCols(mlw),1);
  4845.         if (MultiListNumItems(mlw) == 0)
  4846.             MultiListNumRows(mlw) = 1;
  4847.             else
  4848.             MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) /
  4849.                 MultiListNumCols(mlw) + 1;
  4850.         if (w_changeable)
  4851.         {
  4852.             *w_ptr = MultiListNumCols(mlw) *
  4853.                 MultiListColWidth(mlw);
  4854.             size_changed = True;
  4855.         }
  4856.             else
  4857.         {
  4858.             MultiListColWidth(mlw) = *w_ptr /
  4859.                 MultiListNumCols(mlw);
  4860.         }
  4861.         if (h_changeable)
  4862.         {
  4863.             *h_ptr = MultiListNumRows(mlw) *
  4864.                 MultiListRowHeight(mlw);
  4865.             size_changed = True;
  4866.         }
  4867.         return(size_changed);
  4868.     }
  4869.  
  4870.     /*
  4871.      * If both width and height are free to change then use
  4872.      * default_cols to determine the number of columns and set
  4873.      * the new width and height to just fit the window.
  4874.      */
  4875.  
  4876.     if (w_changeable && h_changeable)
  4877.     {
  4878.         MultiListNumCols(mlw) = max(MultiListDefaultCols(mlw),1);
  4879.         if (MultiListNumItems(mlw) == 0)
  4880.             MultiListNumRows(mlw) = 1;
  4881.             else
  4882.             MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) /
  4883.                 MultiListNumCols(mlw) + 1;
  4884.         *w_ptr = MultiListNumCols(mlw) * MultiListColWidth(mlw);
  4885.         *h_ptr = MultiListNumRows(mlw) * MultiListRowHeight(mlw);
  4886.         return(True);
  4887.     }
  4888.  
  4889.     /*
  4890.      * If the width is fixed then use it to determine the
  4891.      * number of columns.  If the height is free to move
  4892.      * (width still fixed) then resize the height of the
  4893.      * widget to fit the current MultiList exactly.
  4894.      */
  4895.  
  4896.     if (!w_changeable)
  4897.     {
  4898.         MultiListNumCols(mlw) = *w_ptr / MultiListColWidth(mlw);
  4899.         MultiListNumCols(mlw) = max(MultiListNumCols(mlw),1);
  4900.         MultiListNumRows(mlw) = (MultiListNumItems(mlw) - 1) /
  4901.             MultiListNumCols(mlw) + 1;
  4902.         MultiListColWidth(mlw) = *w_ptr / MultiListNumCols(mlw);
  4903.         if (h_changeable)
  4904.         {
  4905.             *h_ptr = MultiListNumRows(mlw) * MultiListRowHeight(mlw);
  4906.             size_changed = True;
  4907.         }
  4908.         return(size_changed);
  4909.     }
  4910.  
  4911.     /*
  4912.      * The last case is xfree and !yfree we use the height to
  4913.      * determine the number of rows and then set the width to
  4914.      * just fit the resulting number of columns.
  4915.      */
  4916.  
  4917.     MultiListNumRows(mlw) = *h_ptr / MultiListRowHeight(mlw);
  4918.     MultiListNumRows(mlw) = max(MultiListNumRows(mlw),1);
  4919.     MultiListNumCols(mlw) = (MultiListNumItems(mlw) - 1) /
  4920.         MultiListNumRows(mlw) + 1;
  4921.     *w_ptr = MultiListNumCols(mlw) * MultiListColWidth(mlw);
  4922.     return(True);
  4923. } /* End Layout */
  4924.  
  4925. /*===========================================================================*
  4926.  
  4927.                     R E D R A W    R O U T I N E S
  4928.  
  4929.  *===========================================================================*/
  4930.  
  4931. /*---------------------------------------------------------------------------*
  4932.  
  4933.     RedrawAll(mlw)
  4934.  
  4935.     This routine simple calls Redisplay to redraw the entire
  4936.     MultiList widget <mlw>.
  4937.  
  4938.  *---------------------------------------------------------------------------*/
  4939.  
  4940. static void RedrawAll(mlw)
  4941. XfwfMultiListWidget mlw;
  4942. {
  4943.     Redisplay(mlw,NULL,NULL);
  4944. } /* End RedrawAll */
  4945.  
  4946.  
  4947. /*---------------------------------------------------------------------------*
  4948.  
  4949.     RedrawItem(mlw,item_index)
  4950.  
  4951.     This routine redraws the item with index <item_index> in the
  4952.     MultiList widget <mlw>.  If the item number is bad, nothing is drawn.
  4953.  
  4954.  *---------------------------------------------------------------------------*/
  4955.  
  4956. static void RedrawItem(mlw,item_index)
  4957. XfwfMultiListWidget mlw;
  4958. int item_index;
  4959. {
  4960.     int row,column;
  4961.  
  4962.     if (ItemToRowColumn(mlw,item_index,&row,&column))
  4963.     {
  4964.         RedrawRowColumn(mlw,row,column);
  4965.     }
  4966. } /* End RedrawItem */
  4967.  
  4968.  
  4969. /*---------------------------------------------------------------------------*
  4970.  
  4971.     RedrawRowColumn(mlw,row,column)
  4972.  
  4973.     This routine paints the item in row/column position <row>,<column>
  4974.     on the MultiList widget <mlw>.  If the row/column coordinates are
  4975.     outside the widget, nothing is drawn.  If the position is empty,
  4976.     blank space is drawn.
  4977.  
  4978.  *---------------------------------------------------------------------------*/
  4979.  
  4980. static void RedrawRowColumn(mlw,row,column)
  4981. XfwfMultiListWidget mlw;
  4982. int row,column;
  4983. {
  4984.     GC bg_gc,fg_gc;
  4985.     XfwfMultiListItem *item;
  4986.     int ul_x,ul_y,str_x,str_y,w,h,item_index,has_item,text_h;
  4987.  
  4988.     if (!XtIsRealized((Widget)mlw)) return;
  4989.     has_item = RowColumnToItem(mlw,row,column,&item_index);
  4990.     RowColumnToPixels(mlw,row,column,&ul_x,&ul_y,&w,&h);
  4991.  
  4992.     if (has_item == False)                    /* No Item */
  4993.     {
  4994.         if (MultiListShadeSurplus(mlw))
  4995.             bg_gc = MultiListGrayGC(mlw);
  4996.             else
  4997.             bg_gc = MultiListEraseGC(mlw);
  4998.     }
  4999.         else
  5000.     {
  5001.         item = MultiListNthItem(mlw,item_index);
  5002.         if (!MultiListItemSensitive(item))        /* Disabled */
  5003.         {
  5004.             bg_gc = MultiListEraseGC(mlw);
  5005.             fg_gc = MultiListGrayGC(mlw);
  5006.         }
  5007.             else if (MultiListItemHighlighted(item))    /* Selected */
  5008.         {
  5009.             bg_gc = MultiListHighlightBackGC(mlw);
  5010.             fg_gc = MultiListHighlightForeGC(mlw);
  5011.         }
  5012.             else                    /* Normal */
  5013.         {
  5014.             bg_gc = MultiListEraseGC(mlw);
  5015.             fg_gc = MultiListDrawGC(mlw);
  5016.         }
  5017.     }
  5018.     XFillRectangle(XtDisplay(mlw),XtWindow(mlw),bg_gc,ul_x,ul_y,w,h);
  5019.     if (has_item == True)
  5020.     {
  5021.         text_h = min(FontH(MultiListFont(mlw)) +
  5022.                  MultiListRowSpace(mlw),MultiListRowHeight(mlw));
  5023.         str_x = ul_x + MultiListColumnSpace(mlw) / 2;
  5024.         str_y = ul_y + FontAscent(MultiListFont(mlw)) +
  5025.             (MultiListRowHeight(mlw) - text_h) / 2;
  5026.         XDrawString(XtDisplay(mlw),XtWindow(mlw),fg_gc,
  5027.                 str_x,str_y,MultiListItemString(item),
  5028.                 strlen(MultiListItemString(item)));
  5029.     }
  5030. } /* End RedrawRowColumn */
  5031.     
  5032. /*===========================================================================*
  5033.  
  5034.                I T E M    L O C A T I O N    R O U T I N E S
  5035.  
  5036.  *===========================================================================*/
  5037.  
  5038. /*---------------------------------------------------------------------------*
  5039.  
  5040.     void PixelToRowColumn(mlw,x,y,row_ptr,column_ptr)
  5041.  
  5042.     This routine takes pixel coordinates <x>, <y> and converts
  5043.     the pixel coordinate into a row/column coordinate.  This row/column
  5044.     coordinate can then easily be converted into the specific item
  5045.     in the list via the function RowColumnToItem().
  5046.  
  5047.     If the pixel lies in blank space outside of the items, the
  5048.     row & column numbers will be outside of the range of normal
  5049.     row & columns numbers, but will correspond to the row & column
  5050.     of the item, if an item was actually there.
  5051.  
  5052.  *---------------------------------------------------------------------------*/
  5053.  
  5054. static void PixelToRowColumn(mlw,x,y,row_ptr,column_ptr)
  5055. XfwfMultiListWidget mlw;
  5056. int x,y,*row_ptr,*column_ptr;
  5057. {
  5058.     *row_ptr = y / MultiListRowHeight(mlw);
  5059.     *column_ptr = x / MultiListColWidth(mlw);
  5060. } /* End PixelToRowColumn */
  5061.  
  5062. /*---------------------------------------------------------------------------*
  5063.  
  5064.     void RowColumnToPixels(mlw,row,col,x_ptr,y_ptr,w_ptr,h_ptr)
  5065.  
  5066.     This routine takes a row/column coordinate <row>,<col> and
  5067.     converts it into the bounding pixel rectangle which is returned.
  5068.  
  5069.  *---------------------------------------------------------------------------*/
  5070.  
  5071. static void RowColumnToPixels(mlw,row,col,x_ptr,y_ptr,w_ptr,h_ptr)
  5072. XfwfMultiListWidget mlw;
  5073. int row,col,*x_ptr,*y_ptr,*w_ptr,*h_ptr;
  5074. {
  5075.     *x_ptr = col * MultiListColWidth(mlw);
  5076.     *y_ptr = row * MultiListRowHeight(mlw);
  5077.     *w_ptr = MultiListColWidth(mlw);
  5078.     *h_ptr = MultiListRowHeight(mlw);
  5079. } /* End RowColumnToPixels */
  5080.  
  5081. /*---------------------------------------------------------------------------*
  5082.  
  5083.     Boolean RowColumnToItem(mlw,row,column,item_ptr)
  5084.  
  5085.     This routine takes a row number <row> and a column number <column>
  5086.     and tries to resolve this row and column into the index of the
  5087.     item in this position of the MultiList widget <mlw>.  The resulting
  5088.     item index is placed through <item_ptr>.  If there is no item at
  5089.     this location, False is returned, else True is returned.
  5090.  
  5091.  *---------------------------------------------------------------------------*/
  5092.  
  5093. static Boolean RowColumnToItem(mlw,row,column,item_ptr)
  5094. XfwfMultiListWidget mlw;
  5095. int row,column,*item_ptr;
  5096. {
  5097.     register int x_stride,y_stride;
  5098.  
  5099.     if (row < 0 || row >= MultiListNumRows(mlw) ||
  5100.         column < 0 || column >= MultiListNumCols(mlw))
  5101.     {
  5102.         return(False);
  5103.     }
  5104.     if (MultiListRowMajor(mlw))
  5105.     {
  5106.         x_stride = 1;
  5107.         y_stride = MultiListNumCols(mlw);
  5108.     }
  5109.         else
  5110.     {
  5111.         x_stride = MultiListNumRows(mlw);
  5112.         y_stride = 1;
  5113.     }
  5114.     *item_ptr = row * y_stride + column * x_stride;
  5115.     if (*item_ptr >= MultiListNumItems(mlw))
  5116.         return(False);
  5117.         else
  5118.         return(True);
  5119. } /* End RowColumnToItem */
  5120.  
  5121.  
  5122. /*---------------------------------------------------------------------------*
  5123.  
  5124.     Boolean ItemToRowColumn(mlw,item_index,row_ptr,column_ptr)
  5125.  
  5126.     This routine takes an item number <item_index> and attempts
  5127.     to convert the index into row and column numbers stored through
  5128.     <row_ptr> and <column_ptr>.  If the item number does not
  5129.     corespond to a valid item, False is returned, else True is
  5130.     returned.
  5131.  
  5132.  *---------------------------------------------------------------------------*/
  5133.  
  5134. static Boolean ItemToRowColumn(mlw,item_index,row_ptr,column_ptr)
  5135. XfwfMultiListWidget mlw;
  5136. int item_index,*row_ptr,*column_ptr;
  5137. {
  5138.     if (item_index < 0 || item_index >= MultiListNumItems(mlw))
  5139.     {
  5140.         return(False);
  5141.     }
  5142.     if (MultiListRowMajor(mlw))
  5143.     {
  5144.         *row_ptr = item_index / MultiListNumCols(mlw);
  5145.         *column_ptr = item_index % MultiListNumCols(mlw);
  5146.     }
  5147.         else
  5148.     {
  5149.         *row_ptr = item_index % MultiListNumRows(mlw);
  5150.         *column_ptr = item_index / MultiListNumRows(mlw);
  5151.     }
  5152.     return(True);
  5153. } /* End ItemToRowColumn */
  5154.  
  5155. /*===========================================================================*
  5156.  
  5157.                 E V E N T    A C T I O N    H A N D L E R S
  5158.  
  5159.  *===========================================================================*/
  5160.  
  5161. /*---------------------------------------------------------------------------*
  5162.  
  5163.     Select(mlw,event,params,num_params)
  5164.  
  5165.     This action handler is called when a user selects an item in the
  5166.     MultiList.  This action first unselects all previously selected
  5167.     items, then selects the item under the mouse, if it is not a
  5168.     background gap, and if it is sensitive.
  5169.  
  5170.     The MultiListMostRecentItem(mlw) variable will be set to the
  5171.     item clicked on, or -1 if the item is background or insensitive.
  5172.     The MultiListMostRecentAct(mlw) variable will be set to
  5173.     XfwfMultiListActionHighlight, in case the selection region is extended.
  5174.  
  5175.  *---------------------------------------------------------------------------*/
  5176.  
  5177. /* ARGSUSED */
  5178. static void Select(mlw,event,params,num_params)
  5179. XfwfMultiListWidget mlw;
  5180. XEvent *event;
  5181. String *params;
  5182. Cardinal *num_params;
  5183. {
  5184.     int click_x,click_y;
  5185.     int status,item_index,row,column;
  5186.  
  5187.     click_x = event->xbutton.x;
  5188.     click_y = event->xbutton.y;
  5189.     PixelToRowColumn(mlw,click_x,click_y,&row,&column);
  5190.     XfwfMultiListUnhighlightAll(mlw);
  5191.     MultiListMostRecentAct(mlw) = XfwfMultiListActionHighlight;
  5192.     status = RowColumnToItem(mlw,row,column,&item_index);
  5193.     if ((status == False) ||
  5194.         (!MultiListItemSensitive(MultiListNthItem(mlw,item_index))))
  5195.     {
  5196.         MultiListMostRecentItem(mlw) = -1;
  5197.     }
  5198.         else
  5199.     {
  5200.         MultiListMostRecentItem(mlw) = item_index;
  5201.         XfwfMultiListHighlightItem(mlw,item_index);
  5202.     }
  5203. } /* End Select */
  5204.  
  5205.  
  5206. /*---------------------------------------------------------------------------*
  5207.  
  5208.     Unselect(mlw,event,params,num_params)
  5209.  
  5210.     This function unselects the single text item pointed to by the
  5211.     mouse, if any.  Any remaining selected entries are left selected.
  5212.  
  5213.     The MultiListMostRecentItem(mlw) variable will be set to -1, and
  5214.     the MultiListMostRecentAct(mlw) variable will be set to
  5215.     XfwfMultiListActionUnhighlight, in case the deselection region is
  5216.     extended.
  5217.     
  5218.  *---------------------------------------------------------------------------*/
  5219.  
  5220. /* ARGSUSED */
  5221. static void Unselect(mlw,event,params,num_params)
  5222. XfwfMultiListWidget mlw;
  5223. XEvent *event;
  5224. String *params;
  5225. Cardinal *num_params;
  5226. {
  5227.     int click_x,click_y;
  5228.     int status,item_index,row,column;
  5229.  
  5230.     click_x = event->xbutton.x;
  5231.     click_y = event->xbutton.y;
  5232.     PixelToRowColumn(mlw,click_x,click_y,&row,&column);
  5233.     MultiListMostRecentItem(mlw) = -1;
  5234.     MultiListMostRecentAct(mlw) = XfwfMultiListActionUnhighlight;
  5235.     status = RowColumnToItem(mlw,row,column,&item_index);
  5236.     if ((status == True) &&
  5237.         (MultiListItemSensitive(MultiListNthItem(mlw,item_index))))
  5238.         XfwfMultiListHighlightItem(mlw,item_index);
  5239. } /* End Unselect */
  5240.  
  5241.  
  5242. /*---------------------------------------------------------------------------*
  5243.  
  5244.     Toggle(mlw,event,params,num_params)
  5245.  
  5246.     This action handler implements the toggling of selection status
  5247.     for a single item.  Any remaining selected entries are left selected.
  5248.  
  5249.     If the mouse is not over a selectable text item, the
  5250.     MultiListMostRecentAct(mlw) variable is set to
  5251.     XfwfMultiListActionHighlight, in case the region is extended into
  5252.     selectable items later.  MultiListMostRecentItem(mlw) is set to -1.
  5253.  
  5254.     If the mouse is over a selectable text item, the item highlight is
  5255.     toggled.  If the item is currently selected, it becomes deselected.
  5256.     If unselected, the item becomes selected.  At the same time, the
  5257.     MultiListMostRecentAct(mlw) variable is set to
  5258.     XfwfMultiListActionHighlight if the item was not previously selected,
  5259.     or XfwfMultiListActionUnhighlight if the item was previously selected.
  5260.     MultiListMostRecentItem(mlw) is set to the index of the item clicked
  5261.     on if the item is selected, or -1 if it is unselected.
  5262.  
  5263.  *---------------------------------------------------------------------------*/
  5264.  
  5265. /* ARGSUSED */
  5266. static void Toggle(mlw,event,params,num_params)
  5267. XfwfMultiListWidget mlw;
  5268. XEvent *event;
  5269. String *params;
  5270. Cardinal *num_params;
  5271. {
  5272.     int click_x,click_y;
  5273.     int status,item_index,row,column;
  5274.  
  5275.     click_x = event->xbutton.x;
  5276.     click_y = event->xbutton.y;
  5277.     PixelToRowColumn(mlw,click_x,click_y,&row,&column);
  5278.     status = RowColumnToItem(mlw,row,column,&item_index);
  5279.     if ((status == False) ||
  5280.         (!MultiListItemSensitive(MultiListNthItem(mlw,item_index))))
  5281.     {
  5282.         MultiListMostRecentAct(mlw) = XfwfMultiListActionHighlight;
  5283.         MultiListMostRecentItem(mlw) = -1;
  5284.     }
  5285.         else
  5286.     {
  5287.         MultiListMostRecentAct(mlw) =
  5288.             XfwfMultiListToggleItem(mlw,item_index);
  5289.         MultiListMostRecentItem(mlw) = item_index;
  5290.     }
  5291. } /* End Toggle */
  5292.  
  5293.  
  5294. /*---------------------------------------------------------------------------*
  5295.  
  5296.     Extend(mlw,event,params,num_params)
  5297.  
  5298.     This action handler implements the extension of a selection/
  5299.     deselection region.
  5300.  
  5301.     The MultiListMostRecentAct(mlw) variable is used to determine
  5302.     if items are to be selected or unselected.  This routine performs
  5303.     select or unselect actions on each item it is called on.
  5304.  
  5305.  *---------------------------------------------------------------------------*/
  5306.  
  5307. /* ARGSUSED */
  5308. static void Extend(mlw,event,params,num_params)
  5309. XfwfMultiListWidget mlw;
  5310. XEvent *event;
  5311. String *params;
  5312. Cardinal *num_params;
  5313. {
  5314.     int click_x,click_y;
  5315.     int status,item_index,row,column;
  5316.  
  5317.     click_x = ((XMotionEvent*)event)->x;
  5318.     click_y = ((XMotionEvent*)event)->y;
  5319.     PixelToRowColumn(mlw,click_x,click_y,&row,&column);
  5320.     status = RowColumnToItem(mlw,row,column,&item_index);
  5321.     if ((status == True) &&
  5322.         (MultiListItemSensitive(MultiListNthItem(mlw,item_index))))
  5323.     {
  5324.         MultiListMostRecentItem(mlw) = item_index;
  5325.         if (MultiListMostRecentAct(mlw) == XfwfMultiListActionHighlight)
  5326.             XfwfMultiListHighlightItem(mlw,item_index);
  5327.             else
  5328.             XfwfMultiListUnhighlightItem(mlw,item_index);
  5329.     }
  5330. } /* End Extend */
  5331.  
  5332.  
  5333. /*---------------------------------------------------------------------------*
  5334.  
  5335.     Notify(mlw,event,params,num_params)
  5336.  
  5337.     This function performs the Notify action, which issues a callback
  5338.     after a selection/unselection has completed.  All callbacks on the
  5339.     callback list are invoked, and a XfxfMultiListReturnStruct describing
  5340.     the selection state is returned.
  5341.  
  5342.     In addition, if the XtNpasteBuffer resource is true and at least one
  5343.     text item is selected, all the selected items are placed in the X
  5344.     cut buffer (buf(0)) separated by newlines.
  5345.  
  5346.  *---------------------------------------------------------------------------*/
  5347.  
  5348. /* ARGSUSED */
  5349. static void Notify(mlw,event,params,num_params)
  5350. XfwfMultiListWidget mlw;
  5351. XEvent *event;
  5352. String *params;
  5353. Cardinal *num_params;
  5354. {
  5355.     char *buffer;
  5356.     String string;
  5357.     int i,byte_count,item_index;
  5358.     XfwfMultiListReturnStruct ret_value;
  5359.  
  5360.     if ((MultiListNumSelected(mlw) != 0) && MultiListPaste(mlw))
  5361.     {
  5362.         byte_count = 0;
  5363.         for (i = 0; i < MultiListNumSelected(mlw); i++)
  5364.         {
  5365.             item_index = MultiListSelArray(mlw)[i];
  5366.             string = MultiListItemString(MultiListNthItem(mlw,
  5367.                 item_index));
  5368.             byte_count = byte_count + strlen(string) + 1;
  5369.         }
  5370.         buffer = (char *)malloc(byte_count);
  5371.         buffer[0] = '\0';
  5372.         for (i = 0; i < MultiListNumSelected(mlw); i++)
  5373.         {
  5374.             if (i != 0) strcat(buffer,"\n");
  5375.             item_index = MultiListSelArray(mlw)[i];
  5376.             string = MultiListItemString(MultiListNthItem(mlw,
  5377.                 item_index));
  5378.             strcat(buffer,string);
  5379.         }
  5380.         XStoreBytes(XtDisplay(mlw),buffer,byte_count);
  5381.         free(buffer);
  5382.     }
  5383.  
  5384.     ret_value.action = MultiListMostRecentAct(mlw);
  5385.     ret_value.item = MultiListMostRecentItem(mlw);
  5386.     if (ret_value.item == -1)
  5387.         ret_value.string = NULL;
  5388.         else
  5389.         ret_value.string = MultiListItemString(MultiListNthItem(mlw,
  5390.             ret_value.item));
  5391.     ret_value.num_selected = MultiListNumSelected(mlw);
  5392.     ret_value.selected_items = MultiListSelArray(mlw);
  5393.     XtCallCallbacks((Widget)mlw,XtNcallback,(caddr_t)&ret_value);
  5394. } /* End Notify */
  5395.  
  5396. /*===========================================================================*
  5397.  
  5398.         U S E R    C A L L A B L E    U T I L I T Y    R O U T I N E S
  5399.  
  5400.  *===========================================================================*/
  5401.  
  5402. /*---------------------------------------------------------------------------*
  5403.  
  5404.     Boolean XfwfMultiListHighlightItem(mlw,item_index)
  5405.  
  5406.     This routine selects an item with index <item_index> in the
  5407.     MultiList widget <mlw>.  If a maximum number of selections is specified
  5408.     and exceeded, the earliest selection will be unselected.  If
  5409.     <item_index> doesn't correspond to an item the most recently
  5410.     clicked item will be set to -1 and this routine will immediately
  5411.     return, otherwise the most recently clicked item will be set to the
  5412.     current item.  If the clicked on item is not sensitive, or if the
  5413.     click is not on an item, False is returned, else True is returned.
  5414.  
  5415.  *---------------------------------------------------------------------------*/
  5416.  
  5417. Boolean XfwfMultiListHighlightItem(mlw,item_index)
  5418. XfwfMultiListWidget mlw;
  5419. int item_index;
  5420. {
  5421.     XfwfMultiListItem *item;
  5422.  
  5423.     if (MultiListMaxSelectable(mlw) == 0) return(False);
  5424.     if (item_index < 0 || item_index >= MultiListNumItems(mlw))
  5425.     {
  5426.         MultiListMostRecentItem(mlw) = -1;
  5427.         return(False);
  5428.     }
  5429.     item = MultiListNthItem(mlw,item_index);
  5430.     if (MultiListItemSensitive(item) == False) return(False);
  5431.     MultiListMostRecentItem(mlw) = item_index;
  5432.     if (MultiListItemHighlighted(item) == True) return(True);
  5433.     if (MultiListNumSelected(mlw) == MultiListMaxSelectable(mlw))
  5434.     {
  5435.         XfwfMultiListUnhighlightItem(mlw,MultiListSelArray(mlw)[0]);
  5436.     }
  5437.     MultiListItemHighlighted(item) = True;
  5438.     MultiListSelArray(mlw)[MultiListNumSelected(mlw)] = item_index;
  5439.     ++ MultiListNumSelected(mlw);
  5440.     RedrawItem(mlw,item_index);
  5441.     return(True);
  5442. } /* End XfwfMultiListHighlightItem */
  5443.  
  5444.  
  5445. /*---------------------------------------------------------------------------*
  5446.  
  5447.     XfwfMultiListHighlightAll(mlw)
  5448.  
  5449.     This routine highlights all highlightable items in the MultiList
  5450.     widget <mlw>, up to the maximum number of allowed highlightable
  5451.     items;
  5452.  
  5453.  *---------------------------------------------------------------------------*/
  5454.  
  5455. void XfwfMultiListHighlightAll(mlw)
  5456. XfwfMultiListWidget mlw;
  5457. {
  5458.     int i;
  5459.     XfwfMultiListItem *item;
  5460.  
  5461.     MultiListNumSelected(mlw) = 0;
  5462.     for (i = 0; i < MultiListNumItems(mlw); i++)
  5463.     {
  5464.         item = MultiListNthItem(mlw,i);
  5465.         MultiListItemHighlighted(item) = False;
  5466.     }
  5467.     for (i = 0; i < MultiListNumItems(mlw); i++)
  5468.     {
  5469.         if (MultiListNumSelected(mlw) == MultiListMaxSelectable(mlw))
  5470.             break;
  5471.         item = MultiListNthItem(mlw,i);
  5472.         if (MultiListItemSensitive(item) == False) continue;
  5473.         MultiListItemHighlighted(item) = True;
  5474.         MultiListSelArray(mlw)[MultiListNumSelected(mlw)] = i;
  5475.         ++ MultiListNumSelected(mlw);
  5476.     }
  5477.     RedrawAll(mlw);
  5478. } /* End XfwfMultiListHighlightAll */
  5479.  
  5480.  
  5481. /*---------------------------------------------------------------------------*
  5482.  
  5483.     XfwfMultiListUnhighlightItem(mlw,item_index)
  5484.  
  5485.     This routine unselects the item with index <item_index> in the
  5486.     MultiList widget <mlw>.  If <item_index> doesn't correspond to a
  5487.     selected item, then nothing will happen.  Otherwise, the item
  5488.     is unselected and the selection array and count are updated.
  5489.  
  5490.  *---------------------------------------------------------------------------*/
  5491.  
  5492. void XfwfMultiListUnhighlightItem(mlw,item_index)
  5493. XfwfMultiListWidget mlw;
  5494. int item_index;
  5495. {
  5496.     int i;
  5497.     XfwfMultiListItem *item;
  5498.  
  5499.     if (MultiListMaxSelectable(mlw) == 0) return;
  5500.     if (item_index < 0 || item_index >= MultiListNumItems(mlw)) return;
  5501.     item = MultiListNthItem(mlw,item_index);
  5502.     if (MultiListItemHighlighted(item) == False) return;
  5503.     MultiListItemHighlighted(item) = False;
  5504.  
  5505.     for (i = 0; i < MultiListNumSelected(mlw); i++)
  5506.         if (MultiListSelArray(mlw)[i] == item_index) break;
  5507.     for (i = i + 1; i < MultiListNumSelected(mlw); i++)
  5508.         MultiListSelArray(mlw)[i - 1] = MultiListSelArray(mlw)[i];
  5509.     -- MultiListNumSelected(mlw);
  5510.  
  5511.     RedrawItem(mlw,item_index);
  5512. } /* End XfwfMultiListUnhighlightItem */
  5513.  
  5514.  
  5515. /*---------------------------------------------------------------------------*
  5516.  
  5517.     XfwfMultiListUnhighlightAll(mlw)
  5518.  
  5519.     This routine unhighlights all items in the MultiList widget <mlw>.
  5520.  
  5521.  *---------------------------------------------------------------------------*/
  5522.  
  5523. void XfwfMultiListUnhighlightAll(mlw)
  5524. XfwfMultiListWidget mlw;
  5525. {
  5526.     int i;
  5527.     XfwfMultiListItem *item;
  5528.  
  5529.     for (i = 0; i < MultiListNumItems(mlw); i++)
  5530.     {
  5531.         item = MultiListNthItem(mlw,i);
  5532.         if (MultiListItemHighlighted(item))
  5533.             XfwfMultiListUnhighlightItem(mlw,i);
  5534.     }
  5535.     MultiListNumSelected(mlw) = 0;
  5536. } /* End XfwfMultiListUnhighlightAll */
  5537.  
  5538.  
  5539. /*---------------------------------------------------------------------------*
  5540.  
  5541.     int XfwfMultiListToggleItem(mlw,item_index)
  5542.  
  5543.     This routine highlights the item with index <item_index>
  5544.     if it is unhighlighted and unhighlights it if it is already
  5545.     highlighted.  The action performed by the toggle is returned
  5546.     (XfwfMultiListActionHighlight or XfwfMultiListActionUnhighlight).
  5547.  
  5548.  *---------------------------------------------------------------------------*/
  5549.  
  5550. int XfwfMultiListToggleItem(mlw,item_index)
  5551. XfwfMultiListWidget mlw;
  5552. int item_index;
  5553. {
  5554.     XfwfMultiListItem *item;
  5555.  
  5556.     if (MultiListMaxSelectable(mlw) == 0)
  5557.         return(XfwfMultiListActionNothing);
  5558.     if (item_index < 0 || item_index >= MultiListNumItems(mlw))
  5559.         return(XfwfMultiListActionNothing);
  5560.     item = MultiListNthItem(mlw,item_index);
  5561.     if (MultiListItemSensitive(item) == False)
  5562.         return(XfwfMultiListActionNothing);
  5563.     if (MultiListItemHighlighted(item))
  5564.     {
  5565.         XfwfMultiListUnhighlightItem(mlw,item_index);
  5566.         return(XfwfMultiListActionUnhighlight);
  5567.     }
  5568.         else
  5569.     {
  5570.         XfwfMultiListHighlightItem(mlw,item_index);
  5571.         return(XfwfMultiListActionHighlight);
  5572.     }
  5573. } /* End XfwfMultiListToggleItem */
  5574.  
  5575.  
  5576. /*---------------------------------------------------------------------------*
  5577.  
  5578.     XfwfMultiListReturnStruct *XfwfMultiListGetHighlighted(mlw)
  5579.  
  5580.     This routine takes a MultiList widget <mlw> and returns a
  5581.     XfwfMultiListReturnStruct whose num_selected and selected_items
  5582.     fields contain the highlight information.  The action field
  5583.     is set to MULTILIST_ACTION_STATUS, and the item_index and string
  5584.     fields are invalid.
  5585.  
  5586.  *---------------------------------------------------------------------------*/
  5587.  
  5588. XfwfMultiListReturnStruct *XfwfMultiListGetHighlighted(mlw)
  5589. XfwfMultiListWidget mlw;
  5590. {
  5591.     XfwfMultiListItem *item;
  5592.     static XfwfMultiListReturnStruct ret_value;
  5593.  
  5594.     ret_value.action = XfwfMultiListActionStatus;
  5595.     if (MultiListNumSelected(mlw) == 0)
  5596.     {
  5597.         ret_value.item = -1;
  5598.         ret_value.string = NULL;
  5599.     }
  5600.         else
  5601.     {
  5602.         ret_value.item = MultiListSelArray(mlw)
  5603.             [MultiListNumSelected(mlw) - 1];
  5604.         item = MultiListNthItem(mlw,ret_value.item);
  5605.         ret_value.string = MultiListItemString(item);
  5606.     }
  5607.     ret_value.num_selected = MultiListNumSelected(mlw);
  5608.     ret_value.selected_items = MultiListSelArray(mlw);
  5609.     return(&ret_value);
  5610. } /* End XfwfMultiListGetHighlighted */
  5611.  
  5612.  
  5613. /*---------------------------------------------------------------------------*
  5614.  
  5615.     Boolean XfwfMultiListIsHighlighted(mlw,item_index)
  5616.  
  5617.     This routine checks if the item with index <item_index>
  5618.     is highlighted and returns True or False depending.  If
  5619.     <item_index> is invalid, False is returned.
  5620.  
  5621.  *---------------------------------------------------------------------------*/
  5622.  
  5623. Boolean XfwfMultiListIsHighlighted(mlw,item_index)
  5624. XfwfMultiListWidget mlw;
  5625. int item_index;
  5626. {
  5627.     XfwfMultiListItem *item;
  5628.  
  5629.     if (item_index < 0 || item_index >= MultiListNumItems(mlw))
  5630.         return(False);
  5631.     item = MultiListNthItem(mlw,item_index);
  5632.     return(MultiListItemHighlighted(item));
  5633. } /* End XfwfMultiListIsHighlighted */
  5634.  
  5635.  
  5636. /*---------------------------------------------------------------------------*
  5637.  
  5638.     Boolean XfwfMultiListGetItemInfo(mlw,item_index,str_ptr,h_ptr,s_ptr)
  5639.  
  5640.     This routine returns the string, highlight status and
  5641.     sensitivity information for the item with index <item_index>
  5642.     via the pointers <str_ptr>, <h_ptr> and <s_ptr>.  If the item
  5643.     index is invalid, False is returned, else True is returned.
  5644.  
  5645.  *---------------------------------------------------------------------------*/
  5646.  
  5647. Boolean XfwfMultiListGetItemInfo(mlw,item_index,str_ptr,h_ptr,s_ptr)
  5648. XfwfMultiListWidget mlw;
  5649. int item_index;
  5650. String *str_ptr;
  5651. Boolean *h_ptr,*s_ptr;
  5652. {
  5653.     XfwfMultiListItem *item;
  5654.  
  5655.     if (item_index < 0 || item_index >= MultiListNumItems(mlw))
  5656.         return(False);
  5657.     item = MultiListNthItem(mlw,item_index);
  5658.     *str_ptr = MultiListItemString(item);
  5659.     *h_ptr = MultiListItemHighlighted(item);
  5660.     *s_ptr = MultiListItemSensitive(item);
  5661.     return(True);
  5662. } /* End XfwfMultiListGetItemInfo */
  5663.  
  5664.  
  5665. /*---------------------------------------------------------------------------*
  5666.  
  5667.     XfwfMultiListSetNewData(mlw,list,nitems,longest,resize,
  5668.         sensitivity_array)
  5669.  
  5670.     This routine will set a new set of strings <list> into the
  5671.     MultiList widget <mlw>.  If <resize> is True, the MultiList widget will
  5672.     try to resize itself.
  5673.  
  5674.  *---------------------------------------------------------------------------*/
  5675.  
  5676. void XfwfMultiListSetNewData(mlw,list,nitems,longest,resize,sensitivity_array)
  5677. XfwfMultiListWidget mlw;
  5678. String *list;
  5679. int nitems,longest;
  5680. Boolean resize;
  5681. Boolean *sensitivity_array;
  5682. {
  5683.     DestroyOldData(mlw);
  5684.     MultiListList(mlw) = list;
  5685.     MultiListNumItems(mlw) = max(nitems,0);
  5686.     MultiListLongest(mlw) = max(longest,0);
  5687.     MultiListSensitiveArray(mlw) = sensitivity_array;
  5688.     InitializeNewData(mlw);
  5689.     RecalcCoords(mlw,resize,resize);
  5690.     if (XtIsRealized((Widget)mlw)) Redisplay(mlw,NULL,NULL);
  5691. } /* End XfwfMultiListSetNewData */
  5692. SHAR_EOF
  5693. fi
  5694. if test -f 'MultiList.h'
  5695. then
  5696.     echo shar: "will not over-write existing file 'MultiList.h'"
  5697. else
  5698. cat << \SHAR_EOF > 'MultiList.h'
  5699. /****************************************************************************
  5700.  
  5701.     MultiList.h
  5702.  
  5703.     This file is the public header file for the MultiList widget, an
  5704.     extension to the Athena List widget.
  5705.  
  5706.     This code is loosely based on the Athena List source which
  5707.     is why the MIT copyright notice appears below.
  5708.  
  5709.     The code was changed substantially in V3.4 to change the
  5710.     action/callback interface which was unnecessarily ugly.  Code
  5711.     using some features of the old interface may need to be changed.
  5712.     Hope the changes don't make people's lives too miserable.
  5713.  
  5714.  ****************************************************************************/
  5715.  
  5716. /*
  5717.  * Author:
  5718.  *     Brian Totty
  5719.  *     Department of Computer Science
  5720.  *     University Of Illinois at Urbana-Champaign
  5721.  *    1304 West Springfield Avenue
  5722.  *     Urbana, IL 61801
  5723.  * 
  5724.  *     totty@cs.uiuc.edu
  5725.  *     
  5726.  */ 
  5727.  
  5728. /*
  5729.  * Copyright 1989 Massachusetts Institute of Technology
  5730.  *
  5731.  * Permission to use, copy, modify, distribute, and sell this software and its
  5732.  * documentation for any purpose is hereby granted without fee, provided that
  5733.  * the above copyright notice appear in all copies and that both that
  5734.  * copyright notice and this permission notice appear in supporting
  5735.  * documentation, and that the name of M.I.T. not be used in advertising or
  5736.  * publicity pertaining to distribution of the software without specific,
  5737.  * written prior permission.  M.I.T. makes no representations about the
  5738.  * suitability of this software for any purpose.  It is provided "as is"
  5739.  * without express or implied warranty.
  5740.  *
  5741.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  5742.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  5743.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  5744.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  5745.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  5746.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  5747.  *
  5748.  * Original Athena Author:  Chris D. Peterson, MIT X Consortium
  5749.  */
  5750.  
  5751. #ifndef _MULTILIST_H_
  5752. #define _MULTILIST_H_
  5753.  
  5754. #include <X11/Xaw/Simple.h>
  5755.  
  5756. /*---------------------------------------------------------------------------*
  5757.  
  5758.       R E S O U R C E    D E S C R I P T I O N S    A N D    N O T E S
  5759.  
  5760.  *---------------------------------------------------------------------------*/
  5761.  
  5762. /*
  5763.  
  5764.  Name             Class        RepType        Default Value
  5765.  ----             -----        -------        -------------
  5766.  background         Background        Pixel        XtDefaultBackground
  5767.  border             BorderColor    Pixel        XtDefaultForeground
  5768.  borderWidth         BorderWidth    Dimension    1
  5769.  callback            Callback           XtCallbackList  NULL                *1
  5770.  columnWidth         Width              Dimension       0                   *9
  5771.  columnSpacing       Spacing            Dimension       8
  5772.  cursor             Cursor        Cursor        left_ptr
  5773.  defaultColumns      Columns            int             1                   *2
  5774.  destroyCallback     Callback        Pointer        NULL 
  5775.  font             Font        XFontStruct*    XtDefaultFont
  5776.  forceColumns        Columns            Boolean         False               *2
  5777.  foreground         Foreground        Pixel        XtDefaultForeground
  5778.  height             Height        Dimension    0                   *3
  5779.  highlightBackground HBackground    Pixel        XtDefaultForeground *4
  5780.  highlightForeground HForeground    Pixel        XtDefaultBackground *4
  5781.  insensitiveBorder   Insensitive    Pixmap        Gray
  5782.  list                List               String *        NULL                *5
  5783.  longest             Longest            int             0                   *6
  5784.  mappedWhenManaged   MappedWhenManaged    Boolean        True
  5785.  maxSelectable       Value              int             1                   *7
  5786.  numberStrings       NumberStrings      int             0                   *5
  5787.  pasteBuffer         Boolean            Boolean         False
  5788.  rowHeight           Height             Dimension       0                   *9
  5789.  rowSpacing          Spacing            Dimension       2
  5790.  sensitive         Sensitive        Boolean        True
  5791.  sensitiveArray      List               Boolean *       NULL                *8
  5792.  shadeSurplus         Boolean        Boolean        True            *10
  5793.  verticalList        Boolean            Boolean         False
  5794.  width             Width        Dimension    0
  5795.  x             Position        Position    0
  5796.  y             Position        Position    0
  5797.  
  5798.  *1 -  The callback functions are called whenever a highlight or unhighlight
  5799.        takes place.  More precisely, a callback occurs whenever the Notify()
  5800.        action is triggered.  By default, this occurs when the mouse button is
  5801.        lifted after a selection or deselection occurred.  The callback returns
  5802.        an XfwfMultiListReturnStruct data structure which contains numerous
  5803.        fields describing the selection state.  The most important fields
  5804.        indicate the total number of items selected, and a list of those items.
  5805.  
  5806.  *2 -  The defaultColumns resource is used in two cases.  If forceColumns
  5807.        is true, the widget will set the number of columns to the value of
  5808.        default columns.  If the widget width is unconstrained by the parent
  5809.        widgets, the defaultColumns is also used to determine the number of
  5810.        columns and the resulting width.  Otherwise, the number of columns
  5811.        will be calcultaed based on the current width and will be changed to
  5812.        an appropriate value.
  5813.  
  5814.  *3 -  If the width or height is set to zero (0), which is the default case,
  5815.        then the widget will calculate the size of that dimension to be just
  5816.        large enough to hold the contents of the widget.
  5817.  
  5818.  *4 -  The highlightForeground and highlightBackground colors specify the
  5819.        colors used to highlight the text (foreground) and the surrounding
  5820.        background space of a list item when it is selected (highlighted).
  5821.        The default is the reverse of the default foreground and background
  5822.        colors.
  5823.  
  5824.  *5 -  The list resource is an array of strings (char * array) which tell
  5825.        the names of each item of the list.  The number of elements of this
  5826.        array are indicated by the resource numberStrings.  If numberStrings
  5827.        is set to 0 (the default), then the MultiList widget will count the
  5828.        number of strings in the list.  This requires that the list be
  5829.        NULL terminated.  If list is NULL, then the widget treats it as an
  5830.        empty list.  Once the list is set the list resource is set to NULL,
  5831.        so you won't be able to read back the list after it has been set.  The
  5832.        widgets copies the strings internally, so the user can free the list
  5833.        storage after setting it.
  5834.  
  5835.  *6 -  This resource represent the longest string in pixels.  If this
  5836.        resource is zero (0), which is the default and probably the value
  5837.        most people should use, the longest string length is calculated
  5838.        and the resource is updated.
  5839.  
  5840.  *7 -  The maxSelectable resource indicates the maximum number of items
  5841.        which can be selected at any one time.  In the original Athena
  5842.        widget, you could have at most one item selected at a time.  In
  5843.        this widget, you can choose how many will be selected at a time.
  5844.  
  5845.  *8 -  Each item in the MultiList can be made insensitive, so it is printed in
  5846.        gray shading and can not be highlighted.  This can be done by
  5847.        setting the sensitivity list, which is an array of Booleans which
  5848.        indicate whether or not the corresponding item is sensitive (can be
  5849.        selected).  If sensitivity list is NULL, all items are sensitive.  The
  5850.        widget copies the sensitivity information, so the user can delete the
  5851.        sensitivity array storage after setting it.  The widget sets the
  5852.        resource to NULL after it has been set, so the user cannot read the
  5853.        old list back.
  5854.  
  5855.  *9 -  These values are intended for reading only.  They indicate the pixel
  5856.        width/height of the column/row.
  5857.  
  5858.  *10 - If the list height is made larger than the sum of the list entry
  5859.        heights, the surplus space is shaded in the background color if
  5860.        shadeSurplus is False, or in a gray stipple pattern if shadeSurplus
  5861.        is True.       
  5862.  
  5863. */
  5864.  
  5865. /*---------------------------------------------------------------------------*
  5866.  
  5867.                     S T R I N G    D E F I N I T I O N S
  5868.  
  5869.  *---------------------------------------------------------------------------*/
  5870.  
  5871. #define XtCList            "List"
  5872. #define XtCSpacing        "Spacing"
  5873. #define XtCColumns        "Columns"
  5874. #define XtCLongest        "Longest"
  5875. #define XtCNumberStrings    "NumberStrings"
  5876. #define    XtCHForeground        "HForeground"
  5877. #define    XtCHBackground        "HBackground"
  5878.  
  5879. #ifndef XtNcursor
  5880. #define XtNcursor        "cursor"
  5881. #endif
  5882.  
  5883. #define    XtNhighlightForeground    "highlightForeground"
  5884. #define    XtNhighlightBackground    "highlightBackground"
  5885. #define XtNcolumnSpacing    "columnSpacing"
  5886. #define XtNrowSpacing        "rowSpacing"
  5887. #define XtNdefaultColumns    "defaultColumns"
  5888. #define XtNforceColumns        "forceColumns"
  5889. #define XtNpasteBuffer        "pasteBuffer"
  5890. #define XtNverticalList        "verticalList"
  5891. #define XtNlongest        "longest"
  5892. #define XtNnumberStrings    "numberStrings"
  5893. #define XtNlist            "list"
  5894. #define    XtNsensitiveArray    "sensitiveArray"
  5895. #define    XtNmaxSelectable    "maxSelectable"
  5896. #define    XtNshadeSurplus        "shadeSurplus"
  5897.  
  5898. #define    XtNrowHeight        "rowHeight"
  5899. #define    XtNcolumnWidth        "columnWidth"
  5900.  
  5901.     /* Class Record Constants */
  5902.  
  5903. extern WidgetClass xfwfMultiListWidgetClass;
  5904.  
  5905. typedef struct _XfwfMultiListClassRec *XfwfMultiListWidgetClass;
  5906. typedef struct _XfwfMultiListRec      *XfwfMultiListWidget;
  5907.  
  5908. /*---------------------------------------------------------------------------*
  5909.  
  5910.                      R E T U R N    S T R U C T U R E
  5911.  
  5912.  *---------------------------------------------------------------------------*/
  5913.  
  5914. #define    XfwfMultiListActionNothing        0
  5915. #define    XfwfMultiListActionHighlight        1
  5916. #define    XfwfMultiListActionUnhighlight        2
  5917. #define    XfwfMultiListActionStatus        3
  5918.  
  5919. typedef struct _XfwfMultiListReturnStruct
  5920. {
  5921.     int num_selected;        /* Number Of Items Now Selected */
  5922.     int *selected_items;        /* Indexes Of Selected Items */
  5923.  
  5924.     int action;            /* Last Action Performed */
  5925.     int item;            /* Last Item Index Modified */
  5926.     String string;            /* String Of Last Index Modified */
  5927. } XfwfMultiListReturnStruct;
  5928.  
  5929. /*---------------------------------------------------------------------------*
  5930.  
  5931.                      U T I L I T Y    R O U T I N E S
  5932.  
  5933.  *---------------------------------------------------------------------------*/
  5934.  
  5935. #if (!NeedFunctionPrototypes)
  5936.  
  5937. extern Boolean        XfwfMultiListHighlightItem();
  5938. extern void        XfwfMultiListHighlightAll();
  5939. extern void        XfwfMultiListUnhighlightItem();
  5940. extern void        XfwfMultiListUnhighlightAll();
  5941. extern int        XfwfMultiListToggleItem();
  5942. extern XfwfMultiListReturnStruct *
  5943.             XfwfMultiListGetHighlighted();
  5944. extern Boolean        XfwfMultiListIsHighlighted();
  5945. extern Boolean        XfwfMultiListGetItemInfo();
  5946. extern void        XfwfMultiListSetNewData();
  5947.  
  5948. #else
  5949.  
  5950. extern Boolean        XfwfMultiListHighlightItem(XfwfMultiListWidget mlw,
  5951.                 int item_index);
  5952. extern void        XfwfMultiListHighlightAll(XfwfMultiListWidget mlw);
  5953. extern void        XfwfMultiListUnhighlightItem(XfwfMultiListWidget mlw,
  5954.                 int item_index);
  5955. extern void        XfwfMultiListUnhighlightAll(XfwfMultiListWidget mlw);
  5956. extern int        XfwfMultiListToggleItem(XfwfMultiListWidget mlw,
  5957.                 int item_index);
  5958. extern XfwfMultiListReturnStruct *
  5959.             XfwfMultiListGetHighlighted(XfwfMultiListWidget mlw);
  5960. extern Boolean        XfwfMultiListIsHighlighted(XfwfMultiListWidget mlw,
  5961.                 int item_index);
  5962. extern Boolean        XfwfMultiListGetItemInfo(XfwfMultiListWidget mlw,
  5963.                 int item_index, String *str_ptr,
  5964.                 Boolean *h_ptr, Boolean *s_ptr);
  5965. extern void        XfwfMultiListSetNewData(XfwfMultiListWidget mlw,
  5966.                 String *list, int nitems, int longest,
  5967.                 int resize, Boolean *sensitivity_array);
  5968.  
  5969. #endif
  5970. #endif
  5971. SHAR_EOF
  5972. fi
  5973. if test -f 'MultiListP.h'
  5974. then
  5975.     echo shar: "will not over-write existing file 'MultiListP.h'"
  5976. else
  5977. cat << \SHAR_EOF > 'MultiListP.h'
  5978. /****************************************************************************
  5979.  
  5980.     MultiListP.h
  5981.  
  5982.     This file is the private header file for the MultiList widget, an
  5983.     extension to the Athena List widget.
  5984.  
  5985.     This code is loosely based on the Athena List source which
  5986.     is why the MIT copyright notice appears below.
  5987.  
  5988.     The code was changed substantially in V3.4 to change the
  5989.     action/callback interface which was unnecessarily ugly.  Code
  5990.     using some features of the old interface may need to be changed.
  5991.     Hope the changes don't make people's lives too miserable.
  5992.  
  5993.  ****************************************************************************/
  5994.  
  5995. /*
  5996.  * Author:
  5997.  *     Brian Totty
  5998.  *     Department of Computer Science
  5999.  *     University Of Illinois at Urbana-Champaign
  6000.  *    1304 West Springfield Avenue
  6001.  *     Urbana, IL 61801
  6002.  * 
  6003.  *     totty@cs.uiuc.edu
  6004.  *     
  6005.  */ 
  6006.  
  6007. /*
  6008.  * Copyright 1989 Massachusetts Institute of Technology
  6009.  *
  6010.  * Permission to use, copy, modify, distribute, and sell this software and its
  6011.  * documentation for any purpose is hereby granted without fee, provided that
  6012.  * the above copyright notice appear in all copies and that both that
  6013.  * copyright notice and this permission notice appear in supporting
  6014.  * documentation, and that the name of M.I.T. not be used in advertising or
  6015.  * publicity pertaining to distribution of the software without specific,
  6016.  * written prior permission.  M.I.T. makes no representations about the
  6017.  * suitability of this software for any purpose.  It is provided "as is"
  6018.  * without express or implied warranty.
  6019.  *
  6020.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  6021.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  6022.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  6023.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  6024.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  6025.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  6026.  *
  6027.  * Original Athena Author:  Chris D. Peterson, MIT X Consortium
  6028.  */
  6029.  
  6030. #ifndef _MULTILISTP_H_
  6031. #define _MULTILISTP_H_
  6032.  
  6033. #include <X11/Xaw/SimpleP.h>
  6034. #include "MultiList.h"
  6035.  
  6036. /*---------------------------------------------------------------------------*
  6037.  
  6038.       L O C A L    D A T A    S T R U C T U R E    D E F I N I T I O N S
  6039.  
  6040.  *---------------------------------------------------------------------------*/
  6041.  
  6042. typedef    struct
  6043. {
  6044.     Boolean        sensitive;
  6045.     Boolean        highlighted;
  6046.     String        string;
  6047. } XfwfMultiListItem;
  6048.  
  6049. /*---------------------------------------------------------------------------*
  6050.  
  6051.      W I D G E T    D A T A    S T R U C T U R E    D E F I N I T I O N S
  6052.  
  6053.  *---------------------------------------------------------------------------*/
  6054.  
  6055. typedef struct
  6056. {
  6057.     int        foo;
  6058. } XfwfMultiListClassPart;
  6059.  
  6060. typedef struct _XfwfMultiListClassRec
  6061. {
  6062.     CoreClassPart        core_class;
  6063.     SimpleClassPart        simple_class;
  6064.     XfwfMultiListClassPart    multiList_class;
  6065. } XfwfMultiListClassRec;
  6066.  
  6067. extern XfwfMultiListClassRec xfwfMultiListClassRec;
  6068.  
  6069. typedef struct
  6070. {
  6071.     Pixel            foreground;
  6072.     Pixel            highlight_fg;
  6073.     Pixel            highlight_bg;
  6074.     Dimension        column_space;
  6075.     Dimension        row_space;
  6076.     int            default_cols;
  6077.     Boolean            force_cols;
  6078.     Boolean            paste;
  6079.     Boolean            row_major;
  6080.     int            longest;
  6081.     int            nitems;
  6082.     XFontStruct        *font;
  6083.     String            *list;
  6084.     Boolean            *sensitive_array;
  6085.     XtCallbackList      callback;
  6086.     int            max_selectable;
  6087.     Boolean            shade_surplus;
  6088.     Dimension        col_width;
  6089.     Dimension        row_height;
  6090.  
  6091.     int            right_padding;
  6092.     int            bottom_padding;
  6093.     int            nrows;
  6094.     int            ncols;
  6095.     int            most_recent_clicked_item;
  6096.     int            most_recent_action;
  6097.     GC            erase_gc;
  6098.     GC            draw_gc;
  6099.     GC            highlight_bg_gc;
  6100.     GC            highlight_fg_gc;
  6101.     GC            gray_gc;
  6102.     XfwfMultiListItem    *item_array;
  6103.     int            num_selected;
  6104.     int            *sel_array;
  6105. } XfwfMultiListPart;
  6106.  
  6107. typedef struct _XfwfMultiListRec
  6108. {
  6109.     CorePart        core;
  6110.     SimplePart        simple;
  6111.     XfwfMultiListPart    multiList;
  6112. } XfwfMultiListRec;
  6113.  
  6114. /*---------------------------------------------------------------------------*
  6115.  
  6116.           D A T A    S T R U C T U R E    A C C E S S    M A C R O S
  6117.  
  6118.  *---------------------------------------------------------------------------*/
  6119.  
  6120. #define    MultiListItemSensitive(i)    ((i)->sensitive)
  6121. #define    MultiListItemHighlighted(i)    ((i)->highlighted)
  6122. #define    MultiListItemString(i)        ((i)->string)
  6123.  
  6124. #define    InstanceCore(w)            (&((w)->core))
  6125. #define    InstanceSimple(w)        (&((w)->simple))
  6126. #define    InstanceMultiList(w)        (&((w)->multiList))
  6127.  
  6128. #define    MultiListWidth(w)        (InstanceCore(w)->width)
  6129. #define    MultiListHeight(w)        (InstanceCore(w)->height)
  6130. #define    MultiListBG(w)            (InstanceCore(w)->background_pixel)
  6131. #define    MultiListSensitive(w)        (InstanceCore(w)->sensitive)
  6132. #define    MultiListAncesSensitive(w)    (InstanceCore(w)->ancestor_sensitive)
  6133. #define    MultiListDepth(w)        (InstanceCore(w)->depth)
  6134.  
  6135. #define    MultiListFG(w)            (InstanceMultiList(w)->foreground)
  6136. #define    MultiListHighlightFG(w)        (InstanceMultiList(w)->highlight_fg)
  6137. #define    MultiListHighlightBG(w)        (InstanceMultiList(w)->highlight_bg)
  6138. #define    MultiListColumnSpace(w)        (InstanceMultiList(w)->column_space)
  6139. #define    MultiListRowSpace(w)        (InstanceMultiList(w)->row_space)
  6140. #define    MultiListDefaultCols(w)        (InstanceMultiList(w)->default_cols)
  6141. #define    MultiListForceCols(w)        (InstanceMultiList(w)->default_cols)
  6142. #define    MultiListPaste(w)        (InstanceMultiList(w)->paste)
  6143. #define    MultiListRowMajor(w)        (InstanceMultiList(w)->row_major)
  6144. #define    MultiListLongest(w)        (InstanceMultiList(w)->longest)
  6145. #define    MultiListNumItems(w)        (InstanceMultiList(w)->nitems)
  6146. #define    MultiListFont(w)        (InstanceMultiList(w)->font)
  6147. #define    MultiListList(w)        (InstanceMultiList(w)->list)
  6148. #define    MultiListSensitiveArray(w)    (InstanceMultiList(w)->sensitive_array)
  6149. #define    MultiListCallback(w)        (InstanceMultiList(w)->callback)
  6150. #define    MultiListMaxSelectable(w)    (InstanceMultiList(w)->max_selectable)
  6151. #define    MultiListShadeSurplus(w)    (InstanceMultiList(w)->shade_surplus)
  6152.  
  6153. #define    MultiListColWidth(w)        (InstanceMultiList(w)->col_width)
  6154. #define    MultiListRowHeight(w)        (InstanceMultiList(w)->row_height)
  6155. #define    MultiListRightPadding(w)    (InstanceMultiList(w)->right_padding)
  6156. #define    MultiListBottomPadding(w)    (InstanceMultiList(w)->bottom_padding)
  6157. #define    MultiListNumRows(w)        (InstanceMultiList(w)->nrows)
  6158. #define    MultiListNumCols(w)        (InstanceMultiList(w)->ncols)
  6159. #define    MultiListMostRecentItem(w)    (InstanceMultiList(w)->most_recent_clicked_item)
  6160. #define    MultiListMostRecentAct(w)    (InstanceMultiList(w)->most_recent_action)
  6161. #define    MultiListEraseGC(w)        (InstanceMultiList(w)->erase_gc)
  6162. #define    MultiListDrawGC(w)        (InstanceMultiList(w)->draw_gc)
  6163. #define    MultiListHighlightForeGC(w)    (InstanceMultiList(w)->highlight_fg_gc)
  6164. #define    MultiListHighlightBackGC(w)    (InstanceMultiList(w)->highlight_bg_gc)
  6165. #define    MultiListGrayGC(w)        (InstanceMultiList(w)->gray_gc)
  6166. #define    MultiListItemArray(w)        (InstanceMultiList(w)->item_array)
  6167. #define    MultiListNthItem(w,n)        (&(MultiListItemArray(w)[n]))
  6168. #define    MultiListSelArray(w)        (InstanceMultiList(w)->sel_array)
  6169. #define    MultiListNumSelected(w)        (InstanceMultiList(w)->num_selected)
  6170.  
  6171. #endif
  6172. SHAR_EOF
  6173. fi
  6174. if test -f 'Prop.lst'
  6175. then
  6176.     echo shar: "will not over-write existing file 'Prop.lst'"
  6177. else
  6178. cat << \SHAR_EOF > 'Prop.lst'
  6179.                              Smart-Go Properties 
  6180.  
  6181. mgt
  6182. supports
  6183.  
  6184. x       "B" : Black move                [move]
  6185. x       "W" : White move                [move]
  6186. x       "C" : Comment                   [Text]
  6187. x       "N" : Node Name                 [Text]
  6188.         "V" : Node value                [number]
  6189.         "CH": Check mark                [triple]
  6190.         "GB": good for black            [triple]
  6191.         "GW": good for white            [triple]
  6192.         "TE": good move (tesuji)        [triple]
  6193.         "BM": bad move                  [triple]
  6194.         "BL": time left for Black       [real]
  6195.         "WL": time left for White       [real]
  6196.         "FG": figure                    [none]
  6197. x       "AB": add black stones          [point list]
  6198. x       "AW": add white stones          [point list]
  6199. x       "AE": add empty stones          [point list]
  6200. x       "PL": player to play first      [color]
  6201. x       "GN": game name                 [text]
  6202. x       "GC": game comment              [text]
  6203. x       "EV": event (tournament)        [text]
  6204. x       "RO": round                     [text]
  6205. x       "DT": date                      [text]
  6206. x       "PC": place                     [text]
  6207. x       "PB": black player name         [text]
  6208. x       "PW": white player name         [text]
  6209. x       "RE": result, outcome           [text]
  6210. x       "US": user (who entered game)   [text]
  6211. x       "TM": time limit per player     [text]
  6212. x       "SO": source (book, journal...) [text]
  6213. x       "GM": game                      [number] (Go=1)
  6214. x       "SZ": board size                [number]
  6215.         "VW": partial view              [point list]
  6216.         "BS": black species             [number] (human=0, modem=-1, computer>0)
  6217.         "WS": white species             [number]
  6218.         "EL": evaluation of computer mv [number]
  6219.         "EX": expected next move        [move, game-specific]
  6220.         "SL": selected points           [point list, game-specific]
  6221. x       "M" : marked points             [point list, game-specific]
  6222. x       "L" : letters on points         [point list, game-specific]
  6223. x       "BR": Black's rank              [text]
  6224. x       "WR": White's rank              [text]
  6225. x       "HA": handicap                  [number]
  6226. x       "KM": komi                      [real]
  6227.         "TB": Black's territory         [point list]
  6228.         "TW": White's territory         [point list]
  6229.         "SC": secure stones             [point list]
  6230.         "RG": region of the board       [point list]
  6231.  
  6232. SHAR_EOF
  6233. fi
  6234. if test -f 'README'
  6235. then
  6236.     echo shar: "will not over-write existing file 'README'"
  6237. else
  6238. cat << \SHAR_EOF > 'README'
  6239. -----------------------------------------------------------------------
  6240.  
  6241.            "mgt" Copyright 1991 Shodan
  6242.         All Rights Reserved.
  6243.         Program by Greg Hale
  6244.  
  6245. Permission to use, copy, modify, and distribute this software and its
  6246. documentation for any purpose and without fee is hereby granted,
  6247. provided that this entire comment and copyright notice appear in all
  6248. copies and that both that copyright notice and this permission notice
  6249. appear in supporting documentation.  No representations are made about
  6250. the suitability of this software for any purpose.  It is provided "as
  6251. is" without express or implied warranty.
  6252.  
  6253. -----------------------------------------------------------------------
  6254.  
  6255. To compile under UNIX, type 'make'
  6256.  
  6257. Under VMS, delete the mou.c file and then type '@build'
  6258.  
  6259. Under MS-DOS with Borland-C, type 'make -f makefile.bc'
  6260.  
  6261. For the X version (X11R4) type xmkmf && make depend && make
  6262.  
  6263. *** Be sure to get the From My Go Teacher tutorial materials available
  6264. *** on anonymous ftp at ftp.u.washington.edu.
  6265.  
  6266. -----------------------------------------------------------------------
  6267.  
  6268. Please send copies of extensions to:  hale@scam.berkeley.edu
  6269.  
  6270. Thanks to the following for suggestions, debugging, code writing, and testing:
  6271.  
  6272.            mgt - you know why he's here :)
  6273.  
  6274.     Kurt Wallnau - for playing and suggesting
  6275.     Jeff Boscole - for sleepless nights of debugging and testing
  6276.     Thos Sumner  - for extensive help with explaining some UNIX particulars
  6277.  
  6278.     Adrian Mariano - (adrian@u.washington.edu) 
  6279.              - massive code extensions, plus IBM version
  6280.     Tim Casey      (tcasey@adobe.com) X11 version.
  6281.     Chien-Min Wang - X11 version niceness (I mean *really* niceness).
  6282.     Mike Dobbins - lots of testing, suggestions and comment editor rewrite
  6283.     Eric Osman   - for getting things to work under VMS
  6284.     Steve Hollasch - debugging assistance
  6285.     Huayong Yang - comments, bug reports
  6286.  
  6287. --------------------------------------
  6288. Changes:
  6289.  
  6290. 9/21/92 V2.3
  6291.     o Rewrite of the comment editor; edits comments up to 120 lines
  6292.       long; additional and user settable edit control commands
  6293.     o Fixed a few parsing bugs
  6294.  
  6295. 4/30/92 V2.2
  6296.     o Increased speed of moving backwards through game record or
  6297.       jumping to an arbitrary node.
  6298.     o Tutor mode
  6299.     o Support for informational properties
  6300.     o Support for PLayer property, and passing (as a move)
  6301.     o Removed restriction on number of letters or marks
  6302.     o Detection of ko during game play
  6303.     o For the IBM version: Mouse support and improved display
  6304.  
  6305. 4/5/91 V2.1
  6306.     o Short format game record support
  6307.     o Filename wild card support
  6308.     o Additional comment editor features
  6309.     o Improved game scoring
  6310.     o Other?
  6311.  
  6312. 2/1/91 V2.0
  6313.     o mgt is more optimized.
  6314.     o IBM version support
  6315.     o revision of display
  6316.     o fixed lots of little bugs
  6317.     o more commands
  6318.     o basic editing of comments
  6319.     o save & load
  6320.     o play-by-mail facility added.
  6321.  
  6322. 2/6/90 V1.0
  6323.     o First release.  All is holding together fine, but no
  6324.       optimization has been done yet.  That is next on the list.  
  6325.       My apologies to the CPU's. :(
  6326. SHAR_EOF
  6327. fi
  6328. if test -f 'README.X11'
  6329. then
  6330.     echo shar: "will not over-write existing file 'README.X11'"
  6331. else
  6332. cat << \SHAR_EOF > 'README.X11'
  6333. ----------------------------------------------------------------------------
  6334.         README FILE OF THE X11 INTERFACE FOR MGT 2.3
  6335.  
  6336.             version 0.94 released 2.4.93
  6337.  
  6338.     Programmed by:    Chien-Min Wang, cmwang@iis.sinica.edu.tw
  6339.             Tim Casey, tcasey@adobe.com
  6340.  
  6341.  
  6342. This program is distributed in the hope that it will be useful.
  6343. Use and copying of this software and preparation of derivative works
  6344. based upon this software are permitted, so long as the following
  6345. conditions are met:
  6346.        o credit to the authors is acknowledged
  6347.        o no fees or compensation are charged for use, copies, or
  6348.          access to this software
  6349.        o this copyright notice is included intact.
  6350. This software is made available AS IS, and no warranty is made about
  6351. the software or its performance.
  6352.  
  6353. Bug descriptions, use reports, comments or suggestions are welcome.
  6354. Send them to   cmwang@iis.sinica.edu.tw tcasey@adobe.com, yes both.
  6355.  
  6356. ----------------------------------------------------------------------------
  6357.  
  6358. Thanks to the following for suggestions, code writing, and testing:
  6359.  
  6360.     Adrian Mariano    - for suggestiions, and testing
  6361.  
  6362.     Stephen Coffin    - for code writing
  6363.               (the interface to IGS uses part of his xigs program)
  6364.  
  6365.     Antoine Dumesnil de Maricourt
  6366.             - for code writing
  6367.               (the prompting box uses part of his xgoban program)
  6368.  
  6369.     Brian Totty    - for code writing
  6370.               (the file selector uses his file selector widget)
  6371.  
  6372. ----------------------------------------------------------------------------
  6373.  
  6374. Changes:
  6375.  
  6376. Version 0.94:
  6377.     1. Rearrange menu entries.
  6378.     2. Correct a bug in save screen dialog box.
  6379.     3. Enhance the message shown in message box.
  6380.     4. Some minor correction to version 0.93.
  6381.  
  6382. Version 0.93:
  6383.     1. Some minor correction to version 0.92.
  6384.  
  6385. Version 0.92:
  6386.     1. Support of Hierarchical File Selector (HFS).
  6387.     2. Some minor correction to version 0.91.
  6388.  
  6389. Version 0.91:
  6390.     1. Some minor correction to version 0.90.
  6391.  
  6392. Version 0.90:
  6393.     1. The first formal version of xmgt.
  6394.     2. Support of Internet Go Server (IGS).
  6395.  
  6396. ----------------------------------------------------------------------------
  6397.  
  6398. Answers to some bug reports and frequently asked questions
  6399.  
  6400.  
  6401. Question:
  6402.     How do I build xmgt?
  6403. Answer:
  6404.     xmkmf && make depend && make
  6405.     If you do not want the Hierarchical File Selector, remove the
  6406.     '-DXMGT_HFS' from the imakefile.  The imakefile could be buggy.
  6407.     Please bear with us.
  6408.  
  6409.  
  6410. Question:
  6411.     How do I build xmgt manually?
  6412. Answer:
  6413.     make -f Makefile.1 xmgt
  6414.     If you can't build xmgt automatically by the above method, you may try 
  6415.     this command to build it manually. If you do not want the Hierarchical 
  6416.     File Selector, remove the '-DXMGT_HFS' from the file Makefile.1.
  6417.  
  6418.  
  6419. Question:
  6420.     How to use the Hierarchical File Selector?
  6421. Answer:
  6422.     It allows a user to move through the directory tree and select files. 
  6423.     It has two scrolled text lists side by side. The left list contains 
  6424.     the current directory path from the root to the current directory, 
  6425.     listed one directory per line. The right list shows the files in the 
  6426.     current directory. Files can be selected by clicking on the appropriate 
  6427.     file in the right list. New files can be keyed in through the file box. 
  6428.     Clicking on a directory will enter that directory and list its files 
  6429.     and directories.
  6430.  
  6431.  
  6432. Question:
  6433.     The variation window is so small, that no name of a variation will
  6434.     actually fit in it.
  6435. Answer:
  6436.     Use the scroll bar at the top of the variation window to see the rest
  6437.     part of names. If you prefer not to use the scroll bar, you may resize
  6438.     the whole window horizontally to widen the variation window.
  6439.  
  6440.  
  6441. Question:
  6442.     I can't type any characters at the promp to load a file. Similarly, 
  6443.     I can't type any characters into the "Go to Node" prompt. 
  6444. Answer:
  6445.     You shold move the cursor to the prompt before type in any characters.
  6446.  
  6447.  
  6448. Question:
  6449.     When I resize the screen, the board appears to be drawn twice, and the
  6450.     other elements of the screen are drawn several times as well.
  6451. Answer:
  6452.     Partly corrected.
  6453.     The borders of board, buttons, and variations might be drawn twice, 
  6454.     but the other elements are drawn only once.
  6455.  
  6456.  
  6457. Question:
  6458.     When I select the load file option from the file menu, I get a prompt 
  6459.     window.  The title on the window is "pshell" and when I double click 
  6460.     on the icon in the upper left corner of the window's border (an action 
  6461.     which kills the window under my window server) both the prompt window, 
  6462.     and all of xmgt are killed.  If I click only once, I get a menu with 
  6463.     options like "close". 
  6464. Answer:
  6465.     It never happened on my computer. So, it is difficult for me to figure 
  6466.     out how it occurs. Several changes are made in the hope that the bug 
  6467.     will be fixed. If it occurs on your computer or you know how to fix 
  6468.     the bug, please send a mail to cmwang@iis.sinica.edu.tw.
  6469.  
  6470.  
  6471. Question:
  6472.     I can't figure out how to use the internet go server related part.
  6473. Answer:
  6474.     The program is not yet completed. Please do not send any bug report 
  6475.     to the authors. If you'd like to try the program in advance, follow 
  6476.     the following instructions.
  6477.  
  6478.         1. Before compile the program, append '-DXMGT_IGS' to the second 
  6479.        line of the file imakefile (for automatic compilation) or to 
  6480.        the first line of the file Makefile.1 (for manual compilation).
  6481.  
  6482.         2. The program must be executed in the foreground. To execute the 
  6483.        program alone, type 'xmgt'. To execute the program in connection 
  6484.        with IGS, type 'telnet [address] [port] | xmgt'.
  6485.        
  6486.     3. Remember to set client mode true in IGS and to set tutor mode 
  6487.        false in xmgt (the default is false).
  6488.  
  6489.         4. Only one game can be observed/played at a time. Remember to type 
  6490.        'moves [game_no]' immediately after you type 'observe [game_no]' 
  6491.        or 'load [game_name]'.
  6492.        
  6493.     5. Do not modify the board when you are observeing/playing a game.
  6494.  
  6495.     6. You can traverse the board when you are observing/playing a game.
  6496.        Remember to set tutor mode true before you traverse the board.
  6497.        To continue observing/playing, you should move to the end of 
  6498.        variation and then set tutor mode false.
  6499.  
  6500.  
  6501. SHAR_EOF
  6502. fi
  6503. if test -f 'RegExp.c'
  6504. then
  6505.     echo shar: "will not over-write existing file 'RegExp.c'"
  6506. else
  6507. cat << \SHAR_EOF > 'RegExp.c'
  6508. /****************************************************************************
  6509.  
  6510.     RegExp.c
  6511.  
  6512.     This file contains the C code for the regular expression
  6513.     matching code.
  6514.  
  6515.     The routines supported act as a more friendly, user level
  6516.     interface to the regexp regular expression matching system.
  6517.  
  6518.  ****************************************************************************/
  6519.  
  6520. /*
  6521.  * Author:
  6522.  *     Brian Totty
  6523.  *     Department of Computer Science
  6524.  *     University Of Illinois at Urbana-Champaign
  6525.  *    1304 West Springfield Avenue
  6526.  *     Urbana, IL 61801
  6527.  * 
  6528.  *     totty@cs.uiuc.edu
  6529.  *     
  6530.  */ 
  6531.  
  6532. #include "RegExp.h"
  6533. /*    modified by Chien-Min Wang, 1/15/93
  6534. #include <regexp.h>
  6535. */
  6536. #define NO_REGEXP
  6537.  
  6538. void RegExpCompile(regexp,fsm_ptr,fsm_length)
  6539. char *regexp,*fsm_ptr;
  6540. int fsm_length;
  6541. {
  6542. #ifndef NO_REGEXP
  6543.     compile(regexp,fsm_ptr,&(fsm_ptr[fsm_length]),'\0');
  6544. #endif
  6545. } /* End RegExpCompile */
  6546.  
  6547.  
  6548. int RegExpMatch(string,fsm_ptr)
  6549. char *string,*fsm_ptr;
  6550. {
  6551. #ifndef NO_REGEXP
  6552.     if (advance(string,fsm_ptr) != 0)
  6553.         return(TRUE);
  6554.         else
  6555.         return(FALSE);
  6556. #else
  6557.     return(TRUE);
  6558. #endif
  6559. } /* End RegExpMatch */
  6560.  
  6561.  
  6562. void _RegExpError(val)
  6563. int val;
  6564. {
  6565.     void fprintf();
  6566.  
  6567.     fprintf(stderr,"Regular Expression Error %d\n",val);
  6568.     exit(-1);
  6569. } /* End _RegExpError */
  6570.  
  6571.  
  6572. void RegExpPatternToRegExp(pattern,reg_exp)
  6573. char *pattern,*reg_exp;
  6574. {
  6575.     int in_bracket;
  6576.  
  6577.     in_bracket = 0;
  6578.     while (*pattern != '\0')
  6579.     {
  6580.         if (in_bracket)
  6581.         {
  6582.             if (*pattern == ']') in_bracket = 0;
  6583.             *reg_exp++ = *pattern++;
  6584.         }
  6585.             else
  6586.         {
  6587.             switch (*pattern)
  6588.             {
  6589.                 case '[':
  6590.                 in_bracket = 1;
  6591.                 *reg_exp++ = '[';
  6592.                 break;
  6593.                 case '?':
  6594.                 *reg_exp++ = '.';
  6595.                 break;
  6596.                 case '*':
  6597.                 *reg_exp++ = '.';
  6598.                 *reg_exp++ = '*';
  6599.                 break;
  6600.                 case '.':
  6601.                 *reg_exp++ = '\\';
  6602.                 *reg_exp++ = '.';
  6603.                 break;
  6604.                 default:
  6605.                 *reg_exp++ = *pattern;
  6606.                 break;
  6607.             }
  6608.             ++ pattern;
  6609.         }
  6610.     }
  6611.     *reg_exp++ = '$';
  6612.     *reg_exp++ = '\0';
  6613. } /* End RegExpPatternToRegExp */
  6614. SHAR_EOF
  6615. fi
  6616. if test -f 'RegExp.h'
  6617. then
  6618.     echo shar: "will not over-write existing file 'RegExp.h'"
  6619. else
  6620. cat << \SHAR_EOF > 'RegExp.h'
  6621. /****************************************************************************
  6622.  
  6623.     RegExp.h
  6624.  
  6625.     This file contains the C definitions and declarations for
  6626.     the regular expression matching code.
  6627.  
  6628.     The routines supported act as a more friendly, user level
  6629.     interface to the regexp regular expression matching system.
  6630.  
  6631.  ****************************************************************************/
  6632.  
  6633. /*
  6634.  * Author:
  6635.  *     Brian Totty
  6636.  *     Department of Computer Science
  6637.  *     University Of Illinois at Urbana-Champaign
  6638.  *    1304 West Springfield Avenue
  6639.  *     Urbana, IL 61801
  6640.  * 
  6641.  *     totty@cs.uiuc.edu
  6642.  *     
  6643.  */ 
  6644.  
  6645. #ifndef _REGEXP_H_
  6646. #define    _REGEXP_H_
  6647.  
  6648. #include <stdio.h>
  6649.  
  6650. #if (!NeedFunctionPrototypes)
  6651.  
  6652. void    RegExpCompile();
  6653. int    RegExpMatch();
  6654. void    _RegExpError();
  6655. void    RegExpPatternToRegExp();
  6656.  
  6657. #else
  6658.  
  6659. void    RegExpCompile(char *regexp, char *fsm_ptr, int fsm_length);
  6660. int    RegExpMatch(char *string, char *fsm_ptr);
  6661. void    _RegExpError(int val);
  6662. void    RegExpPatternToRegExp(char *pattern, char *reg_exp);
  6663.  
  6664. #endif
  6665.  
  6666. #ifndef TRUE
  6667. #define TRUE                1
  6668. #endif
  6669.  
  6670. #ifndef FALSE
  6671. #define    FALSE                0
  6672. #endif
  6673.  
  6674. #define    INIT        register char *sp = instring;
  6675. #define    GETC()        (*sp++)
  6676. #define    PEEKC()        (*sp)
  6677. #define    UNGETC(c)    -- sp
  6678. #define    RETURN(ptr)    return;
  6679. #define    ERROR(val)    _RegExpError(val)
  6680.  
  6681. #endif
  6682. SHAR_EOF
  6683. fi
  6684. if test -f 'Rules'
  6685. then
  6686.     echo shar: "will not over-write existing file 'Rules'"
  6687. else
  6688. cat << \SHAR_EOF > 'Rules'
  6689. This files contains rules to the game of Go in Smart-Go format.  It should be 
  6690. viewed with the mgt program.
  6691.  
  6692. (
  6693. ;
  6694. GaMe[1]
  6695. VieW[]
  6696. SiZe[19]
  6697. Comment[        THE GAME OF GO
  6698.       A Brief Introduction
  6699.  
  6700.        by Adrian Mariano
  6701.  
  6702.  
  6703.  
  6704.    press . to move forward
  6705.    press , to move backward
  6706.    (in the X version make
  6707.     sure the sprite is over
  6708.     the board window.)
  6709. ]
  6710. ;
  6711. Comment[Go is a two player strategy board game.  Players take turns putting black and white pieces \(called stones\) on the board.  The board is normally a 19x19 grid.  The stones are placed on the intersections.  Once played, a stone cannot be moved, though it may be captured by the other player.  The object of the game is to surround territory.]
  6712. ;
  6713. Comment[There are three major scoring systems for Go:  Japanese, Chinese and Ing.  This tutorial describes the Japanese system, which is the most common in Western countries.  Under Japanese rules, a completed game is scored as follows:  each intersection surrounded and each prisoner captured count as a point. The player with the most points wins.]
  6714. ;
  6715. Comment[When a player has nothing left to do, he passes.  After two consecutive passes, the game is over.]
  6716. ;
  6717. Comment[An empty intersection adjacent to a stone \(orthogonally\) is called a liberty. 
  6718.  
  6719. The white stone in the center of the board has 4 liberties, the marked spots.  The white stone at the bottom has three liberties, and the white stone in corner has two liberties.]
  6720. AddWhite[jj][js][ss]
  6721. Mark[ij][ji][kj][jk][is][jr][ks][rs][sr]
  6722. AddEmpty[aa]
  6723. ;
  6724. AddBlack[dc][dd][ed][fd][fe][ge]
  6725. Comment[Groups of stones that are connected orthogonally can be captured all at once by removing all of their liberties.  The black stones are orthogonally connected and have 11 liberties.  The white stones are not orthogonally connected.]
  6726. AddWhite[in][io][jn][jo][kl][km][ll][lm]
  6727. Mark[ff][gf][he][gd][ee][de][cd][fc][ec][cc][db]
  6728. AddEmpty[aa][ep][fp][gp][jj][jp][jq][js][kj][kk][kp][lk][lp][mp][na][np][ob][pb][pc][qd][qk][qm][rb][re][ri][rj][rk][rm][rn][ro][rp][sd][se][si][sp][ss]
  6729. ;
  6730. AddBlack[ij][ji][jj]
  6731. AddEmpty[aa][dc][dd][ed][ep][fd][fe][fp][ge][gp][hj][in][io][jn][jo][jp][jq][kl][km][kp][ll][lm][lp][mp][na][np][ob][pb][pc][qd][qk][ql][qm][rb][re][ri][rj][rk][rm][rn][ro][rp][sd][se][si][sp]
  6732. Comment[A group is captured if its last liberty is taken away.
  6733.  
  6734.  
  6735. Here is a black group with seven liberties.]
  6736. ;
  6737. AddWhite[hj]
  6738. Comment[A single white stone next to the group reduces it to six liberties.]
  6739. ;
  6740. AddWhite[ik][jh][jk][ki][kj]
  6741. Comment[Six white stones reduces the group to one liberty \(remember that play alternates black and white.  These stones could not be placed like this during a game.\)]
  6742. ;
  6743. White[ii]
  6744. Comment[The final white move captures the black group.]
  6745. ;
  6746. AddWhite[qh][qi][qj][rg][rk][sg][sk]
  6747. AddBlack[rh][ri][rj][sh][sj]
  6748. AddEmpty[aa][hj][ii][ik][jh][jk][ki][kj]
  6749. Comment[The black group has only one liberty.  White can capture the black group by playing inside black at T11.]
  6750. ;
  6751. White[si]
  6752. ;
  6753. AddBlack[rh][ri][rj][sh][sj]
  6754. Comment[It is illegal to comit suicide.  White cannot play at T11 now, because the move does not capture the black group, and the white stone at T11 would have no liberties.]
  6755. AddWhite[qh][qj][rg][rk][sg][sk]
  6756. AddEmpty[aa][qi][si]
  6757. ;
  6758. Comment[Another rule of Go is the Ko rule.  It is illegal to make a move which recreates preceeding board positions \(to prevent loops\).
  6759.  
  6760.  
  6761. Suppose black captures the white stone at J12.]
  6762. AddBlack[hh][ig][ii]
  6763. AddWhite[ih][jg][ji][kh]
  6764. AddEmpty[aa][ab][ac][aq][ar][bb][bc][bq][br][bs][ca][cb][cc][cq][cr][da][db][dc][dq][dr][ds][eq][er][es][qg][qh][qi][qj][qk][ql][rf][rg][rh][ri][rj][rk][rl][sf][sg][sh][sj][sk][sl]
  6765. ;
  6766. Black[jh]
  6767. Comment[If white were allowed to play at J12 now, the board would look exactly as it did before.]
  6768. ;
  6769. AddEmpty[jh]
  6770. AddWhite[ih]
  6771. Comment[This white move is ILLEGAL.  White must wait a turn before making this move, giving black the option of filling in the hole at J12.]
  6772. ;
  6773. AddEmpty[aa][hh][ig][ih][ii][jg][ji][kh][ph][qh][qj][rg][rh][ri][rj][rk][sg][sh][sj][sk]
  6774. Comment[The concept of life is an important, and tricky one.  You must know how to make a living group.  A living group is one that can't be captured.  
  6775.  
  6776.  
  6777. A liberty which is inside a group and completely surrounded is called an eye.  A group with two disconnected eyes cannot be captured.]
  6778. ;
  6779. AddBlack[ic][id][ie][jc][je][jj][jk][jl][kc][kd][ke][kj][kl][lc][le][lj][lk][ll][mc][md][me]
  6780. AddWhite[hc][hd][he][ib][if][ij][ik][il][jb][jf][ji][jm][kb][kf][ki][km][lb][lf][li][lm][mb][mf][mj][mk][ml][nc][nd][ne]
  6781. AddEmpty[aa][hb][hf][ii][im][mi][mm][nb][nf]
  6782. Comment[The black group above cannot be captured, because it has two eyes, the points K16 and M16.  White cannot play in either eye, because his stone would have no liberties.
  6783.  
  6784. White CAN capture the lower group, however, because it has only a single eye, and a white stone played within it reduces black to zero liberties.]
  6785. ;
  6786. White[kk]
  6787. ;
  6788. AddWhite[aq][ar][bq][bs][cq][cr][cs]
  6789. AddBlack[ap][bp][cp][dp][dq][dr][ds]
  6790. AddEmpty[aa][hc][hd][he][ib][ic][id][ie][if][ij][ik][il][jb][jc][je][jf][ji][jm][kb][kc][kd][ke][kf][ki][kk][km][lb][lc][le][lf][li][lm][mb][mc][md][me][mf][mj][mk][ml][nc][nd][ne]
  6791. Comment[Here is another example of a living group.  Black cannot capture the white group, because it has two eyes at A1 and B2.  Black cannot play at either of these points, because the black stone would have no liberties.]
  6792. ;
  6793. Comment[The black group here has only ONE eye.  If black does not make further moves in this area, white can capture black.  \(More on this shape later.\)]
  6794. AddBlack[ap][bp][cp][cq][cr][cs]
  6795. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  6796. AddEmpty[aa][aq][ar][bq][br][bs]
  6797. ;
  6798. AddBlack[ao][bo][co][do][eo][fo][go][ho][hp][hq][hr][hs]
  6799. AddWhite[ap][bp][cp][cr][dp][dq][dr][ds][ep][fp][gp][gq][gr][gs]
  6800. Comment[The white group here is also alive.  If black plays inside, white can safely ignore his plays completely.  White will be able to capture the black stones no matter what black does.  If black does this, white can gain points by simply passing.  ]
  6801. AddEmpty[aa][cq][cs]
  6802. ;
  6803. AddBlack[af][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][hc][ic][jc][kc][lc][ma][mb][mc]
  6804. AddWhite[ag][ai][ak][bh][bi][bj][ha][hb][ib][ja][jb][kb][la][lb]
  6805. AddEmpty[aa][ao][ap][bo][bp][co][cp][cr][do][dp][dq][dr][ds][eo][ep][fo][fp][go][gp][gq][gr][gs][ho][hp][hq][hr][hs]
  6806. Comment[Compare these two white groups.  The white group at the top is alive, because it has two eyes.  But beware!  The white group on the left side is dead!]
  6807. ;
  6808. Comment[The Ko rules prevents white from recapturing the stone at A12.  White must play somewhere else on the board, allowing black to capture the stones.]
  6809. Black[ah]
  6810. ;
  6811. Black[aj]
  6812. ;
  6813. Comment[Here is another example of a DEAD group.  The white group at the bottom does NOT have two eyes.]
  6814. AddBlack[lp][lq][lr][ls][mp][np][op][oq][or][pp][qp][rp][sp][sq][sr]
  6815. AddWhite[mr][ms][nr][os][pq][pr][ps][qq][rq][rr][rs]
  6816. AddEmpty[aa][af][ah][aj][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][ha][hb][hc][ib][ic][ja][jb][jc][kb][kc][la][lb][lc][ma][mb][mc][mq][nq]
  6817. ;
  6818. AddWhite[ar][br][cr][cs]
  6819. AddBlack[aq][bq][cq][dq][dr][ds]
  6820. AddEmpty[aa][ao][ap][bo][bp][co][cp][do][dp][eo][ep][fo][fp][go][gp][gq][gr][gs][ho][hp][hq][hr][hs][lp][lq][lr][ls][mp][mr][ms][np][nr][op][oq][or][os][pp][pq][pr][ps][qp][qq][rp][rq][rr][rs][sp][sq][sr]
  6821. Comment[In this example, the white group is dead.  There is nothing white can do to prevent black from capturing it.]
  6822. ;
  6823. Black[bs]
  6824. ;
  6825. White[as]
  6826. ;
  6827. Black[bs]
  6828. Comment[Notice that black had to sacrifice a stone to capture the white group, but black succeeds in the end.  Because both players can tell that black will be able to capture white, black does not actually need to play any stones.  This group is dead and will be removed at the end of the game.]
  6829. ;
  6830. AddWhite[ar][br][cr][dr][ds]
  6831. AddBlack[eq][er][es]
  6832. AddEmpty[aa][bs]
  6833. Comment[This case is more complicated.  If white plays first, then the group has two eyes and lives.]
  6834. ;
  6835. White[bs]
  6836. ;
  6837. Comment[On the other hand, if black plays first, the group is killed. ]
  6838. AddEmpty[aa][bs]
  6839. ;
  6840. Black[bs]
  6841. ;
  6842. White[cs]
  6843. ;
  6844. Black[as]
  6845. ;
  6846. Comment[In this case, the white group is alive, even if black plays first.]
  6847. AddWhite[ar][br][cr][dr][er][es]
  6848. AddBlack[aq][fq][fr][fs]
  6849. AddEmpty[aa][as][bs][en]
  6850. ;
  6851. Black[cs]
  6852. ;
  6853. White[bs]
  6854. ;
  6855. Comment[In this case, however, the white stones can be killed if black moves first.  \(If white plays first at B1, then they are alive.\)]
  6856. AddBlack[ap][bp][cp][dp][dq][eq][er][es]
  6857. AddWhite[aq][bq][cq][cr][ds]
  6858. AddEmpty[aa][ar][bn][br][bs][cs]
  6859. ;
  6860. Black[bs]
  6861. ;
  6862. White[br]
  6863. ;
  6864. Black[as]
  6865. ;
  6866. White[cs]
  6867. ;
  6868. Black[ar]
  6869. ;
  6870. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  6871. AddBlack[ap][bp][cp][cq][cr][cs]
  6872. AddEmpty[aa][aq][ar][as][bq][bs][eq][er][es][fq][fr][fs]
  6873. Comment[As promised, here is the situation we saw earlier.  This situation is similar to the preceeding one.  If black plays first, then black can live.]
  6874. ;
  6875. Black[br]
  6876. ;
  6877. White[ar]
  6878. ;
  6879. Black[aq]
  6880. ;
  6881. White[bs]
  6882. ;
  6883. Black[as]
  6884. ;
  6885. AddEmpty[aa][aq][ar][as][br][es]
  6886. Comment[If, however, white plays first, white can kill the black group.]
  6887. ;
  6888. White[br]
  6889. ;
  6890. Black[bs]
  6891. ;
  6892. White[ar]
  6893. ;
  6894. Black[aq]
  6895. ;
  6896. White[as]
  6897. ;
  6898. Black[bq]
  6899. ;
  6900. White[ar]
  6901. ;
  6902. Black[br]
  6903. ;
  6904. White[as]
  6905. ;
  6906. AddWhite[ab][ai][am][ar][bb][bi][bm][br][ca][cb][ci][cj][ck][cl][cm][cr][dr][ds][rh][ri][rj][rk][sg][si][sk]
  6907. AddBlack[ac][ah][ak][an][aq][bc][bh][bk][bn][bq][bs][cc][ch][cn][cq][da][db][dc][dh][di][dj][dk][dl][dm][dn][dq][eq][er][es][qg][qh][qi][qj][qk][ql][rf][rg][rl][sf][sl]
  6908. AddEmpty[aa][ao][as][bo][co][do][dp][sh]
  6909. Comment[Each of these groups is dead.  In all cases where a group can be considered dead, it can be removed from the board at the end of the game without further play.  It is NOT advantageous to capture groups which are dead, unless they threaten your position, because doing so reduces your own territory, and may allow your opponent to make important moves.]
  6910. ;
  6911. AddBlack[cj][ck][cl][cm][cn][co][db][dc][dd][de][df][dg][dj][do][ea][eb][eg][ej][eo][fa][fg][fj][fo][ga][gg][gj][gn][go][ha][hg][hj][hn][ia][ib][if][ig][ij][ik][il][im][in][jb][jc][jd][je][jf][jg][km][kn][ko][kp][kq][ll][lm][lq][lr][ml][mr][nl][nr][ol][or][pd][pe][pf][pg][ph][pl][pm][pq][pr][qc][qd][qh][qi][qm][qn][qo][qp][qq][rc][ri][sc][si]
  6912. AddWhite[dk][dl][dm][dn][ec][ed][ee][ef][ek][en][fb][fc][ff][fk][fn][gb][gf][gk][gm][hb][hc][he][hf][hk][hl][hm][ic][id][ie][ln][lo][lp][mm][mn][mp][mq][nm][nq][om][on][op][oq][pn][po][pp][qe][qf][qg][rd][re][rg][rh][sd][sh]
  6913. Comment[All of the white groups are dead if black moves first, but live if white moves first.  Can you find the move that kills each group?]
  6914. AddEmpty[aa][ab][ac][ah][ai][ak][al][am][an][aq][ar][bb][bc][bd][be][bh][bi][bk][bl][bm][bn][bq][br][bs][ca][cb][cc][ch][ci][cq][cr][da][dh][di][dq][dr][ds][eh][ei][el][eq][er][es][fh][fl][gh][gl][hh][ih][ii][jh][ji][jj][jk][kh][qj][qk][ql][rf][rj][rk][rl][sf][sg][sk][sl]
  6915. ;
  6916. AddEmpty[aa][cj][ck][cl][cm][cn][co][db][dc][dd][de][df][dg][dj][dk][dl][dm][dn][do][ea][eb][ec][ed][ee][ef][eg][ej][ek][en][eo][fa][fb][fc][ff][fg][fj][fk][fn][fo][ga][gb][gf][gg][gj][gk][gm][gn][go][ha][hb][hc][he][hf][hg][hj][hk][hl][hm][hn][ia][ib][ic][id][ie][if][ig][ij][ik][il][im][in][jb][jc][jd][je][jf][jg][km][kn][ko][kp][kq][ll][lm][ln][lo][lp][lq][lr][ml][mm][mn][mp][mq][mr][nl][nm][nq][nr][ol][om][on][op][oq][or][pd][pe][pf][pg][ph][pl][pm][pn][po][pp][pq][pr][qc][qd][qe][qf][qg][qh][qi][qm][qn][qo][qp][qq][rc][rd][re][rg][rh][ri][sc][sd][sh][si]
  6917. Comment[If there is debate over who owns a territory, or whether a group is alive, simply continue play until the players agree.]
  6918. ;
  6919. AddBlack[an][ap][bn][bo][bp][br][bs][cp][cs][dp][ds][ep][er][es][fp][gp][gq][gr][gs][hr][ir][is]
  6920. AddWhite[aq][ar][as][bq][cq][dq][eq][fq][fr][fs]
  6921. AddEmpty[ai][aj][ak][al][am][bi][bj][bk][bl][bm][cr][dr]
  6922. Comment[This situation is called seki.  Even though the white group and the black group contained inside do not have two eyes, they are considered alive.
  6923.  
  6924. The reason is that neither black nor white can make a move in the region.  ]
  6925. (
  6926. ;
  6927. White[cr]
  6928. Comment[If white attempts to capture black by playing inside...]
  6929. ;
  6930. Black[dr]
  6931. Comment[Then black captures the white stones.]
  6932. )
  6933. (
  6934. ;
  6935. Comment[If black tries to capture white by moving inside...]
  6936. Black[cr]
  6937. ;
  6938. Comment[Then white captures black, and now the white group is alive.  ]
  6939. White[dr]
  6940. ;
  6941. Comment[Notice that the black group around the very outside is clearly alive, with two eyes.  If white were able to surround and capture the black group, then he could break the deadlock and the situation would no longer be seki.]
  6942. ;
  6943. AddEmpty[aa][an][ap][aq][ar][as][bo][bp][bq][cp][cq][dp][dq][dr][ep][eq][fp][fq][fr][fs][gp][gq][gr][gs][hr][ir][is]
  6944. Comment[Examine this situation.  The white and black groups have started surrounding each other.  This is called a "capture race."  If white plays first, who will capture whom?]
  6945. AddWhite[bh][bi][bj][bn][cj][cm][cn][dk][dl]
  6946. AddBlack[bf][bk][bl][bm][cf][cg][ch][ci][ck][di][dj]
  6947. ;
  6948. White[am]
  6949. ;
  6950. Black[bg]
  6951. ;
  6952. White[al]
  6953. ;
  6954. Black[ah]
  6955. ;
  6956. White[ak]
  6957. ;
  6958. Black[ai]
  6959. ;
  6960. White[cl]
  6961. ;
  6962. Black[ag]
  6963. ;
  6964. White[aj]
  6965. ;
  6966. Comment[Connections of stones are very important.  If two groups each have one eye, they can live if they can be connected directly to each other.]
  6967. AddEmpty[aa][ag][ah][ai][aj][ak][al][am][bf][bg][bh][bi][bj][bn][cf][cg][ch][ci][cj][cl][cm][cn][di][dj][dk][dl]
  6968. AddBlack[aq][bq][cq][cr][dq][eq][fq][gq][gr][gs]
  6969. AddWhite[ar][br][bs][dr][ds][er][fr][fs]
  6970. (
  6971. ;
  6972. Black[cs]
  6973. Comment[If black plays here, then the two white groups will die, since each has only one eye.]
  6974. )
  6975. (
  6976. ;
  6977. White[cs]
  6978. Comment[If white plays C1, then his stones are connected into one group which has two eyes.]
  6979. ;
  6980. AddEmpty[aa][aq][ar][bq][br][bs][cq][cr][cs][dq][dr][ds][eq][er][fq][fr][fs][gq][gr][gs]
  6981. Comment[Obviously, this sort of loose connection only works if it happens to be white's turn.  It is not reasonable to play all your stones solidly connected, because you will not be able to get much territory.  You must instead make different types of connections which can be fortified when they are attacked.]
  6982. ;
  6983. Comment[In this situation, the black stones can be considered connected, even though they are not yet orthogonally connected directly.]
  6984. AddWhite[ah][al][bh][bl][ch][ci][ck][cl][di][dk][dl][ei][el][fi][fl][gi][gj][gl][gm][hi][hm][ii][im][ji][jm][ki][kj][kk][kl][km]
  6985. AddBlack[ai][ak][bi][bj][bk][cj][dj][ej][fk][gk][hj][hk][hl][ij][il][jj][jk][jl]
  6986. AddEmpty[aa][cs][ek][fj][lj][lk][ll][mj][mk][ml][nj][nk][nl][oj][ok][ol][pj][pk][pl][qi][qj][qk][ql][qm][ri][rj][rk][rl][rm][si][sj][sl][sm]
  6987. ;
  6988. Comment[If white threatens to disconnect the black stones...]
  6989. White[fj]
  6990. ;
  6991. Comment[...black always has a response which connects his stones.  ]
  6992. Black[ek]
  6993. ;
  6994. AddBlack[lm][lp][mm][mp][nm][np]
  6995. Comment[Here is another strong connection that cannot be cut.]
  6996. AddWhite[io][jo][ko][ln][lo][nn][no][on][pn][qn]
  6997. AddEmpty[aa][ah][ai][ak][al][bh][bi][bj][bk][bl][ch][ci][cj][ck][cl][di][dj][dk][dl][ei][ej][ek][el][fi][fj][fk][fl][gi][gj][gk][gl][gm][hi][hj][hk][hl][hm][ii][ij][il][im][jc][jd][je][ji][jj][jk][jl][jm][kc][ke][ki][kj][kk][kl][km][lc][ld][le][md][nd][ne][pa][pb][pc][pd][pe][qa][qb][qc][qd][ra][rb][rc][rd][sb][sc]
  6998. ;
  6999. Comment[If black tries to disconnect the white stones...]
  7000. Black[mo]
  7001. ;
  7002. Comment[...as with the diagonal connection, white always has a response which directly connects his stones. \(This is called a bamboo connection\)]
  7003. White[mn]
  7004. ;
  7005. Comment[There are several other weaker connections which can be cut.  ]
  7006. AddEmpty[aa][ao][aq][bn][bo][bp][bq][br][cn][cp][cr][dm][dn][do][dp][dq][dr][ep][eq][fo][fp][fq][gp][gq][hp][io][ip][jo][jp][ko][kp][kq][lm][ln][lo][lp][lq][mm][mn][mo][mp][mq][nm][nn][no][np][on][pn][qn]
  7007. ;
  7008. Comment[These are all weaker connections.  Whether the stones can be separated depends on the location on the board and what other stones are in place.  
  7009.     The marked locations are the cutting points -- the moves white would make to disconnect black.]
  7010. Mark[fo][fb][fe][gh][fk]
  7011. AddEmpty[aa][cl][cp][dl][dp][ec][ej][el][ep][fc][fi][fj][fo][fp][gi][gj][gp][hd][hi][hm][id][ii][ij][im][jd][jj][jm][kd][kj][kp][lp][pg][ph][pi][ql][qm][qn]
  7012. AddBlack[cb][ce][ch][ck][co][db][de][dh][dk][do][eb][ee][eh][ek][eo][gb][gl][hb][he][hl][hp][ib][ie][ih][il][ip][je][jh][jp][kh]
  7013. ;
  7014. Comment[In previous diagrams, several times a ko has arisen during an attempt to capture a group.  In these cases, I have ignored the possible reprecussions of the play that must be made elsewhere.  Now consider this one situation on the whole board.  White wishes to kill the black group at the left.]
  7015. AddBlack[bp][cp][dp][dq][dr][ph][pm][pn][po][pp][pq][qi][qq][qr][qs][ri][rj][rk][rs][si][sl]
  7016. AddWhite[bm][bo][co][do][eo][ep][eq][er][gr][oj][ok][ol][pl][ql][qn][rl][rn][ro][rp][rq][sq]
  7017. AddEmpty[aa][cb][ce][ch][ck][co][db][de][dh][dk][do][eb][ee][eh][ek][eo][gb][gl][hb][he][hl][hp][ib][ie][ih][il][ip][je][jh][jp][kh]
  7018. ;
  7019. White[br]
  7020. ;
  7021. Black[ar]
  7022. ;
  7023. White[cr]
  7024. ;
  7025. Black[ds]
  7026. ;
  7027. White[ap]
  7028. ;
  7029. Black[aq]
  7030. ;
  7031. White[ao]
  7032. ;
  7033. Black[bq]
  7034. ;
  7035. White[cs]
  7036. ;
  7037. Black[bs]
  7038. ;
  7039. Comment[We have reached a Ko situation.  Black may not retake the white stone at A1. 
  7040.  
  7041. Black may, however, attack the white formation on the right side of the board.]
  7042. White[as]
  7043. ;
  7044. Comment[This attack by black is called a "ko threat."  Black is forcing white to decide between killing the group in the left corner, and connecting on the right.  Note that if white does not connect on the right, then the white stones on the right will die.]
  7045. Black[qm]
  7046. (
  7047. ;
  7048. Name[On the right]
  7049. Comment[White will now respond on the right, connecting the white groups together.]
  7050. White[rm]
  7051. ;
  7052. Black[bs]
  7053. ;
  7054. Comment[White cannot retake the ko at B1 now.  He would like to find an attack similar to the one black used on him, but since the board is almost empty, no such attack exists.  \(White can play at T7, threatening to capture the single black stone, but black would much rather save his 10 corner stones than a single side stone.\)]
  7055. White[sm]
  7056. ;
  7057. Black[cq]
  7058. Comment[The black group lives.]
  7059. )
  7060. (
  7061. ;
  7062. Comment[White plays in the corner, planning to kill the group on the left.]
  7063. Name[In the corner]
  7064. ;
  7065. White[bs]
  7066. ;
  7067. Black[cq]
  7068. ;
  7069. Comment[The black stones are dead.]
  7070. White[bs]
  7071. ;
  7072. Comment[But black gets to cut off the white stones.]
  7073. Black[rm]
  7074. ;
  7075. Comment[Suppose black wants to capture the white stone.  ]
  7076. AddBlack[dm][em][fn]
  7077. AddWhite[en]
  7078. AddEmpty[aa][ao][ap][aq][ar][as][bm][bo][bp][bq][br][bs][cn][co][cp][cq][cs][dn][do][dp][dq][dr][ds][eo][ep][eq][er][es][gr][oj][ok][ol][ph][pl][pm][pn][po][pp][pq][qi][ql][qm][qn][qq][qr][qs][ri][rj][rk][rl][rm][rn][ro][rp][rq][rs][si][sl][sq]
  7079. (
  7080. ;
  7081. Comment[If black plays here...]
  7082. Black[dn]
  7083. ;
  7084. Comment[...white escapes downward.  
  7085.  
  7086. This is not the correct approach.]
  7087. White[eo]
  7088. )
  7089. (
  7090. ;
  7091. Comment[Instead, black should play here.  This starts a pattern called the "ladder," a very common occurrence in go games.]
  7092. Black[eo]
  7093. ;
  7094. Comment[The only direction white can go is leftwards.  However, observe the sequence that follows. ]
  7095. White[dn]
  7096. ;
  7097. Black[cn]
  7098. ;
  7099. White[do]
  7100. ;
  7101. Black[dp]
  7102. ;
  7103. White[co]
  7104. ;
  7105. Black[bo]
  7106. ;
  7107. White[cp]
  7108. ;
  7109. Black[cq]
  7110. ;
  7111. White[bp]
  7112. ;
  7113. Black[ap]
  7114. ;
  7115. White[bq]
  7116. ;
  7117. Black[br]
  7118. ;
  7119. White[aq]
  7120. ;
  7121. Comment[Each of the moves is forced, and white is unable to save the stones.  
  7122.  
  7123.  
  7124. White must be able to recognize this, so he can avoid playing this sequence and losing such a large group of stones.]
  7125. Black[ar]
  7126. ;
  7127. Comment[The outcome is very different if white has a stone in the path of the ladder.]
  7128. AddBlack[fn]
  7129. AddWhite[bo][en]
  7130. AddEmpty[aa][ap][ar][br][cn][co][cq][dn][dp][eo]
  7131. ;
  7132. Black[eo]
  7133. ;
  7134. White[dn]
  7135. ;
  7136. Black[cn]
  7137. ;
  7138. White[do]
  7139. ;
  7140. Black[dp]
  7141. ;
  7142. White[co]
  7143. ;
  7144. Black[cm]
  7145. ;
  7146. White[ep]
  7147. ;
  7148. Black[fo]
  7149. ;
  7150. Comment[Black fails to capture white in this case.]
  7151. White[dq]
  7152. ;
  7153. Comment[In this case, white wishes to capture the black stone.  ]
  7154. AddWhite[jh][ji][jj][kj][lj]
  7155. AddBlack[ki]
  7156. AddEmpty[aa][bo][cm][cn][co][dm][dn][do][dp][dq][em][en][eo][ep][fn][fo][iq]
  7157. ;
  7158. Comment[To do so, white plays here.]
  7159. White[lh]
  7160. ;
  7161. Black[li]
  7162. ;
  7163. White[mi]
  7164. ;
  7165. Black[kh]
  7166. ;
  7167. White[kg]
  7168. ;
  7169. AddEmpty[aa][jh][ji][jj][kg][kj][lh][lj][mi]
  7170. Comment[It is important to remember that the object of the game is TERRITORY, not captured stones.  Capturing stones, or preventing stones from being captured is important only when it increases your territory.  A frequent beginner error is to place too much emphasis on capturing stones.]
  7171. ;
  7172. AddBlack[ap][bp][cp][da][db][dc][dd][dp][dq][dr][ds][ed][fd][gd][ha][hb][hc][hd][ih][ii][ij][ik][il][jh][jl][kh][kl][lh][ll][mh][mi][mj][mk][ml]
  7173. Comment[It is easiest to make territory in the corner, and hardest in the center.  Each group surrounds nine points of territory.  The corner group is 7 stones, side group is 11 stones, and the center is 16 stones.  Because of this, you should start in the corner, and expand along the sides from the corners, and finally expand into the center from the sides.]
  7174. ;
  7175. AddEmpty[aa][ap][bp][cp][da][db][dc][dd][dp][dq][dr][ds][ed][fd][gd][ha][hb][hc][hd][ih][ii][ij][ik][il][jh][jl][kh][kl][lh][ll][mh][mi][mj][mk][ml]
  7176. Comment[A common opening move is to play at the 4,4 point in one of the corners.  This move has potential to claim corner territory, side territory, and even center territory.]
  7177. Black[pp]
  7178. ;
  7179. White[qq]
  7180. Comment[Note that white can play underneath black and take the corner despite the black stone at the 4,4 point, however.  This move by white is NOT an opening move, but is an attack that would occur later in the game.]
  7181. ;
  7182. AddBlack[qq]
  7183. AddEmpty[aa][pp]
  7184. Comment[Opening at the 3,3 point insures ownership of the corner but has less potential for extension into the center.]
  7185. ;
  7186. AddBlack[de][pq]
  7187. AddEmpty[aa][qq]
  7188. Comment[Other good openings are the 5,4 point and the 3,4 point.]
  7189. ;
  7190. Comment[From either of these openings, black can make a corner enclosure so get corner territory.]
  7191. AddBlack[dc][qo]
  7192. ;
  7193. Comment[And then extend along the side, staking out side territory.]
  7194. AddBlack[ic][kq]
  7195. ;
  7196. AddEmpty[dc][de][ic][kq][pq][qo]
  7197. AddBlack[dd][dj][dp][jj][pd][pj][pp]
  7198. Comment[Go players use a handicap system to balance games between players of 
  7199. different skill.  The weaker player starts by placing from two to nine stones 
  7200. on the board in a special configuration on the handicap points.  
  7201.     
  7202.  
  7203. This is a seven stone handicap.]
  7204. ;
  7205. AddEmpty[aa][dd][dj][dp][jj][pd][pj][pp]
  7206. Comment[Playing strength of amateurs is measured on a scale where one unit 
  7207. corresponds to a handicap stone.  A total beginner is 35 kyu, and will very 
  7208. quickly improve to 20 kyu.  A player will reach 10 kyu after playing about 
  7209. 100 games.  Ranks worse than 10 kyu are unreliable because playing is too 
  7210. uneven and players progress too quickly to get a stable rating.]
  7211. ;
  7212. Comment[Beyond the kyu ranks are the amateur dan ranks which go from 1 dan to 6 dan, the highest amateur rank.
  7213.  
  7214.  
  7215. A 5 kyu player would give a 9 kyu player a four stone handicap.  A 2 dan player would give a two stone handicap to a 1 kyu player.  Each handicap stone is worth about 10 points.]
  7216. ;
  7217. Comment[Professional players have a different ranking system from 1 dan \(lowest\) to 9 dan \(highest\) which has a finer grating:  a 9 dan is about two stones better than a 1 dan. ]
  7218. ;
  7219. Comment[Playing Black, who always moves first, is advantageous because you start with the initiative.  Generally, white is given 5.5 extra points, called a komi, to compensate for his disadvantage.  \(The 1/2 point prevents tie games.\)]
  7220. ;
  7221. Comment[A new player should begin by playing several games on a 9x9 board, followed by several games on a 13x13 board before finally playing on the full sized 19x19 board.]
  7222. ;
  7223. Comment[The strategy of go is very complex and intricate.  If you wish to become a good player, you should buy a book about the game.
  7224.  
  7225. Computer go programs are presently very weak -- they are ranked around 10 kyu]
  7226. )
  7227. )
  7228. )
  7229. )
  7230. )
  7231. SHAR_EOF
  7232. fi
  7233. if test -f 'Sample.01'
  7234. then
  7235.     echo shar: "will not over-write existing file 'Sample.01'"
  7236. else
  7237. cat << \SHAR_EOF > 'Sample.01'
  7238. (
  7239. ;
  7240. GaMe[1]
  7241. VieW[]
  7242. SiZe[19]
  7243. Comment[A game between two amateurs both ranked betwen 10 kyu and 15 kyu
  7244.     
  7245.  
  7246. Result:  with no komi, black wins by 4]
  7247. ;
  7248. Black[pd]
  7249. ;
  7250. White[qp]
  7251. ;
  7252. Black[dp]
  7253. ;
  7254. White[dc]
  7255. ;
  7256. Black[op]
  7257. ;
  7258. White[po]
  7259. ;
  7260. Black[lp]
  7261. ;
  7262. White[pl]
  7263. ;
  7264. Black[de]
  7265. ;
  7266. White[cd]
  7267. ;
  7268. Black[ed]
  7269. ;
  7270. White[ce]
  7271. ;
  7272. Black[cf]
  7273. ;
  7274. White[ec]
  7275. ;
  7276. Black[ci]
  7277. ;
  7278. White[fd]
  7279. ;
  7280. Black[fe]
  7281. ;
  7282. White[gd]
  7283. ;
  7284. Black[ph]
  7285. ;
  7286. White[qi]
  7287. ;
  7288. Black[nc]
  7289. ;
  7290. White[cn]
  7291. ;
  7292. Black[dn]
  7293. ;
  7294. White[cp]
  7295. ;
  7296. Black[co]
  7297. ;
  7298. White[bo]
  7299. ;
  7300. Black[do]
  7301. ;
  7302. White[dq]
  7303. ;
  7304. Black[bp]
  7305. ;
  7306. White[bq]
  7307. ;
  7308. Black[ap]
  7309. ;
  7310. White[cq]
  7311. ;
  7312. Black[bn]
  7313. ;
  7314. White[ep]
  7315. ;
  7316. Black[eo]
  7317. ;
  7318. White[fq]
  7319. ;
  7320. Black[fp]
  7321. ;
  7322. White[eq]
  7323. ;
  7324. Black[gp]
  7325. ;
  7326. White[gq]
  7327. ;
  7328. Black[hq]
  7329. ;
  7330. White[hp]
  7331. ;
  7332. Black[ho]
  7333. ;
  7334. White[iq]
  7335. ;
  7336. Black[ip]
  7337. ;
  7338. White[hr]
  7339. ;
  7340. Black[jq]
  7341. ;
  7342. White[ir]
  7343. ;
  7344. Black[jr]
  7345. ;
  7346. White[go]
  7347. ;
  7348. Black[gn]
  7349. ;
  7350. White[io]
  7351. ;
  7352. Black[hn]
  7353. ;
  7354. White[hp]
  7355. ;
  7356. Black[fo]
  7357. ;
  7358. White[jp]
  7359. ;
  7360. Black[kq]
  7361. ;
  7362. White[jn]
  7363. ;
  7364. Black[kd]
  7365. ;
  7366. White[jc]
  7367. ;
  7368. Black[kc]
  7369. ;
  7370. White[jd]
  7371. ;
  7372. Black[lg]
  7373. ;
  7374. White[ke]
  7375. ;
  7376. Black[le]
  7377. ;
  7378. White[kf]
  7379. ;
  7380. Black[lf]
  7381. ;
  7382. White[if]
  7383. ;
  7384. Black[gg]
  7385. ;
  7386. White[ge]
  7387. ;
  7388. Black[ff]
  7389. ;
  7390. White[jh]
  7391. ;
  7392. Black[hj]
  7393. ;
  7394. White[jk]
  7395. ;
  7396. Black[mk]
  7397. ;
  7398. White[pq]
  7399. ;
  7400. Black[oq]
  7401. ;
  7402. White[qh]
  7403. ;
  7404. Black[qg]
  7405. ;
  7406. White[pi]
  7407. ;
  7408. Black[oh]
  7409. ;
  7410. White[oi]
  7411. ;
  7412. Black[ni]
  7413. ;
  7414. White[nh]
  7415. ;
  7416. Black[ng]
  7417. ;
  7418. White[nj]
  7419. ;
  7420. Black[mh]
  7421. ;
  7422. White[mj]
  7423. ;
  7424. Black[lm]
  7425. ;
  7426. White[kp]
  7427. ;
  7428. Black[lo]
  7429. ;
  7430. White[lq]
  7431. ;
  7432. Black[lr]
  7433. ;
  7434. White[js]
  7435. ;
  7436. Black[mq]
  7437. ;
  7438. White[oo]
  7439. ;
  7440. Black[no]
  7441. ;
  7442. White[nn]
  7443. ;
  7444. Black[nm]
  7445. ;
  7446. White[mn]
  7447. ;
  7448. Black[lj]
  7449. ;
  7450. White[mi]
  7451. ;
  7452. Black[li]
  7453. ;
  7454. White[mo]
  7455. ;
  7456. Black[np]
  7457. ;
  7458. White[nk]
  7459. ;
  7460. Black[ml]
  7461. ;
  7462. White[nl]
  7463. ;
  7464. Black[mm]
  7465. ;
  7466. White[om]
  7467. ;
  7468. Black[il]
  7469. ;
  7470. White[hh]
  7471. ;
  7472. Black[gh]
  7473. ;
  7474. White[gf]
  7475. ;
  7476. Black[kg]
  7477. ;
  7478. White[jg]
  7479. ;
  7480. Black[ii]
  7481. ;
  7482. White[bf]
  7483. ;
  7484. Black[df]
  7485. ;
  7486. White[cg]
  7487. ;
  7488. Black[dg]
  7489. ;
  7490. White[bh]
  7491. ;
  7492. Black[ch]
  7493. ;
  7494. White[bg]
  7495. ;
  7496. Black[bi]
  7497. ;
  7498. White[gi]
  7499. ;
  7500. Black[hi]
  7501. ;
  7502. White[dd]
  7503. ;
  7504. Black[ee]
  7505. ;
  7506. White[hg]
  7507. ;
  7508. Black[fg]
  7509. ;
  7510. White[ji]
  7511. ;
  7512. Black[gj]
  7513. ;
  7514. White[nh]
  7515. ;
  7516. Black[pg]
  7517. ;
  7518. White[aq]
  7519. ;
  7520. Black[ao]
  7521. ;
  7522. White[jl]
  7523. ;
  7524. Black[kl]
  7525. ;
  7526. White[im]
  7527. ;
  7528. Black[hl]
  7529. ;
  7530. White[ln]
  7531. ;
  7532. Black[pr]
  7533. ;
  7534. White[qr]
  7535. ;
  7536. Black[ps]
  7537. ;
  7538. White[qs]
  7539. ;
  7540. Black[or]
  7541. ;
  7542. White[km]
  7543. ;
  7544. Black[ko]
  7545. ;
  7546. White[lk]
  7547. ;
  7548. Black[kk]
  7549. ;
  7550. White[ll]
  7551. ;
  7552. Black[kj]
  7553. ;
  7554. White[jj]
  7555. ;
  7556. Black[jo]
  7557. ;
  7558. White[rg]
  7559. ;
  7560. Black[rf]
  7561. ;
  7562. White[rh]
  7563. ;
  7564. Black[ip]
  7565. ;
  7566. White[hq]
  7567. ;
  7568. Black[in]
  7569. ;
  7570. White[kn]
  7571. ;
  7572. Black[hm]
  7573. ;
  7574. White[kb]
  7575. ;
  7576. Black[lb]
  7577. ;
  7578. White[ka]
  7579. ;
  7580. Black[la]
  7581. ;
  7582. White[jb]
  7583. ;
  7584. Black[lc]
  7585. ;
  7586. White[ih]
  7587. ;
  7588. Black[ah]
  7589. ;
  7590. White[ag]
  7591. ;
  7592. Black[ai]
  7593. ;
  7594. White[be]
  7595. ;
  7596. Black[sg]
  7597. ;
  7598. White[sh]
  7599. ;
  7600. Black[ks]
  7601. ;
  7602. White[is]
  7603. ;
  7604. Black[ik]
  7605. ;
  7606. White[kh]
  7607. ;
  7608. Black[lh]
  7609. ;
  7610. White[jm]
  7611. ;
  7612. Black[sf]
  7613. ;
  7614. White[ni]
  7615. ;
  7616. Black[pp]
  7617. ;
  7618. White[qq]
  7619. )
  7620.  
  7621. SHAR_EOF
  7622. fi
  7623. if test -f 'Sample.02'
  7624. then
  7625.     echo shar: "will not over-write existing file 'Sample.02'"
  7626. else
  7627. cat << \SHAR_EOF > 'Sample.02'
  7628. (
  7629. ;
  7630. GaMe[1]
  7631. SiZe[19]
  7632. VieW[]
  7633. Comment[16th Honinbo League Playoff
  7634.     
  7635. White: Sakata Eio 9-dan    
  7636.     
  7637. Black: Kitani Minoru 9-dan
  7638.     
  7639. Komi: 4 1/2    
  7640.  
  7641. Result: White wins by 3 1/2 points]
  7642. Black[qd]
  7643. ;
  7644. White[dc]
  7645. ;
  7646. Black[pq]
  7647. ;
  7648. White[cq]
  7649. ;
  7650. Black[oc]
  7651. ;
  7652. White[po]
  7653. ;
  7654. Black[qo]
  7655. ;
  7656. White[qn]
  7657. ;
  7658. Black[qp]
  7659. ;
  7660. White[pm]
  7661. ;
  7662. Black[nq]
  7663. ;
  7664. White[qi]
  7665. ;
  7666. Black[ce]
  7667. ;
  7668. White[dh]
  7669. ;
  7670. Black[ee]
  7671. ;
  7672. White[cb]
  7673. ;
  7674. Black[cc]
  7675. ;
  7676. White[gc]
  7677. ;
  7678. Black[bc]
  7679. ;
  7680. White[bb]
  7681. ;
  7682. Black[qg]
  7683. ;
  7684. White[dd]
  7685. ;
  7686. Black[de]
  7687. ;
  7688. White[cg]
  7689. ;
  7690. Black[co]
  7691. ;
  7692. White[cm]
  7693. ;
  7694. Black[ep]
  7695. ;
  7696. White[do]
  7697. ;
  7698. Black[dp]
  7699. ;
  7700. White[cp]
  7701. ;
  7702. Black[dn]
  7703. ;
  7704. White[bo]
  7705. ;
  7706. Black[eo]
  7707. ;
  7708. White[cn]
  7709. ;
  7710. Black[el]
  7711. ;
  7712. White[dk]
  7713. ;
  7714. Black[ql]
  7715. ;
  7716. White[rm]
  7717. ;
  7718. Black[rj]
  7719. ;
  7720. White[qe]
  7721. Comment[Complications start. Creating two weak groups. ]
  7722. ;
  7723. Black[qj]
  7724. ;
  7725. White[rd]
  7726. ;
  7727. Black[qc]
  7728. ;
  7729. White[qf]
  7730. ;
  7731. Black[pg]
  7732. ;
  7733. White[rc]
  7734. ;
  7735. Black[rb]
  7736. ;
  7737. White[oe]
  7738. ;
  7739. Black[mc]
  7740. ;
  7741. White[op]
  7742. ;
  7743. Black[on]
  7744. ;
  7745. White[pn]
  7746. ;
  7747. Black[oq]
  7748. ;
  7749. White[mo]
  7750. ;
  7751. Black[mp]
  7752. Comment[Severe attack. ]
  7753. ;
  7754. White[lo]
  7755. Comment[Counters aggressively. ]
  7756. ;
  7757. Black[no]
  7758. ;
  7759. White[np]
  7760. ;
  7761. Black[nm]
  7762. Comment[Black cuts. Brings on crisis.]
  7763. ;
  7764. White[pj]
  7765. ;
  7766. Black[pi]
  7767. ;
  7768. White[pk]
  7769. ;
  7770. Black[rl]
  7771. ;
  7772. White[ml]
  7773. ;
  7774. Black[nl]
  7775. ;
  7776. White[nk]
  7777. ;
  7778. Black[mk]
  7779. ;
  7780. White[om]
  7781. Comment[Exquisite shinogi tesuji. Lets W secure his endangered group]
  7782. ;
  7783. Black[nj]
  7784. ;
  7785. White[ok]
  7786. ;
  7787. Black[ll]
  7788. ;
  7789. White[lp]
  7790. ;
  7791. Black[mq]
  7792. ;
  7793. White[mn]
  7794. ;
  7795. Black[mm]
  7796. ;
  7797. White[nn]
  7798. ;
  7799. Black[rf]
  7800. Comment[Turns toward other weak group. ]
  7801. ;
  7802. White[re]
  7803. ;
  7804. Black[rg]
  7805. ;
  7806. White[nd]
  7807. ;
  7808. Black[nc]
  7809. ;
  7810. White[nf]
  7811. ;
  7812. Black[nh]
  7813. ;
  7814. White[lf]
  7815. ;
  7816. Black[le]
  7817. ;
  7818. White[mh]
  7819. ;
  7820. Black[mi]
  7821. ;
  7822. White[me]
  7823. ;
  7824. Black[mg]
  7825. ;
  7826. White[ld]
  7827. ;
  7828. Black[ke]
  7829. ;
  7830. White[md]
  7831. ;
  7832. Black[kb]
  7833. ;
  7834. White[kc]
  7835. ;
  7836. Black[jb]
  7837. ;
  7838. White[id]
  7839. ;
  7840. Black[kf]
  7841. ;
  7842. White[oi]
  7843. ;
  7844. Black[ph]
  7845. ;
  7846. White[jc]
  7847. Comment[Manages to rescue weak group. ]
  7848. ;
  7849. Black[ib]
  7850. ;
  7851. White[fd]
  7852. ;
  7853. Black[eg]
  7854. ;
  7855. White[lg]
  7856. Comment[Double attack.]
  7857. ;
  7858. Black[lh]
  7859. ;
  7860. White[kg]
  7861. ;
  7862. Black[if]
  7863. ;
  7864. White[hg]
  7865. ;
  7866. Black[hf]
  7867. ;
  7868. White[gf]
  7869. ;
  7870. Black[ge]
  7871. ;
  7872. White[fe]
  7873. ;
  7874. Black[jg]
  7875. ;
  7876. White[he]
  7877. Comment[First time that B is the one under pressure.]
  7878. ;
  7879. Black[gg]
  7880. ;
  7881. White[ff]
  7882. ;
  7883. Black[dg]
  7884. ;
  7885. White[ef]
  7886. ;
  7887. Black[df]
  7888. ;
  7889. White[fg]
  7890. ;
  7891. Black[ch]
  7892. ;
  7893. White[bh]
  7894. ;
  7895. Black[ci]
  7896. ;
  7897. White[bf]
  7898. ;
  7899. Black[ei]
  7900. ;
  7901. White[cj]
  7902. ;
  7903. Black[gh]
  7904. ;
  7905. White[fh]
  7906. ;
  7907. Black[eh]
  7908. ;
  7909. White[dj]
  7910. ;
  7911. Black[di]
  7912. ;
  7913. White[bi]
  7914. ;
  7915. Black[fi]
  7916. ;
  7917. White[gi]
  7918. ;
  7919. Black[gj]
  7920. ;
  7921. White[hh]
  7922. ;
  7923. Black[ii]
  7924. ;
  7925. White[mf]
  7926. ;
  7927. Black[jh]
  7928. Comment[Fight ends. ]
  7929. ;
  7930. White[er]
  7931. Comment[W has taken the lead.]
  7932. ;
  7933. Black[fk]
  7934. ;
  7935. White[ro]
  7936. ;
  7937. Black[rp]
  7938. ;
  7939. White[fq]
  7940. ;
  7941. Black[in]
  7942. ;
  7943. White[go]
  7944. ;
  7945. Black[gn]
  7946. ;
  7947. White[jn]
  7948. ;
  7949. Black[jm]
  7950. ;
  7951. White[fn]
  7952. ;
  7953. Black[hn]
  7954. ;
  7955. White[fo]
  7956. ;
  7957. Black[en]
  7958. ;
  7959. White[fm]
  7960. ;
  7961. Black[dl]
  7962. ;
  7963. White[cl]
  7964. ;
  7965. Black[hl]
  7966. ;
  7967. White[km]
  7968. ;
  7969. Black[jl]
  7970. ;
  7971. White[lq]
  7972. ;
  7973. Black[ip]
  7974. ;
  7975. White[lr]
  7976. ;
  7977. Black[hq]
  7978. ;
  7979. White[os]
  7980. ;
  7981. Black[or]
  7982. ;
  7983. White[gq]
  7984. ;
  7985. Black[dq]
  7986. ;
  7987. White[dr]
  7988. ;
  7989. Black[be]
  7990. ;
  7991. White[hb]
  7992. ;
  7993. Black[ic]
  7994. ;
  7995. White[sb]
  7996. ;
  7997. Black[ra]
  7998. ;
  7999. White[ie]
  8000. ;
  8001. Black[hc]
  8002. ;
  8003. White[gb]
  8004. ;
  8005. Black[gr]
  8006. ;
  8007. White[hi]
  8008. ;
  8009. Black[hj]
  8010. ;
  8011. White[ns]
  8012. ;
  8013. Black[ps]
  8014. ;
  8015. White[mr]
  8016. ;
  8017. Black[pp]
  8018. ;
  8019. White[oo]
  8020. ;
  8021. Black[rr]
  8022. ;
  8023. White[ej]
  8024. ;
  8025. Black[fj]
  8026. ;
  8027. White[ir]
  8028. ;
  8029. Black[hr]
  8030. ;
  8031. White[jr]
  8032. ;
  8033. Black[jo]
  8034. ;
  8035. White[kn]
  8036. ;
  8037. Black[ab]
  8038. ;
  8039. White[qk]
  8040. ;
  8041. Black[rk]
  8042. ;
  8043. White[oj]
  8044. ;
  8045. Black[ia]
  8046. ;
  8047. White[jp]
  8048. ;
  8049. Black[fr]
  8050. ;
  8051. White[iq]
  8052. ;
  8053. Black[hp]
  8054. ;
  8055. White[eq]
  8056. ;
  8057. Black[af]
  8058. ;
  8059. White[kl]
  8060. ;
  8061. Black[kk]
  8062. ;
  8063. White[ko]
  8064. ;
  8065. Black[ag]
  8066. ;
  8067. White[kh]
  8068. ;
  8069. Black[ki]
  8070. ;
  8071. White[bg]
  8072. ;
  8073. Black[gm]
  8074. ;
  8075. White[ng]
  8076. ;
  8077. Black[mh]
  8078. ;
  8079. White[sl]
  8080. ;
  8081. Black[so]
  8082. ;
  8083. White[rn]
  8084. ;
  8085. Black[hd]
  8086. ;
  8087. White[gd]
  8088. ;
  8089. Black[lm]
  8090. ;
  8091. White[ri]
  8092. ;
  8093. Black[si]
  8094. ;
  8095. White[sf]
  8096. ;
  8097. Black[sg]
  8098. ;
  8099. White[io]
  8100. ;
  8101. Black[ho]
  8102. ;
  8103. White[cd]
  8104. ;
  8105. Black[bd]
  8106. ;
  8107. White[pd]
  8108. ;
  8109. Black[pc]
  8110. ;
  8111. White[se]
  8112. ;
  8113. Black[nr]
  8114. ;
  8115. White[ms]
  8116. ;
  8117. Black[ha]
  8118. ;
  8119. White[ga]
  8120. ;
  8121. Black[lc]
  8122. ;
  8123. White[kd]
  8124. ;
  8125. Black[ed]
  8126. ;
  8127. White[ec]
  8128. ;
  8129. Black[fl]
  8130. ;
  8131. White[ah]
  8132. ;
  8133. Black[ae]
  8134. ;
  8135. White[je]
  8136. ;
  8137. Black[jf]
  8138. ;
  8139. White[ni]
  8140. ;
  8141. Black[mj]
  8142. ;
  8143. White[ih]
  8144. ;
  8145. Black[sc]
  8146. ;
  8147. White[sd]
  8148. ;
  8149. Black[od]
  8150. ;
  8151. White[pf]
  8152. ;
  8153. Black[db]
  8154. ;
  8155. White[eb]
  8156. ;
  8157. Black[ba]
  8158. ;
  8159. White[da]
  8160. ;
  8161. Black[do]
  8162. ;
  8163. White[hs]
  8164. ;
  8165. Black[og]
  8166. ;
  8167. White[of]
  8168. ;
  8169. Black[es]
  8170. ;
  8171. White[ds]
  8172. ;
  8173. Black[fs]
  8174. ;
  8175. White[jo]
  8176. ;
  8177. Black[ac]
  8178. ;
  8179. White[pe]
  8180. )
  8181. SHAR_EOF
  8182. fi
  8183. if test -f 'ScrList.c'
  8184. then
  8185.     echo shar: "will not over-write existing file 'ScrList.c'"
  8186. else
  8187. cat << \SHAR_EOF > 'ScrList.c'
  8188. /*****************************************************************************
  8189.  
  8190.     ScrolledList.c
  8191.  
  8192.     This file contains the C code for the ScrolledList widget, which
  8193.     acts as a vertically scrolling list of text, from which, items can
  8194.     be selected.
  8195.  
  8196. ******************************************************************************/
  8197.  
  8198. /*
  8199.  * Author:
  8200.  *     Brian Totty
  8201.  *     Department of Computer Science
  8202.  *     University Of Illinois at Urbana-Champaign
  8203.  *    1304 West Springfield Avenue
  8204.  *     Urbana, IL 61801
  8205.  * 
  8206.  *     totty@cs.uiuc.edu
  8207.  *     
  8208.  */ 
  8209.  
  8210. #include <stdio.h>
  8211. #include <X11/Xos.h>
  8212. #include <X11/Xlib.h>
  8213. #include <X11/StringDefs.h>
  8214. #include <X11/IntrinsicP.h>
  8215. #include <X11/Intrinsic.h>
  8216. #include <X11/CompositeP.h>
  8217. #include <X11/Composite.h>
  8218. #include <X11/Xaw/ViewportP.h>
  8219. #include <X11/Xaw/Viewport.h>
  8220. #include "MultiListP.h"
  8221. #include "MultiList.h"
  8222. #include "ScrListP.h"
  8223. #include "ScrList.h"
  8224.  
  8225. /*---------------------------------------------------------------------------*
  8226.  
  8227.                        D E C L A R A T I O N S
  8228.  
  8229.  *---------------------------------------------------------------------------*/
  8230.  
  8231. #define    SUPERCLASS        (&compositeClassRec)
  8232.  
  8233. #define max(a,b)        ((a) > (b) ? (a) : (b))
  8234. #define min(a,b)        ((a) < (b) ? (a) : (b))
  8235. #define abs(a)            ((a) < 0 ? -(a) : (a))
  8236. #define XtStrlen(s)        ((s) ? strlen(s) : 0)
  8237.  
  8238. #define offset(field)        XtOffset(XfwfScrolledListWidget,    \
  8239.                      scrolledList.field)
  8240. #define coffset(field)        XtOffset(Widget,core.field)
  8241.  
  8242. #define    MyData(w)        ((w)->scrolledList)
  8243. #define    CoreData(w)        ((w)->core)
  8244.  
  8245. #if (!NeedFunctionPrototypes)
  8246.  
  8247. static void        MultiListCallbackHandler();
  8248. static void        ClassInitialize();
  8249. static void        Initialize();
  8250. static void        Realize();
  8251. static void        Destroy();
  8252. static void        Resize();
  8253. static Boolean        SetValues();
  8254. static XtGeometryResult    GeometryManager();
  8255. static XtGeometryResult    PreferredGeometry();
  8256. static void        ReCalcChildren();
  8257.  
  8258. #else
  8259.  
  8260. static void        MultiListCallbackHandler(Widget w, Widget self,
  8261.                 XfwfMultiListReturnStruct *call_data);
  8262. static void        ClassInitialize(void);
  8263. static void        Initialize(Widget request, Widget new);
  8264. static void        Realize(Widget gw, XtValueMask *valueMask,
  8265.                 XSetWindowAttributes *attrs);
  8266. static void        Destroy(Widget gw);
  8267. static void        Resize(Widget gw);
  8268. static Boolean        SetValues(Widget gcurrent, Widget grequest,
  8269.                 Widget gnew);
  8270. static XtGeometryResult    GeometryManager(Widget w, XtWidgetGeometry *request,
  8271.                 XtWidgetGeometry *reply);
  8272. static XtGeometryResult    PreferredGeometry(XfwfScrolledListWidget slw,
  8273.                 XtWidgetGeometry *parent_idea,
  8274.                 XtWidgetGeometry *our_idea);
  8275. static void        ReCalcChildren(XfwfScrolledListWidget w);
  8276.  
  8277. #endif
  8278.  
  8279. /*---------------------------------------------------------------------------*
  8280.  
  8281.               R E S O U R C E    I N I T I A L I Z A T I O N
  8282.  
  8283.  *---------------------------------------------------------------------------*/
  8284.  
  8285. static XtResource resources[] =
  8286. {
  8287.     {XtNwidth,XtCWidth,XtRDimension,sizeof(Dimension),
  8288.         coffset(width),XtRString,"200"},
  8289.     {XtNheight,XtCHeight,XtRDimension,sizeof(Dimension),
  8290.         coffset(height),XtRString,"500"},
  8291.     {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
  8292.         coffset(background_pixel),XtRString,"white"},
  8293.     {XtNlist,XtCList,XtRPointer,sizeof(char **),
  8294.         offset(item_array),XtRPointer,NULL},
  8295.     {XtNnumberStrings,XtCNumberStrings,XtRInt,sizeof(int),
  8296.         offset(item_count),XtRInt,0},
  8297.     {XtNsensitiveArray,XtCList,XtRPointer,sizeof(Boolean *),
  8298.         offset(sensitive_array),XtRPointer,NULL},
  8299.     {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
  8300.         offset(callback), XtRCallback, NULL}
  8301. };
  8302.  
  8303. #undef offset
  8304. #undef coffset
  8305.  
  8306. /*---------------------------------------------------------------------------*
  8307.  
  8308.                     C L A S S    A L L O C A T I O N
  8309.  
  8310.  *---------------------------------------------------------------------------*/
  8311.  
  8312. XfwfScrolledListClassRec xfwfScrolledListClassRec =
  8313. {
  8314.     {
  8315.         /* superclass        */    (WidgetClass)SUPERCLASS,
  8316.         /* class_name        */    "XfwfScrolledList",
  8317.         /* widget_size        */    sizeof(XfwfScrolledListRec),
  8318.         /* class_initialize    */    (XtProc)ClassInitialize,
  8319.         /* class_part_initialize*/    NULL,
  8320.         /* class_inited        */    FALSE,
  8321.         /* initialize        */    (XtInitProc)Initialize,
  8322.         /* initialize_hook    */    NULL,
  8323.         /* realize        */    (XtRealizeProc)Realize,
  8324.         /* actions        */    NULL,
  8325.         /* num_actions        */    0,
  8326.         /* resources        */    resources,
  8327.         /* resource_count    */    XtNumber(resources),
  8328.         /* xrm_class        */    NULLQUARK,
  8329.         /* compress_motion    */    TRUE,
  8330.         /* compress_exposure    */    TRUE,
  8331.         /* compress_enterleave    */    TRUE,
  8332.         /* visible_interest    */    FALSE,
  8333.         /* destroy        */    (XtWidgetProc)Destroy,
  8334.         /* resize        */    (XtWidgetProc)Resize,
  8335.         /* expose        */    NULL,
  8336.         /* set_values        */    (XtSetValuesFunc)SetValues,
  8337.         /* set_values_hook    */    NULL,
  8338.         /* set_values_almost    */    XtInheritSetValuesAlmost,
  8339.         /* get_values_hook    */    NULL,
  8340.         /* accept_focus        */    NULL,
  8341.         /* version        */    XtVersion,
  8342.         /* callback_private    */    NULL,
  8343.         /* tm_table        */    NULL,
  8344.         /* query_geometry       */    (XtGeometryHandler)
  8345.                             PreferredGeometry,
  8346.         /* display_accelerator  */    XtInheritDisplayAccelerator,
  8347.         /* extension            */    NULL
  8348.     }, /* Core Part */
  8349.     {
  8350.         /* geometry_manager     */    GeometryManager,
  8351.         /* change_managed       */    XtInheritChangeManaged,
  8352.         /* insert_child         */    XtInheritInsertChild,
  8353.         /* delete_child         */    XtInheritDeleteChild,
  8354.         /* extension            */    NULL
  8355.     }, /* Composite Part */        
  8356.     {
  8357.         /* no extra class data  */    0
  8358.     }  /* XfwfScrolledList Part */
  8359. };
  8360.  
  8361. WidgetClass xfwfScrolledListWidgetClass =
  8362.     (WidgetClass)&xfwfScrolledListClassRec;
  8363.  
  8364. /*---------------------------------------------------------------------------*
  8365.  
  8366.                     E X P O R T E D    M E T H O D S
  8367.  
  8368.  *---------------------------------------------------------------------------*/
  8369.  
  8370. /*---------------------------------------------------------------*
  8371.  
  8372.     MultiListCallbackHandler(w,client_data,call_data)
  8373.  
  8374.     This routine gets called when the user clicks on a
  8375.     MultiList item.  It in turn calls any callbacks in the
  8376.     ScrolledList widget.
  8377.  
  8378.  *---------------------------------------------------------------*/
  8379.  
  8380. static void MultiListCallbackHandler(w,self,call_data)
  8381. Widget w;
  8382. Widget self;
  8383. XfwfMultiListReturnStruct *call_data;
  8384. {
  8385.     Boolean highlighted,sensitive;
  8386.     XfwfScrolledListReturnStruct ret_value;
  8387.  
  8388.     if (call_data->num_selected)
  8389.     {
  8390.         ret_value.index = call_data->selected_items[0];
  8391.         XfwfMultiListGetItemInfo((XfwfMultiListWidget)w,
  8392.             ret_value.index,&(ret_value.string),
  8393.             &highlighted,&sensitive);
  8394.     }
  8395.         else
  8396.     {
  8397.         ret_value.index = -1;
  8398.         ret_value.string = NULL;
  8399.     }
  8400.     XtCallCallbacks(self,XtNcallback,(caddr_t)(&ret_value));
  8401. }
  8402.  
  8403.  
  8404. /*---------------------------------------------------------------*
  8405.  
  8406.     ClassInitialize()
  8407.  
  8408.     This procedure is called by the X toolkit to initialize
  8409.     the class.  The hook to this routine is in the
  8410.     class_initialize part of the core part of the class.
  8411.  
  8412.  *---------------------------------------------------------------*/
  8413.  
  8414. static void ClassInitialize()
  8415. {
  8416. } /* End ClassInitialize */
  8417.  
  8418.  
  8419.  
  8420. /*---------------------------------------------------------------*
  8421.  
  8422.     Initialize()
  8423.  
  8424.     This procedure is called by the X toolkit to initialize
  8425.     the widget instance.  The hook to this routine is in the
  8426.     initialize part of the core part of the class.
  8427.  
  8428.  *---------------------------------------------------------------*/
  8429.  
  8430. /* ARGSUSED */
  8431. static void Initialize(request,new)
  8432. Widget request,new;
  8433. {
  8434.     XfwfScrolledListWidget w;
  8435.     Arg args[10];
  8436.  
  8437. /*
  8438.     static char translations[] =
  8439.         "<Btn1Down>:    Select()\n\
  8440.          <Btn1Up>:    Notify()\n";
  8441. */
  8442.  
  8443.     w = (XfwfScrolledListWidget)new;
  8444.  
  8445.     if (CoreData(new).width <= 0) CoreData(new).width = 200;
  8446.     if (CoreData(new).height <= 0) CoreData(new).height = 300;
  8447.  
  8448.     XtSetArg(args[0],XtNuseRight,True);
  8449.     XtSetArg(args[1],XtNwidth,CoreData(new).width);
  8450.     XtSetArg(args[2],XtNheight,CoreData(new).height);
  8451.     XtSetArg(args[3],XtNallowVert,True);
  8452.     XtSetArg(args[4],XtNforceBars,True);
  8453.     MyData(w).viewport = XtCreateManagedWidget("viewport",
  8454.         viewportWidgetClass,(Widget)w,args,5);
  8455.     XtSetArg(args[0],XtNlist,MyData(w).item_array);
  8456.     XtSetArg(args[1],XtNnumberStrings,MyData(w).item_count);
  8457.     XtSetArg(args[2],XtNsensitiveArray,MyData(w).sensitive_array);
  8458.     XtSetArg(args[3],XtNdefaultColumns,1);
  8459.     XtSetArg(args[4],XtNborderWidth,0);
  8460.     XtSetArg(args[5],XtNx,1);
  8461.     XtSetArg(args[6],XtNy,1);
  8462.     XtSetArg(args[7],XtNmaxSelectable,1);
  8463. /*
  8464.     XtSetArg(args[8],XtNtranslations,
  8465.          XtParseTranslationTable(translations));
  8466. */
  8467.     MyData(w).list = XtCreateManagedWidget("multilist",
  8468.         xfwfMultiListWidgetClass,MyData(w).viewport,args,8);
  8469.  
  8470.     XtAddCallback(MyData(w).list,XtNcallback,
  8471.         (XtCallbackProc)MultiListCallbackHandler,(Widget)w);
  8472. } /* End Initialize */
  8473.  
  8474.  
  8475.  
  8476. /*---------------------------------------------------------------*
  8477.  
  8478.     Realize()
  8479.  
  8480.     This function is called to realize a ScrolledList widget.
  8481.  
  8482.  *---------------------------------------------------------------*/
  8483.  
  8484. static void Realize(gw,valueMask,attrs)
  8485. Widget gw;
  8486. XtValueMask *valueMask;
  8487. XSetWindowAttributes *attrs;
  8488. {
  8489.     XfwfScrolledListWidget w;
  8490.  
  8491.     w = (XfwfScrolledListWidget)gw;
  8492.     XtCreateWindow(gw,InputOutput,(Visual *)CopyFromParent,
  8493.         *valueMask,attrs);
  8494.     XtRealizeWidget(MyData(w).viewport);
  8495.  
  8496.     Resize(gw);
  8497. } /* End Realize */
  8498.  
  8499.  
  8500.  
  8501. /*---------------------------------------------------------------*
  8502.  
  8503.     Destroy()
  8504.  
  8505.     This function is called to destroy a scrolledList widget.
  8506.  
  8507.  *---------------------------------------------------------------*/
  8508.  
  8509. static void Destroy(gw)
  8510. Widget gw;
  8511. {
  8512.     XfwfScrolledListWidget w;
  8513.  
  8514.     w = (XfwfScrolledListWidget)gw;
  8515.     XtDestroyWidget(MyData(w).viewport);
  8516.     XtDestroyWidget(MyData(w).list);
  8517. } /* End Destroy */
  8518.  
  8519.  
  8520.  
  8521. /*---------------------------------------------------------------*
  8522.  
  8523.     Resize()
  8524.  
  8525.     This function is called to resize a scrolledList widget.
  8526.  
  8527.  *---------------------------------------------------------------*/
  8528.  
  8529. static void Resize(gw) 
  8530. Widget gw;
  8531. {
  8532.     XfwfScrolledListWidget w;
  8533.  
  8534.     w = (XfwfScrolledListWidget)gw;
  8535.     ReCalcChildren(w);
  8536. } /* End Resize */
  8537.  
  8538.  
  8539.  
  8540. /*---------------------------------------------------------------*
  8541.  
  8542.     Boolean SetValues(wcurrent,wrequest,wnew)
  8543.  
  8544.     This isn't inplemented yet, meaning you can't change
  8545.     resources dynamically.
  8546.  
  8547.  *---------------------------------------------------------------*/
  8548.  
  8549. /* ARGSUSED */
  8550. static Boolean SetValues(wcurrent,wrequest,wnew)
  8551. Widget wcurrent,wrequest,wnew;
  8552. {
  8553.     Boolean redraw,recalc;
  8554.     XfwfScrolledListWidget csl,rsl,nsl;
  8555.  
  8556.     csl = (XfwfScrolledListWidget)wcurrent;
  8557.     rsl = (XfwfScrolledListWidget)wrequest;
  8558.     nsl = (XfwfScrolledListWidget)wnew;
  8559.  
  8560.     redraw = False;
  8561.     recalc = False;
  8562.  
  8563.     if ((MyData(csl).item_array != MyData(nsl).item_array) ||
  8564.         (MyData(csl).item_count != MyData(nsl).item_count) ||
  8565.         (MyData(csl).sensitive_array != MyData(nsl).sensitive_array))
  8566.     {
  8567.         XfwfScrolledListSetList((Widget)csl,
  8568.             MyData(nsl).item_array,
  8569.             MyData(nsl).item_count,True,
  8570.             MyData(nsl).sensitive_array);
  8571.         redraw = recalc = True;
  8572.     }
  8573.  
  8574.     return(redraw);
  8575. } /* End SetValues */
  8576.  
  8577.  
  8578. /*---------------------------------------------------------------*
  8579.  
  8580.     GeometryManager(w,request,reply)
  8581.  
  8582.     This routine acts as the geometry_manager method for the
  8583.     ScrolledList widget.  It is called when a child wants to
  8584.     resize/reposition itself.
  8585.  
  8586.     Currently, we allow all requests.
  8587.  
  8588.  *---------------------------------------------------------------*/
  8589.  
  8590. /* ARGSUSED */
  8591. static XtGeometryResult GeometryManager(w,request,reply)
  8592. Widget w;
  8593. XtWidgetGeometry *request;
  8594. XtWidgetGeometry *reply;
  8595. {
  8596.     return(XtGeometryYes);
  8597. } /* End GeometryManager */
  8598.  
  8599.  
  8600. /*---------------------------------------------------------------------------*
  8601.  
  8602.     PreferredGeometry(slw,parent_idea,our_idea)
  8603.  
  8604.     This routine is called by the parent to tell us about the
  8605.     parent's idea of our width and/or height.  We then suggest
  8606.     our preference through <our_idea> and return the information
  8607.     to the parent.
  8608.  
  8609.  *---------------------------------------------------------------------------*/
  8610.  
  8611. static XtGeometryResult PreferredGeometry(slw,parent_idea,our_idea)
  8612. XfwfScrolledListWidget slw;
  8613. XtWidgetGeometry *parent_idea,*our_idea;
  8614. {
  8615.     Arg multilist_args[2],slist_args[2];
  8616.     Dimension col_width,row_height,num_rows,current_width,current_height;
  8617.     
  8618.     if (!XtIsRealized((Widget)slw)) return(XtGeometryYes);
  8619.  
  8620.     XtSetArg(multilist_args[0],XtNrowHeight,&row_height);
  8621.     XtSetArg(multilist_args[1],XtNcolumnWidth,&col_width);
  8622.     XtSetArg(slist_args[0],XtNwidth,¤t_width);
  8623.     XtSetArg(slist_args[1],XtNheight,¤t_height);
  8624.     XtGetValues(MyData(slw).list,multilist_args,2);
  8625.     XtGetValues((Widget)slw,slist_args,2);
  8626.  
  8627.     row_height = max(1,row_height);
  8628.     num_rows = max(1,(parent_idea->height / row_height));
  8629.  
  8630.     our_idea->request_mode = (CWWidth | CWHeight);
  8631.     our_idea->width = col_width;
  8632.     our_idea->height = num_rows * row_height;
  8633.  
  8634.     if ((our_idea->width == current_width) &&
  8635.         (our_idea->height == current_height))
  8636.     {
  8637.         return(XtGeometryNo);        /* Prefer To Stay As Is */
  8638.     }
  8639.  
  8640.     if ((our_idea->width == parent_idea->width) &&
  8641.         (our_idea->height == parent_idea->height))
  8642.     {
  8643.         return(XtGeometryYes);        /* Proposed Change Is Fine */
  8644.     }
  8645.  
  8646.     return(XtGeometryAlmost);
  8647. } /* End PreferredGeometry */
  8648.  
  8649.  
  8650. /*---------------------------------------------------------------------------*
  8651.  
  8652.                      L O C A L    R O U T I N E S
  8653.  
  8654.  *---------------------------------------------------------------------------*/
  8655.  
  8656. /*---------------------------------------------------------------*
  8657.  
  8658.     ReCalcChildren(w)
  8659.  
  8660.     This routine takes a ScrolledList widget <w> and updates
  8661.     the widths and positions of the child widgets.
  8662.  
  8663.  *---------------------------------------------------------------*/
  8664.  
  8665. static void ReCalcChildren(w)
  8666. XfwfScrolledListWidget w;
  8667. {
  8668.     int wid_h,wid_w;
  8669.  
  8670.     wid_w = CoreData(w).width;
  8671.     wid_h = CoreData(w).height;
  8672.  
  8673.     XtResizeWidget(MyData(w).viewport,wid_w,wid_h,1);
  8674. } /* End ReCalcChildren */
  8675.  
  8676.  
  8677. /*===========================================================================*
  8678.  
  8679.                     E X P O R T E D    F U N C T I O N S
  8680.  
  8681.  *===========================================================================*/
  8682.  
  8683. /*---------------------------------------------------------------------------*
  8684.  
  8685.     XfwfScrolledListSetList(w,newlist,items,resize,sensitive_array)
  8686.  
  8687.     This routine tries to set the string array to the new array
  8688.     <newlist>.  <items> is the count of strings.  If <items> is 0
  8689.     and the array is NULL terminated, the number of strings will be
  8690.     automatically counted.    The <resize> flag indicates if we want
  8691.     the widget to try to resize itself to hold the new array.  The
  8692.     <sensitive_array> parameter (if non-NULL) contains an array of
  8693.     Booleans representing the sensitivity of the list items.
  8694.  
  8695.  *---------------------------------------------------------------------------*/
  8696.  
  8697. void XfwfScrolledListSetList(w,newlist,items,resize,sensitive_array)
  8698. Widget w;
  8699. char **newlist;
  8700. int items;
  8701. Boolean resize;
  8702. Boolean *sensitive_array;
  8703. {
  8704.     XfwfScrolledListWidget sw;
  8705.  
  8706.     sw = (XfwfScrolledListWidget)w;
  8707.     XfwfMultiListSetNewData((XfwfMultiListWidget)(MyData(sw).list),
  8708.         newlist,items,0,resize,sensitive_array);
  8709.     MyData(sw).item_array = newlist;
  8710.     MyData(sw).item_count = items;
  8711.     MyData(sw).sensitive_array = sensitive_array;
  8712. } /* End XfwfScrolledListSetList */
  8713.  
  8714.  
  8715. /*---------------------------------------------------------------------------*
  8716.  
  8717.     XfwfScrolledListUnhighlightAll(w)
  8718.  
  8719.     This routine unhighlights all highlighted items in the
  8720.     ScrolledList widget <w>.
  8721.  
  8722.  *---------------------------------------------------------------------------*/
  8723.  
  8724. void XfwfScrolledListUnhighlightAll(w)
  8725. Widget w;
  8726. {
  8727.     XfwfScrolledListWidget sw;
  8728.  
  8729.     sw = (XfwfScrolledListWidget)w;
  8730.     XfwfMultiListUnhighlightAll((XfwfMultiListWidget)(MyData(sw).list));
  8731. } /* End XfwfScrolledListUnhighlightAll */
  8732.  
  8733.  
  8734. /*---------------------------------------------------------------------------*
  8735.  
  8736.     XfwfScrolledListHighlightItem(w,item_index)
  8737.  
  8738.     This routine highlights the item with index number <item_index>.
  8739.  
  8740.  *---------------------------------------------------------------------------*/
  8741.  
  8742. void XfwfScrolledListHighlightItem(w,item_index)
  8743. Widget w;
  8744. int item_index;
  8745. {
  8746.     XfwfScrolledListWidget sw;
  8747.  
  8748.     sw = (XfwfScrolledListWidget)w;
  8749.     XfwfMultiListHighlightItem((XfwfMultiListWidget)(MyData(sw).list),
  8750.         item_index);
  8751. } /* End XfwfScrolledListHighlightItem */
  8752.  
  8753.  
  8754. /*---------------------------------------------------------------------------*
  8755.  
  8756.     XfwfScrolledListGetHighlighted(w)
  8757.  
  8758.     This routine returns the current highlighted item.
  8759.  
  8760.  *---------------------------------------------------------------------------*/
  8761.  
  8762. XfwfScrolledListReturnStruct *XfwfScrolledListGetHighlighted(sw)
  8763. XfwfScrolledListWidget sw;
  8764. {
  8765.     XfwfMultiListReturnStruct *pl_ret;
  8766.     XfwfScrolledListReturnStruct sl_ret;
  8767.  
  8768.     sl_ret.multilist = MyData(sw).list;
  8769.  
  8770.     pl_ret = XfwfMultiListGetHighlighted((XfwfMultiListWidget)
  8771.         (MyData(sw).list));
  8772.     if (pl_ret->num_selected != 0)
  8773.     {
  8774.         sl_ret.string = pl_ret->string;
  8775.         sl_ret.index = pl_ret->item;
  8776.         sl_ret.highlighted = True;
  8777.     }
  8778.         else
  8779.     {
  8780.         sl_ret.string = NULL;
  8781.         sl_ret.index = -1;
  8782.         sl_ret.highlighted = False;
  8783.     }
  8784.     return(&sl_ret);
  8785. } /* End XfwfScrolledListGetHighlighted */
  8786.  
  8787.  
  8788. /*---------------------------------------------------------------------------*
  8789.  
  8790.     XfwfScrolledListIsHighlighted(w,item_index)
  8791.  
  8792.     This routine returns a boolean that indicates if the item
  8793.     with index <item_index> was highlighted or not.
  8794.  
  8795.  *---------------------------------------------------------------------------*/
  8796.  
  8797. Boolean XfwfScrolledListIsHighlighted(w,item_index)
  8798. Widget w;
  8799. int item_index;
  8800. {
  8801.     XfwfScrolledListWidget sw;
  8802.  
  8803.     sw = (XfwfScrolledListWidget)w;
  8804.     return(XfwfMultiListIsHighlighted((XfwfMultiListWidget)
  8805.         (MyData(sw).list),item_index));
  8806. } /* End XfwfScrolledListIsHighlighted */
  8807.  
  8808.  
  8809. /*---------------------------------------------------------------------------*
  8810.  
  8811.     XfwfScrolledListGetItem(w,item_index,str_ptr,high_ptr,sens_ptr)
  8812.  
  8813.     This routine returns information about a numbered item including
  8814.     the name of the item, whether it is highlighted, and its
  8815.     sensitivity.  If the item index number does not correspond to an
  8816.     item, False is returned, else True is returned.
  8817.  
  8818.  *---------------------------------------------------------------------------*/
  8819.  
  8820. Boolean XfwfScrolledListGetItem(w,item_index,str_ptr,high_ptr,sens_ptr)
  8821. Widget w;
  8822. int item_index;
  8823. String *str_ptr;
  8824. Boolean *high_ptr,*sens_ptr;
  8825. {
  8826.     XfwfScrolledListWidget sw;
  8827.  
  8828.     sw = (XfwfScrolledListWidget)w;
  8829.     return(XfwfMultiListGetItemInfo((XfwfMultiListWidget)(MyData(sw).list),
  8830.         item_index,str_ptr,high_ptr,sens_ptr));
  8831. } /* End XfwfScrolledListGetItem */
  8832. SHAR_EOF
  8833. fi
  8834. if test -f 'ScrList.h'
  8835. then
  8836.     echo shar: "will not over-write existing file 'ScrList.h'"
  8837. else
  8838. cat << \SHAR_EOF > 'ScrList.h'
  8839. /*****************************************************************************
  8840.  
  8841.     ScrolledList.h
  8842.  
  8843.     This file contains the user includes for the ScrolledList widget.
  8844.  
  8845. ******************************************************************************/
  8846.  
  8847. /*
  8848.  * Author:
  8849.  *     Brian Totty
  8850.  *     Department of Computer Science
  8851.  *     University Of Illinois at Urbana-Champaign
  8852.  *    1304 West Springfield Avenue
  8853.  *     Urbana, IL 61801
  8854.  * 
  8855.  *     totty@cs.uiuc.edu
  8856.  *     
  8857.  */ 
  8858.  
  8859. #ifndef _SCROLLEDLIST_H_
  8860. #define _SCROLLEDLIST_H_
  8861.  
  8862. extern WidgetClass        xfwfScrolledListWidgetClass;
  8863.  
  8864. typedef struct _XfwfScrolledListClassRec *XfwfScrolledListWidgetClass;
  8865. typedef struct _XfwfScrolledListRec      *XfwfScrolledListWidget;
  8866.  
  8867. typedef struct
  8868. {
  8869.     Widget multilist;    /* The list widget clicked on */
  8870.     String string;        /* The name of the item clicked on */
  8871.     int index;        /* The index of the item clicked on */
  8872.     Boolean highlighted;    /* Are any items highlighted? */
  8873. } XfwfScrolledListReturnStruct;
  8874.  
  8875. #define    XtNlist            "list"
  8876. #define    XtNnumberStrings    "numberStrings"
  8877.  
  8878. #ifndef XtNsensitiveArray
  8879. #define    XtNsensitiveArray    "sensitiveArray"
  8880. #endif
  8881.  
  8882. /*===========================================================================*
  8883.  
  8884.                     E X P O R T E D    F U N C T I O N S
  8885.  
  8886.  *===========================================================================*/
  8887.  
  8888. #if (!NeedFunctionPrototypes)
  8889.  
  8890. extern void        XfwfScrolledListSetList();
  8891. extern void        XfwfScrolledListUnhighlightAll();
  8892. extern XfwfScrolledListReturnStruct *
  8893.             XfwfScrolledListGetHighlighted();
  8894. extern Boolean        XfwfScrolledListIsHighlighted();
  8895. extern Boolean        XfwfScrolledListGetItem();
  8896.  
  8897. #else
  8898.  
  8899. extern void        XfwfScrolledListSetList(Widget w, char **newlist,
  8900.                 int items, int resize,
  8901.                 Boolean *sensitive_array);
  8902. extern void        XfwfScrolledListUnhighlightAll(Widget w);
  8903. extern void        XfwfScrolledListHighlightItem(Widget w,
  8904.                 int item_index);
  8905. extern XfwfScrolledListReturnStruct *
  8906.         XfwfScrolledListGetHighlighted(XfwfScrolledListWidget sw);
  8907. extern Boolean        XfwfScrolledListIsHighlighted(Widget w,
  8908.                 int item_index);
  8909. extern Boolean        XfwfScrolledListGetItem(Widget w, int item_index,
  8910.                 String *str_ptr, Boolean *high_ptr,
  8911.                 Boolean *sens_ptr);
  8912.  
  8913. #endif
  8914. #endif
  8915.  
  8916. SHAR_EOF
  8917. fi
  8918. if test -f 'ScrListP.h'
  8919. then
  8920.     echo shar: "will not over-write existing file 'ScrListP.h'"
  8921. else
  8922. cat << \SHAR_EOF > 'ScrListP.h'
  8923. /****************************************************************************
  8924.  
  8925.     ScrolledListP.h
  8926.  
  8927.     This file is the private definition file for the File Selector
  8928.     Widget.
  8929.  
  8930.  ****************************************************************************/
  8931.  
  8932. /*
  8933.  * Author:
  8934.  *     Brian Totty
  8935.  *     Department of Computer Science
  8936.  *     University Of Illinois at Urbana-Champaign
  8937.  *    1304 West Springfield Avenue
  8938.  *     Urbana, IL 61801
  8939.  * 
  8940.  *     totty@cs.uiuc.edu
  8941.  *     
  8942.  */ 
  8943.  
  8944. #ifndef    _SCROLLEDLISTP_H_
  8945. #define _SCROLLEDLISTP_H_
  8946.  
  8947. typedef struct _XfwfScrolledListClassPart
  8948. {
  8949.     int    empty;
  8950. } XfwfScrolledListClassPart;
  8951.  
  8952. typedef struct
  8953. {
  8954.     Widget                list;
  8955.     Widget                viewport;
  8956.     char                **item_array;
  8957.     int                item_count;
  8958.     Boolean                *sensitive_array;
  8959.     XtCallbackList            callback;
  8960. } XfwfScrolledListPart;
  8961.  
  8962. typedef struct _XfwfScrolledListClassRec
  8963. {
  8964.     CoreClassPart            core_class;
  8965.     CompositeClassPart        composite_class;
  8966.     XfwfScrolledListClassPart    scrolledList_class;
  8967. } XfwfScrolledListClassRec;
  8968.  
  8969. typedef struct _XfwfScrolledListRec
  8970. {
  8971.     CorePart            core;
  8972.     CompositePart            composite;
  8973.     XfwfScrolledListPart        scrolledList;
  8974. } XfwfScrolledListRec;
  8975.  
  8976. extern XfwfScrolledListClassRec xfwfScrolledListClassRec;
  8977.  
  8978. #endif
  8979. SHAR_EOF
  8980. fi
  8981. if test -f 'Smart-Go.def'
  8982. then
  8983.     echo shar: "will not over-write existing file 'Smart-Go.def'"
  8984. else
  8985. cat << \SHAR_EOF > 'Smart-Go.def'
  8986.                    DEFINITION OF THE SMART-GO FORMAT
  8987.  
  8988. >From the Dissertation of Anders Kierulf
  8989.  
  8990. "Smart Game Board:
  8991. a Workbench for Game-Playing
  8992. Programs, with Go and Othello
  8993. as Case Studies"
  8994.  
  8995. Entered by Greg Hale with permission for distribution. See the many sample 
  8996. files from the 'My Go Teacher' series for examples. 
  8997.     
  8998. ------------
  8999.  
  9000. A standard file format to exchange machine-readable games, problems,
  9001. and opening libraries would save time and work.  That goal may not be
  9002. too far away.  A standard for exchanging collections of Othello games
  9003. is being worked out by Erik Jensen, Emmanuel Lazard, and Brian Rose in
  9004. collaboration with the author.  For Go, a new standard has recently
  9005. been proposed [Connelley 89, High 89]; it seems to suffer from a wealth
  9006. of features, but any standard for exchanging Go games is welcome, and
  9007. will be supported by the Smart Game Board.
  9008.  
  9009. The current file format is specialized for the needs of the Smart Game
  9010. Board.  It is based on an earlier proposal for a standard for Go games
  9011. [Kierulf 87b] which was not widely adopted.  The following description
  9012. is not a new proposal; it is intended for those who want to read or
  9013. white files that are compatible with the Smart Game Board.
  9014.  
  9015. The game collections (documents) of the Smart Game Board are stored as
  9016. text files.  This has the advantage that files can be manipulated with
  9017. standard text utilities, and that it's easier to exchange games by
  9018. electronic mail.  The disadvantage is that text files are less compact
  9019. than binary files.
  9020.  
  9021. The Smart Game Board stores the game trees of each document, with all
  9022. their nodes and properties, and nothing more.  Thus the file format
  9023. reflects the regular internal structure of a tree of property lists.
  9024. There are no exceptions; if a game needs to store some information on
  9025. file with the document, a (game-specific) property must be defined for
  9026. that purpose.
  9027.  
  9028. I will first define the syntax of the game collections, then discuss
  9029. syntax and semantic of various properties.
  9030.  
  9031.  
  9032. GAME COLLECTIONS
  9033.  
  9034. A collection of game sis simply the concatenation of the game trees.
  9035. The structure of each tree is indicated by parentheses.  A tree is
  9036. written as "(" followed by a sequence of nodes (as long as the tree is
  9037. unbranched) and a tree for each son, and terminated by ")".  Each node
  9038. is preceded by a separator, and contains a list of zero or more
  9039. properties.
  9040.  
  9041. Thus the main branch of the game is stored first in the file, and
  9042. programs can easily read that part (until the first closing
  9043. parenthesis) and ignore the rest.
  9044.  
  9045. The conventions of EBNF are discussed in [Wirth 85].  A quick summary:
  9046.  
  9047. "..." : terminal symbols
  9048. [...] : option: occurs at most once
  9049. {...} : repetition: any number of times, including zero
  9050. (...) : grouping
  9051.   |   : exclusive-or
  9052.  
  9053. The overall definition of the file format is as follows:
  9054.  
  9055.         Collection      = {GameTree}.
  9056.         GameTree        = "(" Sequence {GameTree} ")".
  9057.         Sequence        = Node {Node}.
  9058.         Node            = ";" {Property}
  9059.  
  9060. Any text before the first opening parenthesis is reserved for future
  9061. extensions and is ignored when reading a file.  Spaces, tabs, line
  9062. breaks and so on can be inserted anywhere between properties and are
  9063. also ignored.
  9064.  
  9065.  
  9066. GAME-INDEPENDENT PROPERTIES
  9067.  
  9068. Each property is identified by one or two capital letters.  The
  9069. property value is enclosed in brackets; lists of points or integers are
  9070. written as a sequence of property values.  Within text, a closing
  9071. bracket is prefixed by a backslash, and a backslash is doubled.  Moves
  9072. and points are game-specific and are defined later.
  9073.  
  9074.         Property        = PropIdent PropValue {PropValue}.
  9075.         PropIdent       = UpperCase [UpperCase | Digit].
  9076.         PropValue       = "[" [Number | Text | Real | Triple
  9077.                                   | Color | Move | Point | ... ] "]"
  9078.         Number          = ["+" | "-"] Digit {Digit}.
  9079.         Text            = { any character; "\]" = "]", "\\" = "\"}.
  9080.         Real            = { Number ["." {Digit}].
  9081.         Triple          = ("1" | "2").
  9082.         Color           = ("B" | "W").
  9083.  
  9084. Move and Point are game-specific and are described later.  The
  9085. following properties are understood by all games.  The property type is
  9086. given in brackets.
  9087.  
  9088.         "B" : Black move                [move, game-specific]
  9089.         "W" : White move                [move, game-specific]
  9090.         "C" : Comment                   [Text]
  9091.         "N" : Node Name                 [Text]
  9092.  
  9093. The purpose of providing both a node name and a comment is to have a
  9094. short identifier like "doesn't work" or "Dia. 15" that can be displayed
  9095. directly with the properties of the node, even if the comment is turned
  9096. off or shown in a separate window.  There is no limit to the length of
  9097. texts; programs must be able to ignore the rest of texts that are too
  9098. long for them to handle.  Reasonable limits are 32 characters for node
  9099. names and at least 2000 characters for comments.
  9100.  
  9101.         "V" : Node value                [number]
  9102.  
  9103. Positive values are good for Black, negative values are good for
  9104. White.  The interpretation of particular values is game-specific.
  9105.  
  9106.         "CH": Check mark                [triple]
  9107.         "GB": good for black            [triple]
  9108.         "GW": good for white            [triple]
  9109.         "TE": good move (tesuji)        [triple]
  9110.         "BM": bad move                  [triple]
  9111.  
  9112. The normal value for such properties is one, properties that are
  9113. doubled for emphasis have the value two.
  9114.  
  9115.         "BL": time left for Black       [real]
  9116.         "WL": time left for White       [real]
  9117.  
  9118. All times are given in seconds, or fractions thereof {Hale: these can
  9119. be negative, indicating player is playing past time limit set}.
  9120.  
  9121.         "FG": figure                    [none]
  9122.  
  9123. The figure property is used to divide a game into different figures for
  9124. printing: a new figure starts at the node with a figure property.
  9125.  
  9126.         "AB": add black stones          [point list, game specific]
  9127.         "AW": add white stones          [point list, game specific]
  9128.         "AE": add empty stones          [point list, game specific]
  9129.         "PL": player to play first      [color]
  9130.  
  9131. The above properties are used to set up positions in games with only
  9132. black and white stones.  The following properties are all part of the
  9133. game info:
  9134.  
  9135.         "GN": game name                 [text]
  9136.         "GC": game comment              [text]
  9137.         "EV": event (tournament)        [text]
  9138.         "RO": round                     [text]
  9139.         "DT": date                      [text]
  9140.         "PC": place                     [text]
  9141.         "PB": black player name         [text]
  9142.         "PW": white player name         [text]
  9143.         "RE": result, outcome           [text]
  9144.         "US": user (who entered game)   [text]
  9145.         "TM": time limit per player     [text]
  9146.         "SO": source (book, journal...) [text]
  9147.  
  9148. The format in these game-info strings is free, but to be able to search
  9149. for specific games in game collections, it is recommended to adhere to
  9150. the following conventions:
  9151.  
  9152.         - Date is ISO-standard: "YYYY-MM-DD".
  9153.         - Result as "0" (zero) for a draw, "B+score" for a black win,
  9154.                 and "W+score" for a white win, e.g. "B+2.5", "W+64"
  9155.         - Time limit as a number, in minutes.
  9156.  
  9157. In addition, names, events, and places should be spelled the same im all games.
  9158.  
  9159. The following properties may only be present at the root node:
  9160.  
  9161.         "GM": game [number] (Go=1, Othello=2, chess=3, Nine Mens Morris=5)
  9162.         "SZ": board size        [number]
  9163.         "VW": partial view      [point list, game-specific]
  9164.         "BS": black species     [number] (human=0, modem=-1, computer>0)
  9165.         "WS": white species     [number]
  9166.  
  9167. The game number helps the program reject games it cannot handle (this
  9168. property was mandatory as long as an application could play different
  9169. games).  The view gives two corner points of a rectangular subsection;
  9170. an empty list denotes the whole board.  The species denotes the kind of
  9171. player (the source of the more input), with different version of
  9172. computer algorithms denoted by positive numbers (default algorithm =
  9173. 1).
  9174.  
  9175. Computer algorithms may add the following properties:
  9176.  
  9177.         "EL": evaluation of computer move       [number]
  9178.         "EX": expected next move                [move, game-specific]
  9179.  
  9180. Some games support markings on the board: selected points,
  9181. triangles/crosses, or letters (a sequence of letters is shown on the
  9182. points given in the list, starting with "A"):
  9183.  
  9184.         "SL": selected points                   [point list, game-specific]
  9185.         "M" : marked points                     [point list, game-specific]
  9186.         "L" : letters on points                 [point list, game-specific]
  9187.  
  9188.  
  9189. GO-SPECIFIC PROPERTIES
  9190.  
  9191. In my proposal for a standard [Kierul 87b], I intentionally broke with
  9192. the tradition of labeling moves (and points) with letters "A"-"T"
  9193. (excluding "i") and numbers 1-19.  Two lowercase letters in the range
  9194. "a"-"s" were used instead, for reasons of simplicity and compactness.
  9195. This was criticized mainly because it was not human-readable, but as
  9196. that is not an important feature of this file format, I continue to use
  9197. that notation.
  9198.  
  9199. (Hale: diagram omitted)
  9200.  
  9201. The first letter designated the column (left to right), the second the
  9202. row (top to bottom).  The upper left part of the board is used for
  9203. smaller boards, e.g. letters "a"-"m" for 13*13.  (Column before row
  9204. follows the principle "horizontal before vertical" used in x-y
  9205. coordinate systems.  The upper left corner as origin of the board
  9206. corresponds to the way we read, and most modern computers use it as
  9207. origin of the screen coordinates to simplify integration of text and
  9208. graphics.)  A pass move is written as "tt".
  9209.  
  9210. The board must be quadratic, no smaller than 2x2, and no larger than
  9211. 19x19.
  9212.  
  9213. Additional game info properties are defined for Go:
  9214.  
  9215.         "BR": Black's rank              [text]
  9216.         "WR": White's rank              [text]
  9217.         "HA": handicap                  [number]
  9218.         "KM": komi                      [real]
  9219.  
  9220. Sets of board points can be marked as territory, as secure stones, or
  9221. just as a region of the board (e.g. to designate eye space):
  9222.  
  9223.         "TB": Black's territory         [point list]
  9224.         "TW": White's territory         [point list]
  9225.         "SC": secure stones             [point list]
  9226.         "RG": region of the board       [point list]
  9227.  
  9228. SHAR_EOF
  9229. fi
  9230. if test -f 'Spec.io'
  9231. then
  9232.     echo shar: "will not over-write existing file 'Spec.io'"
  9233. else
  9234. cat << \SHAR_EOF > 'Spec.io'
  9235.                         INTERFACE SPECIFICATION FOR MGT
  9236.  
  9237. If you wish to add a new interface to mgt, these are the functions you need to 
  9238. come up with.
  9239.  
  9240. void open()
  9241.         Initialize interface.  Any *interface* specific initialization is done
  9242.         here.
  9243.  
  9244. void close()
  9245.         Leave the interface.
  9246.  
  9247. void refreshIO()
  9248.         update screen to look like memory image.  Somewhat curses specific.
  9249.         Probably will be a null function null(){} in most interfaces.
  9250.  
  9251. void plotPiece(pBoard b, int i, int j)
  9252.         Plots the piece contained in b at i,j on the real screen.
  9253.         Board is read by call boardGet(b, i, j) which returns
  9254.         one of P_NOTHING, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR,
  9255.         or P_WHITETERR. 
  9256.  
  9257.  
  9258. void clearComment()
  9259.         Clears comment window
  9260.  
  9261. void initBoard()
  9262.         Draw a blank board of size 'boardsize'
  9263.  
  9264. void clearScreen()
  9265.         clears screen. 
  9266.  
  9267. int idle(nodep n) 
  9268.         Gets the next command.  Acts like an event driven loop.
  9269.         Waits for keystroke.  Returns a command casted to an int
  9270.         to indicate the command for doit.c to process.
  9271.  
  9272. void drawTree(nodep n)
  9273.         Show the variations that are available in the var list on 
  9274.         the right when starting at node n. (in Ascii version)
  9275.         Interface-local variables exists to handle scrolling.
  9276.         scrolling should be handled by the interface alone.
  9277.  
  9278. void highlightLast(int x, y, movenum, turn)
  9279.         Show last move number, current turn, whose move it is,
  9280.         and the prisoner count.
  9281.         turn==0 means Black just moved.
  9282.         If x and y are equal to PASSVAL then the move was a pass.
  9283.         Use these to get current player turn and prisoner count
  9284.         extern int prisoners[black=0,white=1] ;
  9285.         extern int curPlayer;
  9286.  
  9287. void readEnv(char **env)
  9288.         Check *env for environment string.  Increment it to point to 
  9289.         the first character not used.
  9290.  
  9291. void notifyMessage(char *s)
  9292.         Print single line message someplace.
  9293.  
  9294. void notifyClear()
  9295.         Clear notify message area
  9296.  
  9297. int queryStr(char *query, char *dst, int maxLen)
  9298.         Print query out.  Get at most maxLen chars into dst.
  9299.         Return length of the result.
  9300.  
  9301. void setCursor(int i, int j)
  9302.         Move cursor (pointer) to position i,j on go board
  9303.  
  9304. void plotMark(pBoard b,int i,int j) 
  9305.         Plot mark at position i,j on displayed board.
  9306.         DOES NOT modify *b.
  9307.         Mark is erased by call to plotPiece
  9308.  
  9309. void plotLetter(int i, int j, char c)
  9310.         Puts letter c on the screen at board position i,j
  9311.  
  9312. int getPoint()    
  9313.         Allow user to specify a board position (Cursor
  9314.         keys, mouse, etc) Used when scoring the game.
  9315.         Uses globals xcur and ycur to
  9316.         store the position.  The return value 
  9317.         can be C_QUIT to abort score.  C_SCORE to calculate
  9318.         the score.  C_REDRAW to redraw screen, or C_NOTHING
  9319.         to kill the group we're on right now.
  9320.  
  9321. void editComment(char *inp, char **out)
  9322.         Edit a comment.  inp contains the input comment to be
  9323.         edited.  THIS MUST BE free()'d.  out contains the return
  9324.         pointer.  It should be allocated to the appropriate size
  9325.         and the new edited comment should be placed in the
  9326.         allocated space.
  9327.  
  9328. int askYN(char *query, int defalt)
  9329.         Prompt user with query.  The query will NOT end in " (y/n)? " 
  9330.         If needed by the interface, this should be added here. 
  9331.         Returns 1 for yes, 0 for no.  defalt contains the default 
  9332.         response (1 for yes, 0 for no).
  9333.  
  9334. void notifyError(char *errormsg)
  9335.         Display error message.  Give user a chance to see it, and
  9336.         clear message.  
  9337.  
  9338. void displayInfo(char *s)
  9339.         Formats and displays string s as a list of game information.  Each
  9340.         informational item starts on its own line but may contain newlines.
  9341.  
  9342. Token getInfoToChange()
  9343.         Passes back an informational token to change, or t_EOF to escape
  9344.         from the info editor.  (Scrolling of the info region should be 
  9345.         handled internally here.)
  9346.  
  9347. void editInfo(char *input, char **output, property info_item)
  9348.     Edits the info item corresponding to info_item.  The current
  9349.         text is given in input which should be freed.  The replacement
  9350.         text should be put in *output which needs to be allocated by 
  9351.         this function.  (This works like the comment editor.)
  9352. SHAR_EOF
  9353. fi
  9354. if test -f 'advunix.c'
  9355. then
  9356.     echo shar: "will not over-write existing file 'advunix.c'"
  9357. else
  9358. cat << \SHAR_EOF > 'advunix.c'
  9359. /*  advunix.c
  9360.  *
  9361.  *  Copyright (c) 1992 by Chien-Min Wang.
  9362.  *  All rights reserved.
  9363.  */
  9364.  
  9365. #include <stdio.h>
  9366. #include <errno.h>
  9367. #include <fcntl.h>
  9368. #include "advunix.h"
  9369.  
  9370. /*    print system call error message and terminate    */
  9371. void syserr(msg)
  9372. char *msg;
  9373. {
  9374.     extern int errno, sys_nerr;
  9375.     extern char *sys_errlist[];
  9376.     
  9377.     fprintf(stderr, "ERROR: %s (%d", msg, errno);
  9378.     if (errno > 0 && errno < sys_nerr)
  9379.     fprintf(stderr, "; %s)\n", sys_errlist[errno]);
  9380.     else
  9381.     fprintf(stderr, ")\n");
  9382.     exit(1);
  9383. }
  9384.  
  9385. /*    print error message and terminate    */
  9386. void fatal(msg)
  9387. char *msg;
  9388. {
  9389.     fprintf(stderr, "ERROR: %s\n", msg);
  9390.     exit(1);
  9391. }
  9392.  
  9393. /*    turn blocking on or off        */
  9394. void setblock(fd, on)
  9395. int fd;
  9396. BOOLEAN on;
  9397. {
  9398.     static int blockf, nonblockf;
  9399.     static BOOLEAN first = TRUE;
  9400.     int flags;
  9401.  
  9402.     if (first) {
  9403.     first = FALSE;
  9404.     if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
  9405.         syserr("fnctl");
  9406.     blockf = flags & ~O_NDELAY;    /* make sure O_NDELAY is off */
  9407.     nonblockf = flags | O_NDELAY;    /* make sure O_NDELAY is on */
  9408.     }
  9409.     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
  9410.     syserr("fcntl2");
  9411. }
  9412.  
  9413. static BOOLEAN inbuf = FALSE;
  9414. static char cbuf;
  9415.  
  9416. /*    test if a character is ready    */
  9417. BOOLEAN cready()
  9418. {
  9419.     if (inbuf)
  9420.     return TRUE;
  9421.     setblock(0, FALSE);
  9422.     switch (read(0, &cbuf, 1)) {
  9423.     case -1:
  9424.     if(errno != EWOULDBLOCK)    /* test if 4.2BSD style */
  9425.         syserr("read");
  9426.     case 0:
  9427.     return(inbuf = FALSE);    /* could be EOF too */
  9428.     default:
  9429.     return(inbuf = TRUE);
  9430.     }
  9431. }
  9432.  
  9433. /*    get a character        */
  9434. int cget()
  9435. {
  9436.     if (inbuf) {
  9437.     inbuf = FALSE;
  9438.     return(cbuf & 0377);    /* prevent sign extension */
  9439.     }
  9440.     setblock(0, TRUE);
  9441.     switch (read(0, &cbuf, 1)) {
  9442.     case -1:
  9443.     syserr("read");
  9444.     case 0:
  9445.     return(-1);    /* must be EOF */
  9446.     default:
  9447.     return(cbuf & 0377);
  9448.     }
  9449. }
  9450.  
  9451. /*    get a line of characters    */
  9452. BOOLEAN lget(s, max)
  9453. char *s;
  9454. int max;
  9455. {
  9456.     register int i;
  9457.     char c;
  9458.  
  9459.     i = 0;
  9460.     if (inbuf) {
  9461.     s[i++] = cbuf;
  9462.     inbuf = FALSE;
  9463.     }
  9464.     setblock(0, FALSE);
  9465.     while (TRUE) {
  9466.         switch (read(0, &c, 1)) {
  9467.         case -1:
  9468.         if(errno != EWOULDBLOCK)    /* test if 4.2BSD style */
  9469.             syserr("read");
  9470.         case 0:
  9471.         if (i >= max)
  9472.             fatal("lget overflow");
  9473.         s[i] = '\0';
  9474.         return(FALSE);    /* could be EOF too */
  9475.         default:
  9476.         if (i >= max)
  9477.             fatal("lget overflow");
  9478.         s[i++] = c;
  9479.         if ((c == '\n') || (c == '\r')) {
  9480.             if (i >= max)
  9481.                 fatal("lget overflow");
  9482.         s[i] = '\0';
  9483.             return(TRUE);
  9484.         }
  9485.     }
  9486.     }
  9487. }
  9488.  
  9489. SHAR_EOF
  9490. fi
  9491. if test -f 'advunix.h'
  9492. then
  9493.     echo shar: "will not over-write existing file 'advunix.h'"
  9494. else
  9495. cat << \SHAR_EOF > 'advunix.h'
  9496. /*  advunix.h
  9497.  *
  9498.  *  Copyright (c) 1992 by Chien-Min Wang.
  9499.  *  All rights reserved.
  9500.  */
  9501.  
  9502. #define lowbyte(w)    ((w) & 0377)
  9503. #define highbyte(w)    lowbyte((w) >> 8)
  9504.  
  9505. #undef TRUE
  9506. #undef FALSE
  9507.  
  9508. typedef enum {FALSE, TRUE} BOOLEAN;
  9509.  
  9510. SHAR_EOF
  9511. fi
  9512. if test -f 'build.c'
  9513. then
  9514.     echo shar: "will not over-write existing file 'build.c'"
  9515. else
  9516. cat << \SHAR_EOF > 'build.c'
  9517. /* "mgt" Copyright (c) 1991 Shodan  */
  9518.  
  9519. #include "mgt.h"
  9520.  
  9521. int lastMoveX, lastMoveY, moveNum, lastTurn;
  9522. coordList *lastletters = 0, *lastmarks;
  9523. coordList *marks = 0;
  9524. coordList *letters = 0;
  9525.  
  9526.  
  9527. FUNCTION void clearLast()
  9528. {
  9529.    lastMoveX = lastMoveY = -1;
  9530.    moveNum = 0;
  9531. }
  9532.  
  9533. FUNCTION void highlightLast()
  9534. {
  9535.    extern Token curPlayer;
  9536.    if (lastMoveX >= 0 && moveNum > 0 && lastTurn != (int) t_EOF)
  9537.       curPlayer = lastTurn ? t_Black : t_White;
  9538.    (*io->highlightLast) (lastMoveX, lastMoveY, moveNum, lastTurn);
  9539.  
  9540. }
  9541.  
  9542.  
  9543. FUNCTION void doPlace(p, b, t)
  9544. property *p;
  9545. pBoard b;
  9546. piece t;
  9547. {
  9548.    coordList *list;
  9549.  
  9550.    list = p->data.stones;
  9551.    while (list) {
  9552.       placeStone(b, list->x, list->y, t);
  9553.       list = list->next;
  9554.    }
  9555.    if (p->t == t_Black || p->t == t_White)
  9556.       moveNum++;
  9557.  
  9558. }
  9559.  
  9560.  
  9561.  
  9562.  
  9563. FUNCTION void doProps(p, b)
  9564. property *p;
  9565. pBoard b;
  9566. {
  9567.    letters = NULL;
  9568.    marks = NULL;
  9569.    while (p) {
  9570.       switch (p->t) {
  9571.      case t_White:
  9572.         BUG("t_White ");
  9573.         doPlace(p, b, P_WHITE);
  9574.         break;
  9575.      case t_Black:
  9576.         BUG("t_Black ");
  9577.         doPlace(p, b, P_BLACK);
  9578.         break;
  9579.      case t_AddWhite:
  9580.         BUG("t_AddWhite ");
  9581.         doPlace(p, b, P_WHITE);
  9582.         break;
  9583.      case t_AddBlack:
  9584.         BUG("t_AddBlack ");
  9585.         doPlace(p, b, P_BLACK);
  9586.         break;
  9587.      case t_AddEmpty:
  9588.         BUG("t_AddEmpty ");
  9589.         doPlace(p, b, P_NOTHING);
  9590.         break;
  9591.      case t_Comment:
  9592.         break;
  9593.      case t_Pass:
  9594.         moveNum++;
  9595.         break;
  9596.      case t_Mark:
  9597.         marks = p->data.stones;
  9598.         break;
  9599.      case t_Letter:
  9600.         letters = p->data.stones;
  9601.         BUG("t_Letter ");
  9602.         break;
  9603.      default:
  9604.         BUG("default ");
  9605.       }
  9606.       p = p->next;
  9607.    }
  9608. }
  9609.  
  9610. static void setLastMovePos(p)
  9611. property *p;
  9612. {
  9613.    lastTurn = p->t == t_White ? 1 : 0;
  9614.    if (p->data.stones) {
  9615.       lastMoveX = p->data.stones->x;
  9616.       lastMoveY = p->data.stones->y;
  9617.    } else
  9618.       lastMoveX = lastMoveY = -1;
  9619.  
  9620. }
  9621.  
  9622.  
  9623. FUNCTION void doPropComment(n)
  9624. nodep n;
  9625. {
  9626.    property *p;
  9627.  
  9628.    if (p = getprop(n, t_Comment))
  9629.       (*io->displayComment) (p->data.comment);
  9630.  
  9631.    if (p = getprop(n, t_Black))
  9632.       setLastMovePos(p);
  9633.    else if (p = getprop(n, t_White))
  9634.       setLastMovePos(p);
  9635.  
  9636.    if (p = getprop(n, t_Pass)) {
  9637.       lastTurn = p->data.player == t_White ? 1 : 0;
  9638.       lastMoveX = lastMoveY = PASSVAL;
  9639.    }
  9640. }
  9641.  
  9642. FUNCTION void buildTree0(n, b)
  9643. nodep n;
  9644. pBoard b;
  9645. {
  9646.    BUG("parent >");
  9647.    if (n) {
  9648.       buildTree0(n->parent, b);
  9649.       BUG("\nprops:");
  9650.       doProps(n->p, b);
  9651.    }
  9652. }
  9653.  
  9654.  
  9655.  
  9656. FUNCTION void buildTree(n, b)
  9657. nodep n;
  9658. pBoard b;
  9659. {
  9660.    extern int prisoners[];
  9661.    prisoners[0] = 0;
  9662.    prisoners[1] = 0;
  9663.    boardClear(b);
  9664.    (*io->clearComment) ();
  9665.    BUG("buildTree:\n");
  9666.    clearLast();
  9667.    buildTree0(n, b);
  9668.    doPropComment(n);
  9669. }
  9670.  
  9671.  
  9672. FUNCTION void setPiece(b, i, j, p)
  9673. pBoard b;
  9674. int i, j;
  9675. piece p;
  9676. {
  9677.    boardSet(b, i, j, p);
  9678.    (*io->plotPiece) (b, i, j);
  9679. }
  9680.  
  9681. FUNCTION void updateBoard(dst, new)
  9682. pBoard dst, new;        /* update dst to look like new */
  9683. {
  9684.    extern int prisoners[];
  9685.    int i, j;
  9686.    coordList *cl;
  9687.  
  9688.    for (cl = lastmarks; cl; cl = cl->next)
  9689.       (*io->plotPiece) (new, cl->x, cl->y);
  9690.  
  9691.    for (cl = lastletters; cl; cl = cl->next)
  9692.       (*io->plotPiece) (new, cl->x, cl->y);
  9693.    lastmarks = marks;
  9694.    lastletters = letters;
  9695.    for (i = boardsize; i--;)
  9696.       for (j = boardsize; j--;) {
  9697.      if (boardGet(new, i, j) != boardGet(dst, i, j)) {
  9698.         setPiece(dst, i, j, boardGet(new, i, j));
  9699.      }
  9700.       }
  9701.    if (marks) {
  9702.       for (cl = marks; cl; cl = cl->next)
  9703.      (*io->plotMark) (new, cl->x, cl->y);
  9704.       marks = NULL;
  9705.    }
  9706.    if (letters) {
  9707.       for (i = 0, cl = letters; cl; cl = cl->next, i++)
  9708.      (*io->plotLetter) (cl->x, cl->y, (i % 26) + 'a');
  9709.       letters = NULL;
  9710.    }
  9711. }
  9712. SHAR_EOF
  9713. fi
  9714. if test -f 'comment.c'
  9715. then
  9716.     echo shar: "will not over-write existing file 'comment.c'"
  9717. else
  9718. cat << \SHAR_EOF > 'comment.c'
  9719. /* "mgt" Copyright (c) 1991 Shodan  */
  9720.  
  9721. #include "mgt.h"
  9722. #include <string.h>
  9723. #include <ctype.h>
  9724.  
  9725.  
  9726. short clines;
  9727. char cbuf[MAXCOMMENTLINES][MAXCOMMENTWIDTH];
  9728. char *empty = "";
  9729.  
  9730. FUNCTION char *commentGet(line)    /* int */
  9731. int line;
  9732. {
  9733.    if (line < clines)
  9734.       return cbuf[line];
  9735.    else
  9736.       return empty;
  9737. }
  9738.  
  9739. FUNCTION int commentLines()
  9740. {
  9741.    return clines;
  9742. }
  9743.  
  9744.  
  9745.  
  9746.  
  9747. FUNCTION void formatComment(comment, width)
  9748. char *comment;
  9749. int width;
  9750. {
  9751.    char *partstart, *dest, c;
  9752.    int len, partlen, wordlen;
  9753.  
  9754.    clines = 0;
  9755.    width = MIN(width, MAXCOMMENTWIDTH - 1);
  9756.    wordlen = partlen = len = 0;
  9757.    dest = cbuf[0];
  9758.    if (*comment == '\n')
  9759.       comment++;
  9760.    partstart = comment;
  9761.    do {
  9762.       c = *(comment++);
  9763.       len++;
  9764.       partlen++;
  9765.       wordlen++;
  9766.       if (c == ' ')
  9767.      wordlen = 0;
  9768.       else if (c == '\n' && *(comment - 2) == ' ' &&
  9769.            *comment != '\n') {
  9770.      partlen--;
  9771.      len--;
  9772.      strncpy(dest, partstart, partlen);
  9773.      dest += partlen;
  9774.      partstart = comment;
  9775.      wordlen = partlen = 0;
  9776.       } else if (c == '\n' || !c) {
  9777.      strncpy(dest, partstart, partlen - 1);
  9778.      *(dest + partlen - 1) = 0;
  9779.      len = partlen = wordlen = 0;
  9780.      dest = cbuf[++clines];
  9781.      partstart = comment;
  9782.       }
  9783.       if (len == width) {
  9784.  
  9785.      if (len == wordlen)
  9786.         wordlen = 0;
  9787.  
  9788.      else
  9789.         len = partlen - wordlen;
  9790.  
  9791.      strncpy(dest, partstart, len);
  9792.      partstart += len;
  9793.      *(dest + len) = 0;
  9794.      len = partlen = wordlen;
  9795.  
  9796.      dest = cbuf[++clines];
  9797.       }
  9798.    } while (c && clines < MAXCOMMENTLINES);
  9799.  
  9800. }
  9801. SHAR_EOF
  9802. fi
  9803. if test -f 'doit.c'
  9804. then
  9805.     echo shar: "will not over-write existing file 'doit.c'"
  9806. else
  9807. cat << \SHAR_EOF > 'doit.c'
  9808. /* "mgt" Copyright (c) 1991 Shodan  */
  9809.  
  9810. #include "mgt.h"
  9811.  
  9812. int xcur, ycur;
  9813. Token curPlayer;
  9814. int change;
  9815. int madechanges;
  9816. int searchNodeNum;
  9817. int ispl = 0;
  9818.  
  9819. FUNCTION int okChange()
  9820. {
  9821.    if (tutor) {
  9822.       (*io->notifyError) ("Can't edit in tutor mode.");
  9823.       return 0;
  9824.    }
  9825.    if ((!change) && ((*io->askYN) ("Modify tree", 0)))
  9826.       change = 1;
  9827.    if (change)
  9828.       madechanges = 1;
  9829.    return change;
  9830. }
  9831.  
  9832.  
  9833.  
  9834. FUNCTION int okExit(root)
  9835. nodep root;
  9836. {
  9837.    if (mailFlag) {
  9838.       if (madechanges) {
  9839.      if (!(*io->askYN) ("Save", 1)) {
  9840.         retVal = 1;
  9841.         return 1;
  9842.      }
  9843.      if (writeTree(saveName, root))
  9844.         return 0;
  9845.      return 1;
  9846.       }
  9847.       retVal = 1;
  9848.       return 1;
  9849.    }
  9850.    if (madechanges) {
  9851.       if ((*io->askYN) ("Unsaved changes.  Exit without saving", 0))
  9852.      return 1;
  9853.       return 0;
  9854.    }
  9855.    return 1;
  9856. }
  9857.  
  9858.  
  9859.  
  9860. FUNCTION nodep search(n)    /* return 0 on failure */
  9861. nodep n;
  9862. {
  9863.    nodep s;
  9864.    if (!n || n->nodeNum == searchNodeNum)
  9865.       return n;
  9866.    s = search(child(n));
  9867.    if (s && s->nodeNum == searchNodeNum)
  9868.       return s;
  9869.    s = search(nextSibling(n));
  9870.    if (s && s->nodeNum == searchNodeNum)
  9871.       return s;
  9872.    return (nodep) 0;
  9873. }
  9874.  
  9875. FUNCTION void step(n, b)
  9876. nodep n;
  9877. pBoard b;
  9878. {
  9879.    board temp;
  9880.    buildTree(n, &temp);
  9881.    updateBoard(b, &temp);
  9882.    (*io->drawTree) (n);
  9883.    (*io->refreshIO) ();
  9884.    highlightLast();
  9885. }
  9886.  
  9887. FUNCTION void stepDown(n, b)
  9888. nodep n;
  9889. pBoard b;
  9890. {
  9891.    board temp;
  9892.    (*io->clearComment) ();
  9893.    copyBoard(b, &temp);
  9894.    doProps(n->p, &temp);
  9895.    doPropComment(n);
  9896.    updateBoard(b, &temp);
  9897.    (*io->drawTree) (n);
  9898.    (*io->refreshIO) ();
  9899.    highlightLast();
  9900. };
  9901.  
  9902.  
  9903. static char *color[] =
  9904. {
  9905.    "Black", "White"
  9906. };
  9907.  
  9908.  
  9909. int adjust(val, halfk, ksign)
  9910. int val, halfk, ksign;
  9911. {
  9912.    if (!halfk)
  9913.       return val;
  9914.    if (val * ksign >= 0)
  9915.       return val;
  9916.    return val + ksign;
  9917. }
  9918.  
  9919.  
  9920. FUNCTION void doScore(b, curNode)
  9921. pBoard b;
  9922. nodep curNode;
  9923. {
  9924.    extern int prisoners[];
  9925.    int savepris[2], lastpris[2];
  9926.    char out[200];
  9927.    command c;
  9928.    property *p;
  9929.    board new, old, last;
  9930.    int score[2], scored;
  9931.    char komicopy[10];
  9932.    int intkomi, halfkomi, kptr, komisign, winner, diff;
  9933.  
  9934.    winner = -1;
  9935.    scored = 0;
  9936.    lastpris[1] = savepris[1] = prisoners[1];
  9937.    lastpris[0] = savepris[0] = prisoners[0];
  9938.    copyBoard(b, &old);
  9939.    copyBoard(b, &last);
  9940.    copyBoard(b, &new);
  9941.    (*io->notifyClear) ();
  9942.    (*io->notifyMessage) ("return score, space kill, u undo, q quit");
  9943.    do {
  9944.       c = (command) (*io->getPoint) ();
  9945.       if (c == C_MOVE && (new.b[xcur][ycur] == P_WHITE ||
  9946.               new.b[xcur][ycur] == P_BLACK)
  9947.      ) {
  9948.      if (scored) {
  9949.         scored = 0;
  9950.         copyBoard(&last, &new);
  9951.         prisoners[1] = lastpris[1];
  9952.         prisoners[0] = lastpris[0];
  9953.      }
  9954.      copyBoard(&new, &last);
  9955.      lastpris[1] = prisoners[1];
  9956.      lastpris[0] = prisoners[0];
  9957.      removeStones(&new, xcur, ycur);
  9958.      updateBoard(b, &new);
  9959.       }
  9960.       if (c == C_UNDO) {
  9961.      copyBoard(&last, &new);
  9962.      prisoners[1] = lastpris[1];
  9963.      prisoners[0] = lastpris[0];
  9964.      updateBoard(b, &new);
  9965.       }
  9966.       if (c == C_SCORE && !scored) {
  9967.      copyBoard(&new, &last);
  9968.      lastpris[1] = prisoners[1];
  9969.      lastpris[0] = prisoners[0];
  9970.      scoreBoard(&new, score);
  9971.      updateBoard(b, &new);
  9972.      if (info[t_Komi - FIRSTINFO]) {
  9973.         halfkomi = 0;
  9974.         for (kptr = 0; info[t_Komi - FIRSTINFO][kptr]; kptr++) {
  9975.            if (info[t_Komi - FIRSTINFO][kptr] == '.') {
  9976.           kptr++;
  9977.           if (info[t_Komi - FIRSTINFO][kptr] >= '1' && info[t_Komi - FIRSTINFO][kptr] <= '9')
  9978.              halfkomi = 1;
  9979.           break;
  9980.            }
  9981.            komicopy[kptr] = info[t_Komi - FIRSTINFO][kptr];
  9982.         }
  9983.         komicopy[kptr] = 0;
  9984.         intkomi = atoi(komicopy);
  9985.         komisign = 0;
  9986.         if (komicopy[0] == '-' || intkomi < 0)
  9987.            komisign = -1;
  9988.         else if (intkomi > 0 || halfkomi)
  9989.            komisign = 1;
  9990.         sprintf(komicopy, "+ %s ", info[t_Komi - FIRSTINFO]);
  9991.      } else {
  9992.         komisign = intkomi = halfkomi = 0;
  9993.         strcpy(komicopy, "");
  9994.      }
  9995.  
  9996.      diff = score[1] + prisoners[0] - score[0] - prisoners[1] + intkomi;
  9997.  
  9998.      if (!diff) {
  9999.         if (halfkomi) {
  10000.            if (komisign > 0)
  10001.           winner = 1;
  10002.            else if (komisign < 0)
  10003.           winner = 0;
  10004.         } else
  10005.            winner = 2;
  10006.      } else
  10007.         winner = diff > 0 ? 1 : 0;
  10008.  
  10009.  
  10010.      diff = adjust(diff, halfkomi, komisign);
  10011.      sprintf(out,
  10012.          "Black: %d + %d = %d\n\nWhite: %d + %d %s= %s%d%s\n\n",
  10013.          score[0], prisoners[1], score[0] + prisoners[1],
  10014.          score[1], prisoners[0], komicopy, (!diff) && halfkomi && (komisign == -1) ? "-" : "",
  10015.          adjust(score[1] + prisoners[0] + intkomi, halfkomi, komisign),
  10016.          halfkomi ? ".5" : "");
  10017.      if (winner == 2)
  10018.         sprintf(out + strlen(out), "Tie game.");
  10019.      else
  10020.         sprintf(out + strlen(out), "%s wins by %d%s",
  10021.             color[winner], abs(diff), halfkomi ? ".5" : "");
  10022.  
  10023.  
  10024.      (*io->clearComment) ();
  10025.      (*io->displayComment) (out);
  10026.      scored = 1;
  10027.       }
  10028.    }
  10029.    while (c != C_QUIT);
  10030.  
  10031.    if (scored && (*io->askYN) ("Keep comment", 1) && okChange())
  10032.       replaceComment(curNode, out);
  10033.    else {
  10034.       (*io->clearComment) ();
  10035.       if (p = getprop(curNode, t_Comment))
  10036.      (*io->displayComment) (p->data.comment);
  10037.    }
  10038.  
  10039.    prisoners[0] = savepris[0];
  10040.    prisoners[1] = savepris[1];
  10041.  
  10042.    (*io->notifyClear) ();
  10043.    updateBoard(b, &old);
  10044. }
  10045.  
  10046.  
  10047.  
  10048. static void initBoard(b)
  10049. pBoard b;
  10050. {
  10051.    extern coordList *lastmarks, *lastletters;
  10052.  
  10053.    boardClear(b);
  10054.    (*io->initializeBoard) ();
  10055.    lastletters = lastmarks = 0;
  10056. }
  10057.  
  10058.  
  10059.  
  10060. FUNCTION nodep loadFile(filename, root, b)
  10061. char *filename;
  10062. nodep root;
  10063. board *b;
  10064. {
  10065.    openfile(filename);
  10066.    if (input) {
  10067.       madechanges = change = 0;
  10068.       freeNode(root);
  10069.       initNodes();
  10070.       readInit();
  10071.       root = parse(0);
  10072.       fclose(input);
  10073.       if (!root)
  10074.      root = newNode();
  10075.       initBoard(b);
  10076.       (*io->setCursor) (xcur, ycur);
  10077.       (*io->refreshIO) ();
  10078.       xcur = ycur = 0;
  10079.    } else
  10080.       (*io->notifyError) ("Unable to load file.");
  10081.    return root;
  10082. }
  10083.  
  10084.  
  10085. FUNCTION nodep makeTutor(nod, tok, x, y)
  10086. nodep nod;
  10087. Token tok;
  10088. int x, y;
  10089. {
  10090.    property *prop;
  10091.    if (!nod->child)
  10092.       return 0;
  10093.    nod = nod->child;
  10094.    while (!((prop = getprop(nod, tok)) && getCoord(x, y, prop->data.stones))) {
  10095.       if (!nod->nextSibling)
  10096.      return 0;
  10097.       nod = nod->nextSibling;
  10098.    }
  10099.    return nod;
  10100. }
  10101.  
  10102.  
  10103.  
  10104.  
  10105.  
  10106. static char *infotitle[] =
  10107. {
  10108.    "Game name: ",
  10109.    "Event: ",
  10110.    "rouNd: ",
  10111.    "Date: ",
  10112.    "Place: ",
  10113.    "Time limit: ",
  10114.    "Result: ",
  10115.    "Comment: ",
  10116.    "sOurce: ",
  10117.    "User: ",
  10118.    "Komi: "
  10119. };
  10120.  
  10121.  
  10122.  
  10123.  
  10124. static void showinfo()
  10125. {
  10126.    char infoarray[4000];
  10127.    char *infostr;
  10128.    int p;
  10129.  
  10130.    infostr = infoarray;
  10131.  
  10132.    sprintf(infostr, "Size: %d", boardsize);
  10133.    while (*infostr)
  10134.       infostr++;
  10135.    if (info[(int) t_Komi - FIRSTINFO]) {
  10136.       sprintf(infostr, "  Komi: %s", info[(int) t_Komi - FIRSTINFO]);
  10137.       while (*infostr)
  10138.      infostr++;
  10139.    }
  10140.    if (handicap) {
  10141.       sprintf(infostr, "  Handicap: %d", handicap);
  10142.       while (*infostr)
  10143.      infostr++;
  10144.    }
  10145.    *infostr = '\n';
  10146.    infostr++;
  10147.  
  10148.    if (info[0] || info[1]) {
  10149.       sprintf(infostr, "Black: %s%s%s\n", info[0] ? info[0] : "",
  10150.           info[0] && info[1] ? ", " : "",
  10151.           info[1] ? info[1] : "");
  10152.       while (*infostr)
  10153.      infostr++;
  10154.    }
  10155.    if (info[2] || info[3]) {
  10156.       sprintf(infostr, "White: %s%s%s\n", info[2] ? info[2] : "",
  10157.           info[2] && info[3] ? ", " : "",
  10158.           info[3] ? info[3] : "");
  10159.       while (*infostr)
  10160.      infostr++;
  10161.    }
  10162.    for (p = 0; p <= LASTINFO - FIRSTINFO - 4; p++) {
  10163.       if (info[p + 4]) {
  10164.      sprintf(infostr, "%s%s\n", infotitle[p], info[p + 4]);
  10165.      while (*infostr)
  10166.         infostr++;
  10167.       }
  10168.    }
  10169.    *infostr = 0;
  10170.    (*io->displayInfo) (infoarray);
  10171.  
  10172. }
  10173.  
  10174.  
  10175. #define BUFFERSIZE 50
  10176.  
  10177.  
  10178. static int doinfo()
  10179. {
  10180.    Token change;
  10181.    int sizechanged, value;
  10182.    char buffer[BUFFERSIZE + 1];
  10183.    char *current;
  10184.  
  10185.    sizechanged = 0;
  10186.    do {
  10187.       showinfo();
  10188.       change = (Token) (*io->getInfoToChange) ();
  10189.       if (change == t_EOF)
  10190.      break;
  10191.       if (!okChange())
  10192.      continue;
  10193.       if (change == t_Size) {
  10194.      sprintf(buffer, "%d", boardsize);
  10195.      current = dupStr(buffer);
  10196.      (*io->editInfo) (current, ¤t, t_Size);
  10197.      if (current) {
  10198.         value = atoi(current);
  10199.         if (value > 1 && value < 20) {
  10200.            if (value != boardsize)
  10201.           sizechanged = 1;
  10202.            boardsize = value;
  10203.         } free(current);
  10204.      }
  10205.       } else if (change == t_Handicap) {
  10206.      sprintf(buffer, "%d", handicap);
  10207.      current = dupStr(buffer);
  10208.      (*io->editInfo) (current, ¤t, t_Handicap);
  10209.      if (current) {
  10210.         handicap = atoi(current);
  10211.         free(current);
  10212.      }
  10213.       } else {
  10214.  
  10215.      (*io->editInfo) (info[(int) change - FIRSTINFO], &info[(int) change - FIRSTINFO],
  10216.               change);
  10217.      if (!strlen(info[(int) change - FIRSTINFO])) {
  10218.         free(info[(int) change - FIRSTINFO]);
  10219.         info[(int) change - FIRSTINFO] = 0;
  10220.      }
  10221.       }
  10222.  
  10223.  
  10224.    } while (1);
  10225.    return sizechanged;
  10226.  
  10227. }
  10228.  
  10229.  
  10230.  
  10231.  
  10232. static void savescreen(bord)
  10233. board *bord;
  10234. {
  10235.    char fname[75];
  10236.    int i, j;
  10237.    FILE *out;
  10238.    extern coordList *lastletters;
  10239.    extern int prisoners[];
  10240.    coordList *let;
  10241.    char local[19][19];
  10242.    if ((*io->queryStr) ("Save screen: ", fname, 74)) {
  10243.       if (out = fopen(fname, "a+t")) {
  10244.      fprintf(out, "%s to play.\n\n", curPlayer == t_Black ? "Black" : "White");
  10245.      fputs("  ", out);
  10246.      for (i = 0; i < boardsize; i++) {
  10247.         fputc(' ', out);
  10248.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  10249.      }
  10250.      fputc('\n', out);
  10251.  
  10252.  
  10253.      for (j = 0; j < boardsize; j++)
  10254.         for (i = 0; i < boardsize; i++) {
  10255.            local[i][j] = ' ';
  10256.            switch (bord->b[i][j]) {
  10257.  
  10258.           case P_WHITE:
  10259.              local[i][j] = 'O';
  10260.              break;
  10261.           case P_BLACK:
  10262.              local[i][j] = '#';
  10263.              break;
  10264.  
  10265.           case P_NOTHING:
  10266.           default:
  10267.              local[i][j] = '.';
  10268.              break;
  10269.            }
  10270.         }
  10271.      let = lastletters;
  10272.      i = 0;
  10273.      while (let) {
  10274.         local[let->x][let->y] = i + 'a';
  10275.         i++;
  10276.         i %= 26;
  10277.         let = let->next;
  10278.  
  10279.  
  10280.      }
  10281.  
  10282.      for (j = 0; j < boardsize; j++) {
  10283.         fprintf(out, "%2d ", boardsize - j);
  10284.         for (i = 0; i < boardsize; i++) {
  10285.            fputc(local[i][j], out);
  10286.            fputc(' ', out);
  10287.         }
  10288.  
  10289.         fprintf(out, "%2d", boardsize - j);
  10290.         if (
  10291.           (j == boardsize / 2) && (prisoners[0] || prisoners[1]))
  10292.            fprintf(out, "  Captured #: %d   Captured O: %d", prisoners[0], prisoners[1]);
  10293.         fputc('\n', out);
  10294.      }
  10295.      fputs("  ", out);
  10296.      for (i = 0; i < boardsize; i++) {
  10297.         fputc(' ', out);
  10298.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  10299.      }
  10300.  
  10301.      fputs("\n\n", out);
  10302.      for (i = 0; i < commentLines(); i++) {
  10303.         fputs(commentGet(i), out);
  10304.         putc('\n', out);
  10305.      }
  10306.  
  10307.      fclose(out);
  10308.       } else
  10309.      (*io->notifyError) ("Unable to open file.");
  10310.    }
  10311. }
  10312.  
  10313.  
  10314.  
  10315.  
  10316.  
  10317. FUNCTION void doit()
  10318. {
  10319.    int quitflg, i;
  10320.    nodep root, curNode;
  10321.    board theBoard;
  10322.    extern coordList *lastletters, *lastmarks;
  10323.  
  10324.    curPlayer = t_Black;
  10325.    xcur = ycur = quitflg = 0;
  10326.    root = 0;
  10327.    madechanges = 0;
  10328.    change = 1;
  10329.    if (input != stdin) {
  10330.       root = parse(0);
  10331.       fclose(input);
  10332.       change = 0;
  10333.    }
  10334.    if (!root)
  10335.       root = newNode();
  10336.    curNode = root;
  10337.    initBoard(&theBoard);
  10338.    (*io->setCursor) (xcur, ycur);
  10339.    (*io->refreshIO) ();
  10340.    if (mailFlag) {
  10341.       while (curNode->child)
  10342.      curNode = treeDown(curNode);
  10343.       change = 1;
  10344.    }
  10345.    step(curNode, &theBoard);
  10346.    while (!quitflg) {
  10347.       nodep tNode;
  10348.       command c;
  10349.       property *prop;
  10350.  
  10351.       if (prop = getprop(curNode, t_Player)) {
  10352.      extern Token lastTurn;
  10353.      curPlayer = prop->data.player;
  10354.      lastTurn = t_EOF;
  10355.      ispl = 1;
  10356.       } else
  10357.      ispl = 0;
  10358.  
  10359.       c = (command) (*io->idle) (curNode);
  10360.  
  10361.       if ((int) c >= (int) C_CHOSECHILD && (int) c < (int) C_NEXTCMD) {
  10362.      nodep new;
  10363.      new = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  10364.      if (new) {
  10365.         curNode = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  10366.         step(curNode, &theBoard);
  10367.      }
  10368.       } else
  10369.      switch (c) {
  10370.         case C_LOAD:
  10371.            if (okExit(root)) {
  10372.           char filename[50];
  10373.           if ((*io->queryStr) ("Load file? ", filename, 48)) {
  10374.              root = curNode = loadFile(filename, root, &theBoard);
  10375.              step(curNode, &theBoard);
  10376.           }
  10377.            }
  10378.            break;
  10379.         case C_BACKFILE:
  10380.  
  10381.            if (currentfile > 0 && okExit(root)) {
  10382.           currentfile--;
  10383.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  10384.           step(curNode, &theBoard);
  10385.            } else
  10386.           (*io->notifyError) ("No previous file.");
  10387.            break;
  10388.  
  10389.  
  10390.         case C_NEXTFILE:
  10391.            if (currentfile + 1 < filecount && okExit(root)) {
  10392.           currentfile++;
  10393.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  10394.           step(curNode, &theBoard);
  10395.            } else
  10396.           (*io->notifyError) ("No next file.");
  10397.            break;
  10398.  
  10399.         case C_INFO:
  10400.            if (doinfo())
  10401.           initBoard(&theBoard);
  10402.            step(curNode, &theBoard);
  10403.            if (xcur >= boardsize)
  10404.           xcur = boardsize - 1;
  10405.            if (ycur >= boardsize)
  10406.           ycur = boardsize - 1;
  10407.            break;
  10408.         case C_SAVESCREEN:
  10409.            savescreen(&theBoard);
  10410.            break;
  10411.         case C_REDRAW:
  10412.            {
  10413.           int savex, savey;
  10414.           savex = xcur;
  10415.           savey = ycur;
  10416.           initBoard(&theBoard);
  10417.           (*io->refreshIO) ();
  10418.           step(curNode, &theBoard);
  10419.           xcur = savex;
  10420.           ycur = savey;
  10421.           break;
  10422.            }
  10423.         case C_NOTHING:
  10424.            break;
  10425.         case C_TOPLAY:
  10426.            if (okChange())
  10427.           addPlayer(curNode, (curPlayer == t_Black) ? t_White : t_Black);
  10428.            break;
  10429.         case C_PASSMOVE:{
  10430.           int mod_cur_node;
  10431.           mod_cur_node = passMove(curNode, curPlayer);
  10432.           if (mod_cur_node)
  10433.              step(curNode, &theBoard);
  10434.           else {
  10435.              curNode = treeDown(curNode);
  10436.              stepDown(curNode, &theBoard);
  10437.           }
  10438.            }
  10439.            break;
  10440.  
  10441.  
  10442.         case C_TOGGLESTONE:{
  10443.           extern Token lastTurn;
  10444.           curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  10445.           lastTurn = t_EOF;
  10446.            }
  10447.  
  10448.            break;
  10449.         case C_TUTORSWAP:
  10450.            tutor = !tutor;
  10451.            break;
  10452.         case C_MOVE:
  10453.            if (tutor) {
  10454.           nodep save;
  10455.           save = curNode;
  10456.           if (curNode = makeTutor(curNode, curPlayer, xcur, ycur)) {
  10457.              step(curNode, &theBoard);
  10458.           } else {
  10459.              (*io->notifyError) ("Wrong move.");
  10460.              curNode = save;;
  10461.           }
  10462.            } else {
  10463.           if (okChange() && legal(&theBoard, curNode, curPlayer, xcur, ycur)) {
  10464.              int mod_cur_node;
  10465.              mod_cur_node = makeMove(curNode, curPlayer, xcur, ycur);
  10466.              curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  10467.              if (mod_cur_node)
  10468.             step(curNode, &theBoard);
  10469.              else {
  10470.             curNode = treeDown(curNode);
  10471.             stepDown(curNode, &theBoard);
  10472.              }
  10473.           }
  10474.            }
  10475.  
  10476.            break;
  10477.         case C_ADDVAR:
  10478.            if (okChange()) {
  10479.           makeVariation(curNode);
  10480.           step(curNode, &theBoard);
  10481.            }
  10482.            break;
  10483.         case C_DELNODE:
  10484.            if (okChange()) {
  10485.           deleteNode(&curNode);
  10486.           step(curNode, &theBoard);
  10487.            }
  10488.            break;
  10489.         case C_PASTE:
  10490.            if (okChange())
  10491.           if (pasteTree(curNode))
  10492.              step(curNode, &theBoard);
  10493.           else
  10494.              (*io->notifyError) ("Nothing to paste.");
  10495.            break;
  10496.  
  10497.         case C_TREECUT:
  10498.            if (okChange()) {
  10499.           nodep prevNode;
  10500.           int savex, savey;
  10501.           savex = xcur;
  10502.           savey = ycur;
  10503.           prevNode = curNode->parent;
  10504.           cutTree(curNode);
  10505.           curNode = prevNode;
  10506.           if (!curNode) {
  10507.              initNodes();
  10508.              root = curNode = newNode();
  10509.           }
  10510.           step(curNode, &theBoard);
  10511.           xcur = savex;
  10512.           ycur = savey;
  10513.           break;
  10514.            }
  10515.         case C_ADDBLACK:
  10516.            if (okChange()) {
  10517.           coordList *cl;
  10518.           property *prop;
  10519.           if (boardGet(&theBoard, xcur, ycur) == P_BLACK) {
  10520.              addStone(curNode, t_AddEmpty, xcur, ycur);
  10521.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  10522.           } else {
  10523.              addStone(curNode, t_AddBlack, xcur, ycur);
  10524.              setPiece(&theBoard, xcur, ycur, P_BLACK);
  10525.           }
  10526.           if (prop = getprop(curNode, t_Letter))
  10527.              lastletters = prop->data.stones;
  10528.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  10529.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  10530.            }
  10531.            break;
  10532.         case C_ADDWHITE:
  10533.            if (okChange()) {
  10534.           coordList *cl;
  10535.           property *prop;
  10536.           if (boardGet(&theBoard, xcur, ycur) == P_WHITE) {
  10537.              addStone(curNode, t_AddEmpty, xcur, ycur);
  10538.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  10539.           } else {
  10540.              addStone(curNode, t_AddWhite, xcur, ycur);
  10541.              setPiece(&theBoard, xcur, ycur, P_WHITE);
  10542.           }
  10543.           if (prop = getprop(curNode, t_Letter))
  10544.              lastletters = prop->data.stones;
  10545.  
  10546.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  10547.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  10548.  
  10549.            }
  10550.            break;
  10551.         case C_ADDLETTER:
  10552.            if (okChange()) {
  10553.  
  10554.  
  10555.  
  10556.           int sx, sy;
  10557.  
  10558.           for (; lastletters; lastletters = lastletters->next)
  10559.              (*io->plotPiece) (&theBoard, lastletters->x, lastletters->y);
  10560.           lastletters = 0;
  10561.  
  10562.           sx = xcur;
  10563.           sy = ycur;
  10564.  
  10565.  
  10566.           if (addMark(curNode, t_Letter, xcur, ycur))
  10567.              (*io->plotPiece) (&theBoard, xcur, ycur);
  10568.           stepDown(curNode, &theBoard);
  10569.           xcur = sx;
  10570.           ycur = sy;
  10571.            }
  10572.            break;
  10573.         case C_ADDMARK:
  10574.            if (okChange()) {
  10575.           int sx, sy;
  10576.  
  10577.           for (; lastmarks; lastmarks = lastmarks->next)
  10578.              (*io->plotPiece) (&theBoard, lastmarks->x, lastmarks->y);
  10579.           lastmarks = 0;
  10580.  
  10581.           sx = xcur;
  10582.           sy = ycur;
  10583.           if (addMark(curNode, t_Mark, xcur, ycur))
  10584.              (*io->plotPiece) (&theBoard, xcur, ycur);
  10585.  
  10586.           stepDown(curNode, &theBoard);
  10587.           xcur = sx;
  10588.           ycur = sy;
  10589.            }
  10590.            break;
  10591.         case C_EDCOMMENT:
  10592.            if (okChange()) {
  10593.           edComment(curNode);
  10594.           step(curNode, &theBoard);
  10595.            }
  10596.            break;
  10597.         case C_ADDNAME:
  10598.            if (okChange()) {
  10599.           makeName(curNode);
  10600.           step(curNode, &theBoard);
  10601.            }
  10602.            break;
  10603.         case C_DOWN:
  10604.            tNode = treeDown(curNode);
  10605.            if (tNode != curNode) {
  10606.           curNode = tNode;
  10607.           stepDown(curNode, &theBoard);
  10608.            }
  10609.            break;
  10610.         case C_UP:
  10611.            curNode = treeUp(curNode);
  10612.            step(curNode, &theBoard);
  10613.            break;
  10614.         case C_WALKDOWN:
  10615.            tNode = treeNext(curNode);
  10616.            if (tNode->parent == curNode) {
  10617.           stepDown(tNode, &theBoard);
  10618.            } else {
  10619.           step(tNode, &theBoard);
  10620.            }
  10621.            curNode = tNode;
  10622.            break;
  10623.         case C_WALKUP:
  10624.            curNode = treeLast(curNode);
  10625.            step(curNode, &theBoard);
  10626.            break;
  10627.         case C_SEARCHCOMMENT:
  10628.            {
  10629.           nodep tBegin;
  10630.           tBegin = curNode;
  10631.           tNode = curNode;
  10632.           do {
  10633.              tNode = treeNext(tNode);
  10634.           }
  10635.           while (tNode != tBegin && !getprop(tNode, t_Comment));
  10636.           if (tNode != curNode) {
  10637.              if (tNode->parent == curNode) {
  10638.             stepDown(tNode, &theBoard);
  10639.              } else {
  10640.             step(tNode, &theBoard);
  10641.              }
  10642.              curNode = tNode;
  10643.           }
  10644.            }
  10645.            break;
  10646.         case C_SEARCHBACKCOMMENT:
  10647.            tNode = curNode;
  10648.            curNode = curNode;
  10649.            do {
  10650.           curNode = treeLast(curNode);
  10651.            }
  10652.            while (curNode != tNode && !getprop(curNode, t_Comment));
  10653.            step(curNode, &theBoard);
  10654.            break;
  10655.         case C_UPFORK:
  10656.            while (curNode->parent) {
  10657.           curNode = curNode->parent;
  10658.           if (treeCountSiblings(curNode) > 1)
  10659.              break;
  10660.            }
  10661.            step(curNode, &theBoard);
  10662.            break;
  10663.         case C_DOWNFORK:
  10664.            {
  10665.           while (curNode->child) {
  10666.              curNode = treeDown(curNode);
  10667.              if (treeCountSiblings(curNode) > 1)
  10668.             break;
  10669.           }
  10670.           step(curNode, &theBoard);
  10671.            }
  10672.            break;
  10673.         case C_END:
  10674.            while (curNode->child) {
  10675.           curNode = treeDown(curNode);
  10676.            }
  10677.            step(curNode, &theBoard);
  10678.            break;
  10679.         case C_BEGINNING:
  10680.            curNode = root;
  10681.            step(curNode, &theBoard);
  10682.            break;
  10683.         case C_SCORE:
  10684.            doScore(&theBoard, curNode);
  10685.            break;
  10686.         case C_GOTO:
  10687.            {
  10688.           char buf[7];
  10689.           nodep new;
  10690.           if ((*io->queryStr) ("Move to node # ?", buf, 5)) {
  10691.              searchNodeNum = atoi(buf);
  10692.              if (searchNodeNum == 0 && strcmp(buf, "0"))
  10693.             searchNodeNum = -1;
  10694.              if (searchNodeNum >= 0) {
  10695.             if (new = search(root)) {
  10696.                curNode = new;
  10697.                step(curNode, &theBoard);
  10698.                (*io->notifyClear) ();
  10699.             } else {
  10700.                (*io->notifyClear) ();
  10701.                (*io->notifyError) ("Node not found.");
  10702.             }
  10703.  
  10704.              }
  10705.           }
  10706.            }
  10707.            break;
  10708.         case C_QUIT:
  10709.            if (okExit(root))
  10710.           quitflg++;
  10711.            break;
  10712.         case C_WRITE:
  10713.            {
  10714.           char filename[50];
  10715.           if ((*io->queryStr) ("Save name? ", filename, 48)) {
  10716.              if (!strcmp("*", filename)) {
  10717.             if (!writeTree(name_buf, root))
  10718.                madechanges = 0;
  10719.              } else {
  10720.             if (!writeTree(filename, root))
  10721.                madechanges = 0;
  10722.              }
  10723.           }
  10724.            }
  10725.            break;
  10726.         case C_SAVESHORT:
  10727.            saveShort = !saveShort;
  10728.            break;
  10729.         case C_CURLEFT:
  10730.            xcur = (xcur - 1 + boardsize) % boardsize;
  10731.            (*io->setCursor) (xcur, ycur);
  10732.            (*io->refreshIO) ();
  10733.            break;
  10734.         case C_CURRIGHT:
  10735.            xcur = (xcur + 1) % boardsize;
  10736.            (*io->setCursor) (xcur, ycur);
  10737.            (*io->refreshIO) ();
  10738.            break;
  10739.         case C_CURUP:
  10740.            ycur = (ycur - 1 + boardsize) % boardsize;
  10741.            (*io->setCursor) (xcur, ycur);
  10742.            (*io->refreshIO) ();
  10743.            break;
  10744.         case C_CURDOWN:
  10745.            ycur = (ycur + 1) % boardsize;
  10746.            (*io->setCursor) (xcur, ycur);
  10747.            (*io->refreshIO) ();
  10748.            break;
  10749.         case C_UPLEFT:
  10750.            ycur = (ycur - 1 + boardsize) % boardsize;
  10751.            xcur = (xcur - 1 + boardsize) % boardsize;
  10752.            (*io->setCursor) (xcur, ycur);
  10753.            (*io->refreshIO) ();
  10754.            break;
  10755.         case C_UPRIGHT:
  10756.            xcur = (xcur + 1) % boardsize;
  10757.            ycur = (ycur - 1 + boardsize) % boardsize;
  10758.            (*io->setCursor) (xcur, ycur);
  10759.            (*io->refreshIO) ();
  10760.            break;
  10761.         case C_DOWNLEFT:
  10762.            xcur = (xcur - 1 + boardsize) % boardsize;
  10763.            ycur = (ycur + 1) % boardsize;
  10764.            (*io->setCursor) (xcur, ycur);
  10765.            (*io->refreshIO) ();
  10766.            break;
  10767.         case C_DOWNRIGHT:
  10768.            xcur = (xcur + 1) % boardsize;
  10769.            ycur = (ycur + 1) % boardsize;
  10770.            (*io->setCursor) (xcur, ycur);
  10771.            (*io->refreshIO) ();
  10772.            break;
  10773.      }
  10774.    }
  10775. }
  10776. SHAR_EOF
  10777. fi
  10778. if test -f 'edit.c'
  10779. then
  10780.     echo shar: "will not over-write existing file 'edit.c'"
  10781. else
  10782. cat << \SHAR_EOF > 'edit.c'
  10783. /* "mgt" Copyright (c) 1991 Shodan  */
  10784.  
  10785. #include "mgt.h"
  10786.  
  10787. int first;
  10788. nodep buffer = 0;
  10789.  
  10790.  
  10791. FUNCTION void writeStrEscaped(output, s)
  10792. FILE *output;
  10793. char *s;
  10794. {
  10795.    while (*s) {
  10796.       if (*s == ')' || *s == '(' || *s == ']' || *s == '[')
  10797.      fputc('\\', output);
  10798.       fputc(*(s++), output);
  10799.    }
  10800. }
  10801.  
  10802.  
  10803. #define WRITE(short,long) if (saveShort) fputs(short,output);else fputs(long,output)
  10804.  
  10805.  
  10806. static char *infoshort[] =
  10807. {"PB", "BR", "PW", "WR",
  10808.  "GN", "EV", "RO", "DT", "PC", "TM", "RE", "GC",
  10809.  "SO", "US", "KM"};
  10810.  
  10811. static char *infolong[] =
  10812. {
  10813.    "PlayerBlack", "BlackRank", "PlayerWhite", "WhiteRank", "GameName", "EVent", "ROund",
  10814.    "DaTe", "PlaCe", "TiMe", "REsult", "GameComment", "SOurce", "USer", "KoMi"};
  10815.  
  10816.  
  10817.  
  10818. static void writeFirst(output)
  10819. FILE *output;
  10820. {
  10821.    int p;
  10822.    if (saveShort) {
  10823.       fprintf(output, "GM[1]VW[]SZ[%d]", boardsize);
  10824.       if (handicap)
  10825.      fprintf(output, "HA[%d]", handicap);
  10826.    } else {
  10827.       fprintf(output, "GaMe[1]\nVieW[]\nSiZe[%d]\n", boardsize);
  10828.       if (handicap)
  10829.      fprintf(output, "HAndicap[%d]\n", handicap);
  10830.    }
  10831.  
  10832.    for (p = 0; p <= t_Komi - FIRSTINFO; p++) {
  10833.       if (info[p]) {
  10834.      WRITE(infoshort[p], infolong[p]);
  10835.      fputc('[', output);
  10836.      writeStrEscaped(output, info[p]);
  10837.      WRITE("]", "]\n");
  10838.       }
  10839.    }
  10840. }
  10841.  
  10842.  
  10843.  
  10844. FUNCTION void writeNode(output, n)
  10845. FILE *output;
  10846. nodep n;
  10847. {
  10848.    property *prop;
  10849.    char str[1445];
  10850.  
  10851.    WRITE(";", ";\n");
  10852.    if (first) {
  10853.       writeFirst(output);
  10854.       first = 0;
  10855.    }
  10856.    prop = n->p;
  10857.    while (prop) {
  10858.       switch (prop->t) {
  10859.      case t_AddBlack:
  10860.         if (writeCoordList(prop->data.stones, str)) {
  10861.            WRITE("AB", "AddBlack");
  10862.            fputs(str, output);
  10863.         }
  10864.         break;
  10865.      case t_AddWhite:
  10866.         if (writeCoordList(prop->data.stones, str)) {
  10867.            WRITE("AW", "AddWhite");
  10868.            fputs(str, output);
  10869.         }
  10870.         break;
  10871.      case t_White:
  10872.         if (writeCoordList(prop->data.stones, str)) {
  10873.            WRITE("W", "White");
  10874.            fputs(str, output);
  10875.         }
  10876.         break;
  10877.      case t_Black:
  10878.         if (writeCoordList(prop->data.stones, str)) {
  10879.            WRITE("B", "Black");
  10880.            fputs(str, output);
  10881.         }
  10882.         break;
  10883.      case t_AddEmpty:
  10884.         if (writeCoordList(prop->data.stones, str)) {
  10885.            WRITE("AE", "AddEmpty");
  10886.            fputs(str, output);
  10887.         }
  10888.         break;
  10889.      case t_Mark:
  10890.         if (writeCoordList(prop->data.stones, str)) {
  10891.            WRITE("M", "Mark");
  10892.            fputs(str, output);
  10893.         }
  10894.         break;
  10895.      case t_Letter:
  10896.         if (writeCoordList(prop->data.stones, str)) {
  10897.            WRITE("L", "Letter");
  10898.            fputs(str, output);
  10899.         }
  10900.         break;
  10901.      case t_Name:
  10902.         if (strlen(prop->data.comment)) {
  10903.            WRITE("N[", "Name[");
  10904.            writeStrEscaped(output, prop->data.comment);
  10905.            WRITE("]", "]\n");
  10906.         }
  10907.         break;
  10908.      case t_Pass:
  10909.         if (prop->data.player == t_Black)
  10910.            WRITE("B", "Black");
  10911.         else
  10912.            WRITE("W", "White");
  10913.         WRITE("[tt]", "[tt]\n");
  10914.         break;
  10915.  
  10916.      case t_Player:
  10917.         WRITE("PL[", "PLayer[");
  10918.         if (prop->data.player == t_Black)
  10919.            fputc('B', output);
  10920.         else
  10921.            fputc('W', output);
  10922.         WRITE("]", "]\n");
  10923.         break;
  10924.      case t_Comment:
  10925.         if (strlen(prop->data.comment)) {
  10926.            WRITE("C[", "Comment[");
  10927.            writeStrEscaped(output, prop->data.comment);
  10928.            WRITE("]", "]\n");
  10929.         }
  10930.         break;
  10931.       }
  10932.       prop = prop->next;
  10933.    }
  10934. }
  10935.  
  10936.  
  10937.  
  10938. FUNCTION void WriteSubTree(output, root, sib)
  10939. FILE *output;
  10940. nodep root;
  10941. int sib;
  10942. {
  10943.    WRITE("(", "(\n");
  10944.    do {
  10945.       if (sib && root->nextSibling) {
  10946.      WriteSubTree(output, root, 0);
  10947.      while (root->nextSibling) {
  10948.         root = root->nextSibling;
  10949.         WriteSubTree(output, root, 0);
  10950.      }
  10951.      root = NULL;
  10952.       } else {
  10953.      writeNode(output, root);
  10954.      root = root->child;
  10955.      sib = 1;
  10956.       }
  10957.    }
  10958.    while (root);
  10959.    WRITE(")", ")\n");
  10960. }
  10961.  
  10962.  
  10963.  
  10964. FUNCTION int writeCoordList(list, str)
  10965. coordList *list;
  10966. char *str;
  10967. {
  10968.    *str = 0;
  10969.    while (list) {
  10970.       sprintf(str + strlen(str), "[%c%c]", list->x + 'a', list->y + 'a');
  10971.       list = list->next;
  10972.    }
  10973.    if (!(strlen(str)))
  10974.       return 0;
  10975.    if (!saveShort)
  10976.       strcat(str, "\n");
  10977.    return 1;
  10978. }
  10979.  
  10980.  
  10981.  
  10982. FUNCTION int writeTree(name, root)
  10983. char *name;
  10984. nodep root;
  10985. {
  10986.    FILE *output;
  10987.  
  10988.    if (output = fopen(name, "w")) {
  10989.       first = 1;
  10990.       WriteSubTree(output, root, 1);
  10991.       fclose(output);
  10992.       return 0;
  10993.    } else {
  10994.       (*io->notifyError) ("Error saving file.");
  10995.       return 1;
  10996.    }
  10997. }
  10998.  
  10999.  
  11000.  
  11001. static void clearSpace(prop, x, y)
  11002. property *prop;
  11003. int x, y;
  11004. {
  11005.    while (prop) {
  11006.       switch (prop->t) {
  11007.      case t_AddEmpty:
  11008.      case t_AddBlack:
  11009.      case t_AddWhite:
  11010.      case t_Black:
  11011.      case t_White:
  11012.      case t_Mark:
  11013.      case t_Letter:
  11014.         clearCoord(x, y, &(prop->data.stones));
  11015.         break;
  11016.       }
  11017.       prop = prop->next;
  11018.    }
  11019. }
  11020.  
  11021.  
  11022. FUNCTION int addMark(n, t, x, y)
  11023. nodep n;
  11024. Token t;
  11025. int x, y;
  11026. {
  11027.    property *prop;
  11028.  
  11029.    if (prop = getprop(n, t)) {
  11030.       if ((getCoord(x, y, prop->data.stones))) {
  11031.      clearCoord(x, y, &(prop->data.stones));
  11032.      return 1;
  11033.       }
  11034.    } else {
  11035.       prop = (property *) malloc(sizeof(property));
  11036.       if (!prop)
  11037.      barf("Memory allocation failure (markStone)");
  11038.       prop->next = n->p;
  11039.       n->p = prop;
  11040.       prop->data.stones = 0;
  11041.       prop->t = t;
  11042.  
  11043.    }
  11044.    setCoord(x, y, &(prop->data.stones));
  11045.    return 0;
  11046. }
  11047.  
  11048.  
  11049.  
  11050.  
  11051. FUNCTION void addStone(n, t, x, y)
  11052. nodep n;
  11053. Token t;
  11054. int x, y;
  11055. {
  11056.    property *prop;
  11057.  
  11058.    clearSpace(n->p, x, y);
  11059.    if (!(prop = getprop(n, t))) {
  11060.       prop = (property *) calloc(1, sizeof(property));
  11061.       if (!prop)
  11062.      barf("Memory allocation failure (addStone)");
  11063.       prop->next = n->p;
  11064.       n->p = prop;
  11065.       prop->data.stones = 0;
  11066.       prop->t = t;
  11067.    }
  11068.    setCoord(x, y, &(prop->data.stones));
  11069.  
  11070. }
  11071.  
  11072. FUNCTION int makeMove(n, t, x, y)
  11073. nodep n;
  11074. Token t;
  11075. int x, y;
  11076. {
  11077.    nodep new;
  11078.    property *prop;
  11079.    int ret;
  11080.    ret = 0;
  11081.  
  11082.    if (!(n->p)) {
  11083.       new = n;
  11084.       ret = 1;
  11085.    } else {
  11086.  
  11087.       new = newNode();
  11088.       if (n->child)
  11089.      n->child->parent = new;
  11090.       new->parent = n;
  11091.       new->child = n->child;
  11092.       n->child = new;
  11093.    }
  11094.  
  11095.  
  11096.    prop = (property *) calloc(1, sizeof(property));
  11097.    if (!prop)
  11098.       barf("Memory allocation failure (makeMove)");
  11099.    new->p = prop;
  11100.    prop->data.stones = 0;
  11101.    prop->t = t;
  11102.  
  11103.    setCoord(x, y, &(prop->data.stones));
  11104.    return ret;
  11105.  
  11106. }
  11107.  
  11108. FUNCTION int passMove(n, t)
  11109. nodep n;
  11110. Token t;
  11111. {
  11112.    nodep new;
  11113.    property *prop;
  11114.    int ret;
  11115.    ret = 0;
  11116.  
  11117.    if (!(n->p)) {
  11118.       new = n;
  11119.       ret = 1;
  11120.    } else {
  11121.  
  11122.       new = newNode();
  11123.       if (n->child)
  11124.      n->child->parent = new;
  11125.       new->parent = n;
  11126.       new->child = n->child;
  11127.       n->child = new;
  11128.    }
  11129.  
  11130.  
  11131.    prop = (property *) calloc(1, sizeof(property));
  11132.    if (!prop)
  11133.       barf("Memory allocation failure (passMove)");
  11134.    new->p = prop;
  11135.    prop->data.player = t;
  11136.    prop->t = t_Pass;
  11137.  
  11138.    return ret;
  11139.  
  11140. }
  11141.  
  11142.  
  11143. FUNCTION void addPlayer(n, t)
  11144. nodep n;
  11145. Token t;
  11146. {
  11147.    property *prop;
  11148.    if (!(prop = getprop(n, t_Player))) {
  11149.       prop = (property *) calloc(1, sizeof(property));
  11150.       if (!prop)
  11151.      barf("Memory allocation failure (addPlayer)");
  11152.       addprop(n, prop);
  11153.    }
  11154.    prop->data.player = t;
  11155.    prop->t = t_Player;
  11156. }
  11157.  
  11158.  
  11159. FUNCTION void makeVariation(n)
  11160. nodep n;
  11161. {
  11162.    nodep new, last;
  11163.  
  11164.    if (!(n->child)) {
  11165.       new = newNode();
  11166.       new->parent = n;
  11167.       n->child = new;
  11168.    } else {
  11169.       new = newNode();
  11170.       new->parent = n;
  11171.       last = treeLastSibling(n->child);
  11172.       last->nextSibling = new;
  11173.       new->lastSibling = last;
  11174.    }
  11175. }
  11176.  
  11177.  
  11178. FUNCTION void cutTree(n)
  11179. nodep n;
  11180. {
  11181.    freeNode(buffer);
  11182.    if (n->nextSibling)
  11183.       n->nextSibling->lastSibling = n->lastSibling;
  11184.    if (n->lastSibling)
  11185.       n->lastSibling->nextSibling = n->nextSibling;
  11186.    else if (n->parent)
  11187.       n->parent->child = n->nextSibling;
  11188.    n->nextSibling = 0;
  11189.    n->lastSibling = 0;
  11190.    buffer = n;
  11191. }
  11192.  
  11193.  
  11194. FUNCTION boolean pasteTree(n)
  11195. nodep n;
  11196. {
  11197.    nodep last, sib;
  11198.    if (buffer) {
  11199.       for (last = buffer; last->child; last = last->child);
  11200.       if (n->child) {
  11201.      n->child->parent = last;
  11202.      for (sib = n->child->nextSibling; sib; sib = sib->nextSibling)
  11203.         sib->parent = last;
  11204.      last->child = n->child;
  11205.       }
  11206.       n->child = buffer;
  11207.       buffer->parent = n;
  11208.       buffer = (nodep) 0;
  11209.       return true;
  11210.    }
  11211.    return false;
  11212. }
  11213.  
  11214.  
  11215. FUNCTION void edComment(n)
  11216. nodep n;
  11217. {
  11218.    property *prop;
  11219.  
  11220.    if (!(prop = getprop(n, t_Comment))) {
  11221.       prop = (property *) calloc(1, sizeof(property));
  11222.       prop->t = t_Comment;
  11223.       prop->next = n->p;
  11224.       n->p = prop;
  11225.    }
  11226.    (*io->editComment) (prop->data.comment, &(prop->data.comment));
  11227.    if (!(prop->data.comment)) {
  11228.       n->p = prop->next;
  11229.       free(prop);
  11230.    }
  11231. }
  11232.  
  11233.  
  11234.  
  11235. FUNCTION void deleteNode(n)
  11236. nodep *n;
  11237. {
  11238.    nodep last;
  11239.    if (!((*n)->child)) {
  11240.       freeProps(*n);
  11241.       (*n)->p = 0;
  11242.    } else {
  11243.       if ((*n)->parent && (*n)->parent->child == *n)
  11244.      (*n)->parent->child = (*n)->child;
  11245.       if ((*n)->lastSibling) {
  11246.      (*n)->child->lastSibling = (*n)->lastSibling;
  11247.      (*n)->lastSibling->nextSibling = (*n)->child;
  11248.       }
  11249.       /* new parent for all of child's sibs */
  11250.  
  11251.       for (last = (*n)->child; last->nextSibling; last = last->nextSibling)
  11252.      last->parent = (*n)->parent;
  11253.       last->parent = (*n)->parent;
  11254.  
  11255.       /* Last of child's sibs get's to point to next sib of main node */
  11256.       last->nextSibling = (*n)->nextSibling;
  11257.  
  11258.       if ((*n)->nextSibling)
  11259.      (*n)->nextSibling = last;
  11260.       last = *n;
  11261.       *n = (*n)->child;
  11262.       delNode(last);
  11263.    }
  11264. }
  11265.  
  11266.  
  11267. FUNCTION void makeName(n)
  11268. nodep n;
  11269. {
  11270.    char newname[41];
  11271.    property *prop;
  11272.  
  11273.    (*io->queryStr) ("Name: ", newname, 40);
  11274.  
  11275.    if (prop = getprop(n, t_Name))
  11276.       free(prop->data.comment);
  11277.    else {
  11278.       prop = (property *) calloc(1, sizeof(property));
  11279.       addprop(n, prop);
  11280.       prop->t = t_Name;
  11281.    }
  11282.    prop->data.comment = dupStr(newname);
  11283. }
  11284.  
  11285.  
  11286. FUNCTION void replaceComment(n, str)
  11287. nodep n;
  11288. char *str;
  11289. {
  11290.    property *prop;
  11291.  
  11292.    if (!(prop = getprop(n, t_Comment))) {
  11293.       prop = (property *) calloc(1, sizeof(property));
  11294.       prop->t = t_Comment;
  11295.       prop->next = n->p;
  11296.       n->p = prop;
  11297.    } else
  11298.       free(prop->data.comment);
  11299.    prop->data.comment = dupStr(str);
  11300. }
  11301. SHAR_EOF
  11302. fi
  11303. if test -f 'format'
  11304. then
  11305.     echo shar: "will not over-write existing file 'format'"
  11306. else
  11307. cat << \SHAR_EOF > 'format'
  11308. #!/bin/csh -f
  11309. foreach f ( $* )
  11310. indent -ndj -i3 -ip0 -npcs -cli3 -di3 -npsl -ncdb -l80 $f
  11311. end
  11312.  
  11313. SHAR_EOF
  11314. chmod +x 'format'
  11315. fi
  11316. if test -f 'goserver.c'
  11317. then
  11318.     echo shar: "will not over-write existing file 'goserver.c'"
  11319. else
  11320. cat << \SHAR_EOF > 'goserver.c'
  11321. /*  goserver.c
  11322.  *
  11323.  */
  11324.  
  11325. #include <stdio.h>
  11326. #include <errno.h>
  11327. #include <strings.h>
  11328. #include "mgt.h"
  11329. #include "advunix.h"
  11330.  
  11331. #define BUFFSIZE    2048
  11332. #define LINESIZE    1024
  11333.  
  11334. typedef    struct ComNode {
  11335.     command        code;
  11336.     int        xcur;
  11337.     int        ycur;
  11338.     struct    ComNode    *next;
  11339. } comnode;
  11340.  
  11341. static comnode *head = NULL;
  11342. static int count = 0;
  11343.  
  11344. static int hand[9][9][2] = {
  11345.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11346.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11347.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11348.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11349.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11350.     { {15,15}, {3,3}, {3,15}, {15,3}, {3,9}, {15,9}, {9,15}, {9,3}, {0,0} },
  11351.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} },
  11352.     { {15,15}, {3,3}, {3,15}, {15,3}, {3,9}, {15,9}, {9,15}, {9,3}, {0,0} },
  11353.     { {15,15}, {3,3}, {3,15}, {15,3}, {9,9}, {3,9}, {15,9}, {9,15}, {9,3} }
  11354. };
  11355.  
  11356. static void appendnode (np)
  11357. comnode *np;
  11358. {
  11359.     register comnode *temp;
  11360.  
  11361.     if (head) {
  11362.     temp = head;
  11363.     while (temp->next)
  11364.         temp = temp->next;
  11365.         temp->next = np;
  11366.     } else {
  11367.     head = np;
  11368.     }
  11369. }
  11370.  
  11371. static comnode *createnode(code)
  11372. command code;
  11373. {
  11374.     register comnode *temp;
  11375.  
  11376.     temp = (comnode *) malloc(sizeof(comnode));
  11377.     temp->code = code;
  11378.     temp->next = NULL;
  11379.     return temp;
  11380. }
  11381.  
  11382. static void undo()
  11383. {
  11384.     appendnode(createnode(C_TREECUT));
  11385.     count--;
  11386. }
  11387.  
  11388. static void sethandicap(num)
  11389. int num;
  11390. {
  11391.     register comnode *temp;
  11392.     register int i;
  11393.  
  11394.     if (num < 1 || num > 9)
  11395.     fatal("Handicap overflow");
  11396.     count++;
  11397.     appendnode(createnode(C_PASSMOVE));
  11398.     for (i = 0; i < num; i++){
  11399.     temp = createnode(C_ADDBLACK);
  11400.     temp->xcur = hand[num-1][i][0];
  11401.     temp->ycur = boardsize - 1 - hand[num-1][i][1];
  11402.         appendnode(temp);
  11403.     }
  11404. }
  11405.  
  11406. static void update_handicap(num)
  11407. int num;
  11408. {
  11409.     handicap = num;
  11410. }
  11411.  
  11412. static void makemove(xpos, ypos, move, color)
  11413. int xpos, ypos, move, color;
  11414. {
  11415.     register comnode *temp;
  11416.  
  11417.     if (count != move)
  11418.     return;
  11419.     if (xpos == -1 || ypos == -1) {
  11420.     count++;
  11421.     appendnode(createnode(C_PASSMOVE));
  11422.     } else {
  11423.     count++;
  11424.     temp = createnode(C_MOVE);
  11425.     temp->xcur = xpos - 1;
  11426.     temp->ycur = boardsize - ypos;
  11427.         appendnode(temp);
  11428.     }
  11429. }
  11430.  
  11431. static void score_it(xpos, ypos)
  11432. int xpos, ypos;
  11433. {
  11434.     register comnode *temp;
  11435.  
  11436.     temp = createnode(C_MOVE);
  11437.     temp->xcur = xpos - 1;
  11438.     temp->ycur = boardsize - ypos;
  11439.     appendnode(temp);
  11440. }
  11441.  
  11442. static void RefreshBoard()
  11443. {
  11444.     appendnode(createnode(C_PASSMOVE));
  11445.     appendnode(createnode(C_BEGINNING));
  11446.     appendnode(createnode(C_TREECUT));
  11447.     appendnode(createnode(C_TOGGLESTONE));
  11448.     handicap = 0;
  11449.     count = 0;
  11450. }
  11451.  
  11452. static void StartScoring()
  11453. {
  11454.     appendnode(createnode(C_SCORE));
  11455. }
  11456.  
  11457. static void StopScoring()
  11458. {
  11459.     appendnode(createnode(C_SCORE));
  11460.     appendnode(createnode(C_QUIT));
  11461. }
  11462.  
  11463. static void update_status( gameno, player2, player1, p2_captured, p1_captured,
  11464.                 p2_sec, p1_sec, p2_byoyomi, p1_byoyomi )
  11465. int gameno, p2_captured, p1_captured, p2_sec, p1_sec, p2_byoyomi, p1_byoyomi;
  11466. char *player2, *player1;
  11467. {
  11468.     static int beenhere = FALSE;
  11469.     
  11470.     if (!beenhere || 
  11471.     strcmp(info[t_PlayerBlack - FIRSTINFO], player2) || 
  11472.         strcmp(info[t_PlayerWhite - FIRSTINFO], player1)) {
  11473.  
  11474.     beenhere = TRUE;
  11475.     free(info[t_PlayerBlack - FIRSTINFO]);
  11476.     free(info[t_PlayerWhite - FIRSTINFO]);
  11477.     info[t_PlayerBlack - FIRSTINFO] = (char *) malloc(strlen(player2) + 1);
  11478.     info[t_PlayerWhite - FIRSTINFO] = (char *) malloc(strlen(player1) + 1);
  11479.     strcpy(info[t_PlayerBlack - FIRSTINFO], player2);
  11480.     strcpy(info[t_PlayerWhite - FIRSTINFO], player1);
  11481.     RefreshBoard();
  11482.     }
  11483. }
  11484.  
  11485. command goserver(curnode)
  11486. nodep curnode;
  11487. {
  11488.     int code, nread;
  11489.     char str[BUFFSIZE];
  11490.     comnode *temp;
  11491.  
  11492.     if (!tutor && head) {
  11493.         switch (code = head->code) {
  11494.         case C_MOVE:
  11495.         case C_ADDBLACK:
  11496.         case C_ADDWHITE:
  11497.         xcur = head->xcur;
  11498.         ycur = head->ycur;
  11499.         default:
  11500.         temp = head;
  11501.         head = head->next;
  11502.         free(temp);
  11503.         return code;
  11504.         }
  11505.     }
  11506.     setblock(0, FALSE);
  11507.     switch(nread = read(0, str, LINESIZE)) {
  11508.     case -1:
  11509.         if (errno != EWOULDBLOCK)
  11510.             syserr("read");
  11511.     case 0:
  11512.         return C_NOTHING;
  11513.     default:
  11514.         str[nread] = '\0';
  11515.         preprocess(str);
  11516.         process_input(str);
  11517.         return C_NOTHING;
  11518.     }
  11519. }
  11520.  
  11521. preprocess(str)
  11522. char *str;
  11523. {
  11524.     static char last = '\0';
  11525.     register int i;
  11526.  
  11527.     if (last == '\r') {
  11528.     for (i = strlen(str); i >= 0; i--)
  11529.         str[i+1] = str[i];
  11530.     str[0] = '\r';
  11531.     last = '\0';
  11532.     }
  11533.     for (i = 0; str[i] != '\0'; i++){
  11534.     if (str[i] == '\r') {
  11535.         if (str[i+1] == '\0') {
  11536.         last = '\r';
  11537.         str[i] = '\0';
  11538.         } else if (str[i+1] != '\n') {
  11539.         str[i] = '\n';
  11540.         } else {
  11541.         str[i] = ' ';
  11542.         }
  11543.     }
  11544.     }
  11545. }
  11546.  
  11547. /* filter.c
  11548.  * S.Coffin    USWAT 4/92
  11549.  *
  11550.  * process I/O stream between user and igs
  11551.  */
  11552.  
  11553. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  11554.  *
  11555.  *  This program is distributed in the hope that it will be useful.
  11556.  *  Use and copying of this software and preparation of derivative works
  11557.  *  based upon this software are permitted, so long as the following
  11558.  *  conditions are met:
  11559.  *       o credit to the authors is acknowledged following current
  11560.  *         academic behavior
  11561.  *       o no fees or compensation are charged for use, copies, or
  11562.  *         access to this software
  11563.  *       o this copyright notice is included intact.
  11564.  *  This software is made available AS IS, and no warranty is made about 
  11565.  *  the software or its performance. 
  11566.  * 
  11567.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  11568.  *  Send them to    scoffin@uswest.com
  11569.  */
  11570.  
  11571. /*
  11572.  *    Rewritten by Chien-Min Wang for xmgt
  11573.  */
  11574.  
  11575. #include "shared.h"
  11576.  
  11577. #define EMPTY    0
  11578. #define BLACK    1
  11579. #define WHITE    2
  11580.  
  11581. static int observeflag = FALSE;
  11582. static char infileflag = FALSE;
  11583. static int dbg = 0;
  11584. static int move = -1;
  11585. static int gameno = -1;
  11586. char player1[40], player2[40];
  11587. int p1_sec, p2_sec;
  11588. int p1_captured, p2_captured;
  11589. int p1_byoyomi, p2_byoyomi;
  11590.  
  11591. /* Find the first occurrence of s2 in s1  */
  11592. char *SCstrstr( s1, s2 )
  11593.     char *s1, *s2;
  11594. {
  11595.     char c, sc;
  11596.     int len;
  11597.  
  11598.     if( (c = *s2++) != 0 ) {
  11599.         len = strlen(s2);
  11600.         do {
  11601.         do {
  11602.             if ((sc = *s1++) == 0) return (NULL);
  11603.         } while (sc != c);
  11604.         } while (strncmp(s1, s2, len) != 0);
  11605.         s1--;
  11606.     }
  11607.     return( s1 );
  11608. }
  11609.  
  11610. /* this one parses input of interest from the comm channel, and
  11611.  * takes appropriate action to place stones on the board
  11612.  */
  11613. process_input( str )
  11614.     char *str;
  11615. {
  11616.     int i, j, len, ret, tt, t, c2;
  11617.     int m, code, yloc;
  11618.     char xloc, color;
  11619.     static char s[BUFFSIZE];
  11620.     static int beenhere = FALSE;
  11621.     char *temp_str, *current_str;
  11622.     char p1[20], p2[20];
  11623.  
  11624.     if( !beenhere ) {
  11625.         beenhere = TRUE;
  11626.         for( j=0; j<BUFFSIZE; ++j ) s[j] = '\0';
  11627.     }
  11628.  
  11629.     if( dbg ) fprintf( stderr, "In process_input: str=>>%s<<\n", str );
  11630.  
  11631.     for( temp_str = str ;; ) {
  11632.  
  11633.         /* find newline */
  11634.         for(i=0; temp_str[i] != '\n' && temp_str[i] != '\0'; ++i );
  11635.  
  11636.         /* no newline ..... */
  11637.         if( temp_str[i] == '\0' ) {
  11638.         if( i > 0 ) {
  11639.             strcat( s, temp_str );
  11640.         }
  11641.  
  11642.         /* get code */
  11643.         ret = sscanf( s, "%d", &code );
  11644.  
  11645.          /* no code, print it */
  11646.         if( ret != 1 ) {
  11647.             fprintf( stderr, "%s", s );
  11648.             fflush( stderr );
  11649.             for( j=0; j<BUFFSIZE; ++j ) s[j] = '\0';
  11650.         }
  11651.         return( 0 );
  11652.         }
  11653.  
  11654.         if( temp_str[i] == '\n' ) {
  11655.  
  11656.         len = strlen(s);
  11657.         strncat( s, temp_str, i );
  11658.         s[i+len+1] = '\0';
  11659.  
  11660.         /* get code */
  11661.         ret = sscanf( s, "%d", &code );
  11662.  
  11663.         /* no code, print it */
  11664.         if( ret != 1 ) {
  11665.                 fprintf( stderr, "%s\n", s );
  11666.                 fflush( stderr );
  11667.         }
  11668.  
  11669.         else {
  11670.             /* find space */
  11671.             for(j=0; s[j] != ' ' && s[j] != '\0'; ++j );
  11672.             if( s[j] == ' ' ) current_str = &s[++j];
  11673.             else current_str = &s[j];
  11674.  
  11675.             switch( code ) {
  11676.             case HELP:    /* has a "File" after code */
  11677.             case THIST:
  11678.             case STORED:
  11679.             case INFO:
  11680.             case MESSAGE:
  11681.                             /* scoring done under "INFO" msg */
  11682.                             if( observeflag == SCORING ) {
  11683.                                 ret = sscanf( current_str, "Removing @ %c%d",
  11684.                                                 &xloc, &yloc );
  11685.                                 if( ret == 2 ) {
  11686.                                     xloc = xloc - 'A' + 1;
  11687.                                     if( xloc > 8 ) --xloc;
  11688.                                     score_it( xloc, yloc );
  11689.                                 }
  11690.                             }
  11691.                 if( strncmp( current_str, "File", 4 ) == 0 ) {
  11692.                 fprintf( stderr, "%s\n", ¤t_str[4] );
  11693.                 if( infileflag ) infileflag = FALSE;
  11694.                                 else infileflag = TRUE;
  11695.                 }
  11696.                 else fprintf( stderr, "%s\n", current_str );
  11697.                 fflush( stderr );
  11698.                 break;
  11699.             case UNDO:    /* undo */
  11700.                 fprintf( stderr, "\n%s\n", current_str );
  11701.                 fflush( stderr );
  11702.                 undo();
  11703.                 break;
  11704.                 case MOVE:    /* a move */
  11705.                 /* game number? */
  11706.                 ret = sscanf( current_str,
  11707.                     "Game %d: %s (%d %d %d) vs %s (%d %d %d)",
  11708.                     &t, player1, &p1_captured, &p1_sec,
  11709.                     &p1_byoyomi, player2, &p2_captured,
  11710.                     &p2_sec, &p2_byoyomi );
  11711.  
  11712.                 if( ret == 9 ) {
  11713.                 if( t != gameno ) {
  11714.                     gameno = t;
  11715.                     fprintf( stderr,
  11716.                     "LOCAL: Changing game number to %d\n",
  11717.                     gameno );
  11718.                 }
  11719.  
  11720.                 update_status( gameno, player2,
  11721.                     player1, p2_captured, p1_captured,
  11722.                     p2_sec, p1_sec, p2_byoyomi,
  11723.                     p1_byoyomi );
  11724.                         fprintf( stderr, "%s\n", current_str );
  11725.                     fflush( stderr );
  11726.                 }
  11727.  
  11728.                 /* handicap? */
  11729.                 ret = sscanf( current_str, "%d(%c): Handicap %d", &m,
  11730.                     &color, &tt );
  11731.                 if( ret == 3 ) {
  11732.                 fprintf( stderr, "Handicap %d\n", tt );
  11733.                 handicap = tt;
  11734.                 sethandicap( tt );
  11735.                 update_handicap( handicap );
  11736.                 goto done;
  11737.                 }
  11738.  
  11739.                 /* its a move? */
  11740.                         ret = sscanf( current_str, "%d(%c): %c%d",
  11741.                 &m, &color, &xloc, &yloc );
  11742.                     if( ret == 4 ) {
  11743.                 move = m;
  11744.  
  11745.                             if( dbg ) {
  11746.                             fprintf( stderr,
  11747.                             "Move=%d, color=%c, xloc=%c, yloc=%d\n",
  11748.                             move, color, xloc, yloc );
  11749.                         }
  11750.                 ret = xloc - 'A' + 1;
  11751.                 if (ret > 8 ) --ret;
  11752.                     if( color == 'W' ) 
  11753.                             makemove( ret, yloc, move, WHITE);
  11754.                     else if( color == 'B' )
  11755.                             makemove( ret, yloc, move, BLACK);
  11756.                         fprintf( stderr, "%s\n", current_str );
  11757.                     fflush( stderr );
  11758.                         }
  11759.  
  11760.                 /* its a pass ?? */
  11761.                 else if( SCstrstr( current_str, "Pass" ) != NULL ) {
  11762.                 move = m;
  11763.                         makemove( (-1), (-1), move, EMPTY);
  11764.                 fprintf( stderr, "%s\n", current_str );
  11765.                     fflush( stderr );
  11766.                 }
  11767.                 
  11768.               done:
  11769.                     break;
  11770.             case PROMPT:    /* prompt */
  11771.                 sscanf( current_str, "%d", &c2 );
  11772.                 switch( c2 ) {
  11773.                 case LOGON:
  11774.                     fprintf( stderr, "Login: " );
  11775.                     break;
  11776.                 case PASSWORD:
  11777.                     fprintf( stderr, "Password: " );
  11778.                     break;
  11779.                 case PASSWD_NEW:
  11780.                    fprintf( stderr, "New Password: " );
  11781.                    break;
  11782.                 case PASSWD_CONFIRM:
  11783.                    fprintf( stderr, "Re-enter Password: " );
  11784.                    break;
  11785.                 case WAITING:
  11786.                     fprintf( stderr, "igs> " );
  11787.                     observeflag = FALSE;
  11788.                     break;
  11789.                 case PLAYING:
  11790.                     /* refresh board if just start playing */
  11791.                     if( observeflag != PLAYING )
  11792.                     RefreshBoard();
  11793.                     fprintf( stderr, "igs [p%d]> ", gameno );
  11794.                     observeflag = PLAYING;
  11795.                     break;
  11796.                 case SCORING:
  11797.                     if( observeflag != SCORING )
  11798.                     StartScoring();
  11799.                     fprintf( stderr, "igs [s%d]> ", gameno );
  11800.                     observeflag = SCORING;
  11801.                     break;
  11802.                 case OBSERVING:
  11803.                     /* refresh board if just start observing */
  11804.                     if( observeflag != OBSERVING )
  11805.                     RefreshBoard();
  11806.                     fprintf( stderr, "igs [o%d]> ", gameno );
  11807.                     observeflag = OBSERVING;
  11808.                     break;
  11809.                 default:
  11810.                             fprintf( stderr, "%s\n", current_str );
  11811.                     observeflag = FALSE;
  11812.                     break;
  11813.                 }
  11814.                 fflush( stderr );
  11815.                 break;
  11816.             case SCORE:
  11817.                 if( observeflag == SCORING )
  11818.                     StopScoring();
  11819.             case LOOK_M:
  11820.             case STATUS:
  11821.             case UNKNOWN:    /* strip the code from these, but */
  11822.             case BOARD:    /* otherwise pass them untouched */
  11823.             case DOWN:
  11824.             case ERROR:
  11825.             case FIL:
  11826.             case GAMES:
  11827.             case LAST:
  11828.             case KIBITZ:
  11829.             case LOAD:
  11830.             case OBSERVE:
  11831.             case REFRESH:
  11832.             case SAVED:
  11833.             case SAY:
  11834.             case SHOUT:
  11835.             case TELL:
  11836.             case TRANS:
  11837.             case SHOW:      /* what is this? */
  11838.             case TIM:
  11839.             case WHO:
  11840.                 if( strncmp( current_str, "File", 4 ) == 0 ) {
  11841.                 fprintf( stderr, "%s\n", ¤t_str[4] );
  11842.                 if( infileflag ) infileflag = FALSE;
  11843.                                 else infileflag = TRUE;
  11844.                 }
  11845.                 else fprintf( stderr, "%s\n", current_str );
  11846.                 fflush( stderr );
  11847.                     break;
  11848.             case BEEP:
  11849.                 if( current_str[0] == 0x07 ) {
  11850.                     fprintf( stderr, "\007" );
  11851.                     current_str += 2;
  11852.                 }
  11853.                 fprintf( stderr, "%s\n", current_str );
  11854.                 fflush( stderr );
  11855.                 break;
  11856.             default:    /* print code if it is unexpected */
  11857.                     fprintf( stderr, "%d %s\n", code, current_str );
  11858.                 fflush( stderr );
  11859.                     break;
  11860.             }
  11861.         }
  11862.             
  11863.         /* reset active string */
  11864.         for( j=0; j<BUFFSIZE; ++j ) s[j] = '\0';
  11865.         temp_str = &temp_str[i+1];
  11866.         continue;
  11867.         }
  11868.     }
  11869. }
  11870.  
  11871.  
  11872. SHAR_EOF
  11873. fi
  11874. if test -f 'help.c'
  11875. then
  11876.     echo shar: "will not over-write existing file 'help.c'"
  11877. else
  11878. cat << \SHAR_EOF > 'help.c'
  11879. /* "mgt" Copyright (c) 1991 Shodan  */
  11880.  
  11881. /* Short help strings.  Don't make any of these longer than the longest one
  11882.  * already present */
  11883.  
  11884. char *shortHelpStr[] =
  11885. {
  11886.    "Quit mgt (turn off help to quit)",
  11887.    "Move forward",
  11888.    "Move backward",
  11889.    "Next node",
  11890.    "Previous node",
  11891.    "End of the current variation",
  11892.    "Beginning of file",
  11893.    "Next comment",
  11894.    "Previous comment",
  11895.    "Next variation branch",
  11896.    "Last variation branch",
  11897.    "Jump to a specific node number",
  11898.    "Write Smart-Go file",
  11899.    "Set black stone",
  11900.    "Set white stone",
  11901.    "Make variation",
  11902.    "Cut tree into buffer",
  11903.    "Add letter",
  11904.    "Add mark",
  11905.    "Load new file",
  11906.    "Paste buffer in",
  11907.    "Edit comment",
  11908.    "Delete current node",
  11909.    "Name the current node",
  11910.    "Score the game",
  11911.    "Pass move",
  11912.    "Other player's turn (permanent)",
  11913.    "Toggle stone",
  11914.    "Reverse through files",
  11915.    "Forward through files",
  11916.    "Redraw screen",
  11917.    "Toggle save format",
  11918.    "Toggle tutor mode",
  11919.    "Save screen image",
  11920.    "Show game info",
  11921.    "Make a move",
  11922.    "Cursor down left",
  11923.    "Cursor down",
  11924.    "Cursor down right",
  11925.    "Cursor left",
  11926.    "Cursor right",
  11927.    "Cursor up left",
  11928.    "Cursor up",
  11929.    "Cursor up right",
  11930.    "___last command marker___"};
  11931. char *longHelpStr[] =
  11932. {
  11933.    "I think this token has two purposes.  One is to quit out of xmgt, the other is to quit scoring.  You must turn off help to quit mgt :) :).",
  11934.    " Step down the game tree to the next move.  Stop at the end of a variation and do not visit other variations.",
  11935.    "Move back up the game tree (previous move) -- the opposite of \",\".",
  11936.    "Go to the next node using a tree traversal which will visit all nodes.  Sometimes the order of traversal can be confusing.",
  11937.    "Go to the previous node -- the opposite of \".\" forward movement.",
  11938.    "End of the current variation",
  11939.    "Beginning of file, beginning of game tree.",
  11940.    "Does \".\" until a node with a comment it reached.",
  11941.    "Does \",\" until a node with a comment it reached.",
  11942.    "Move forward until there is a variation branch in the game tree.",
  11943.    "Move backwards until there is a variation branch in the game tree.",
  11944.    "Goes to a numbered node.  You will be prompted with a dialog box, enter the node number in the dialog box.  Make sure your cursor is in the text box.",
  11945.    "Write out Smart-Go file.  Will prompt for a filename.  The path to the file is in the upper text box, the file name should be entered on the lower text box.  Becarefull in the file dilog, when one hits return it is becomes part of the file name.",
  11946.    "Set a black stone on the board.  If you click to select a point (a square box will appear) this command will place a stone on that point.  This command has no regaurd for whose turn it is.  This command is a toggle, selecting a point with a black stone will erase that stone, selecting a point with a white stone will place a black stone on the board.",
  11947.    "Set a white stone on the board.  If you click to select a point (a square box will appear) this command will place a stone on that point.  This command has no regaurd for whose turn it is.  This command is a toggle, selecting a point with a white stone will erase that stone, selecting a point with a black stone will place a white stone on the board.",
  11948.    "Create a variation below the current node.  The variation will initially contain a null node.  You must move to that variation to make a move in it.  If the \"v\" command is invoked at a node which is at the end of a variation, variation \"Var. 0\" is created with a null node.  Subsequent invocations of the \"v\" command will create the \"Var. 1\", \"Var. 2\"... variations.",
  11949.    "Cut tree.  Moves the current node and everything below it to a temporary holding buffer.  (Moves your location back to the parent of the node you are one when you invoke it.)",
  11950.    "Places a letter on the selected point.  The letters start at \"a\".",
  11951.    "Places a mark on the selected point.  The mark is a diamond shape.",
  11952.    "Load new file",
  11953.    "Paste tree.  Pastes the temporary holding buffer in after the current node.  Usually the  opposite of cutting the tree.",
  11954.    "Edits the comment.  A dialog box will come up asking you if the chages are ok.  You are to edit the comment, as you wish, and then click \"confirm\" to keep the comment, or \"cancel\" to revert back to the original.",
  11955.    "Delete node.  Deletes the current node, replacing it with its child.  If the current node has no child, then clear the proper- ties of the current node.",
  11956.    "Name the current node.  You will be prompted for the name.",
  11957.    "Score the game.  After selecting this, move the cursor around and remove the dead groups with 0 or space.  You can undo one (and only one) kill with the u key.  Pressing return will score the game and print the (Japanese) score in the comment area.  If you missed some dead groups, continue removing them.  Press q when you wish to exit scoring mode.  You will be prompted to either keep the score information as a comment for the current node or restore the old comment",
  11958.    "Select \"Pass\" as a move.",
  11959.    "Other player.  Changes whose turn it is, adding a token in the game tree to force the change whenever this node is visited.  If the player is forced by such a token, the current player turn is indicated by } { characters on the lower right.",
  11960.    "Toggle stone color.  Changes whose turn it is without adding any tokens in the game tree.  This will not work if the game tree has a PLayer token (generated by the o key) at the current node.",
  11961.    "Load previous file.  (Reverse through the file list)",
  11962.    "Load next file.  (Forward through the file list",
  11963.    "Redraw screen, not in xmgt",
  11964.    "Toggle save format.  Has something to do with mailgo, I believe.  It should be in mgtdoc.asc -- sigh",
  11965.    "Toggle tutor mode -- could not find this easily -- sigh, but has something to do with making a move.",
  11966.    "Prompts for a file, then writes an ascii board out.  Becarefull in the file dilog, when one hits return it is becomes part of the file name.",
  11967.    "Show game info -- -- could not find this easily -- sigh",
  11968.    "Make a move.  The current player turn is indicated by the > < around the captured stones on the lower right.  Normally, this adds the move to the game tree and moves to a new node.  In tutor mode, it checks the various game continuations.  If one of them contains the move you made, it moves to that variation.  If not, it prints an error message.  The game tree cannot be modified in tutor mode.",
  11969.    "Cursor down left -- not in xmgt",
  11970.    "Cursor down -- not in xmgt",
  11971.    "Cursor down right -- not in xmgt",
  11972.    "Cursor left -- not in xmgt",
  11973.    "Cursor right -- not in xmgt",
  11974.    "Cursor up left -- not in xmgt",
  11975.    "Cursor up -- not in xmgt",
  11976.    "Cursor up right -- not in xmgt",
  11977.    "___last command marker___"};
  11978. SHAR_EOF
  11979. fi
  11980. if test -f 'imakefile'
  11981. then
  11982.     echo shar: "will not over-write existing file 'imakefile'"
  11983. else
  11984. cat << \SHAR_EOF > 'imakefile'
  11985.  
  11986.     DEFINES = -DXMGT_HFS
  11987.         MANSUFFIX = 6
  11988.   LOCAL_LIBRARIES = XawClientLibs
  11989.  
  11990.             SRCS = help.c  build.c comment.c doit.c edit.c \
  11991.               mgt.c parse.c play.c tree.c Board.c x11.4.c xutil.c \
  11992.               advunix.c goserver.c DirMgr.c Directory.c \
  11993.           FileSel.c MultiList.c RegExp.c ScrList.c
  11994.  
  11995.             OBJS = help.o build.o comment.o doit.o edit.o \
  11996.               mgt.o parse.o play.o tree.o Board.o x11.4.o xutil.o \
  11997.               advunix.o goserver.o DirMgr.o Directory.o \
  11998.           FileSel.o MultiList.o RegExp.o ScrList.o
  11999.  
  12000.             ComplexProgramTarget(xmgt)
  12001. SHAR_EOF
  12002. fi
  12003. if test -f 'mailgo'
  12004. then
  12005.     echo shar: "will not over-write existing file 'mailgo'"
  12006. else
  12007. cat << \SHAR_EOF > 'mailgo'
  12008. #!/bin/sh
  12009. #
  12010. #  mailgo 1.641   E-mail go game management program by Adrian Mariano
  12011. #     11/21/92    I place it on the public domain.  Please send improvements
  12012. #                 to me at adrian@u.washington.edu.
  12013. #  Syntax: mailgo [-r] filename
  12014. #          mailgo -n [filename]
  12015. #          mailgo -c 
  12016. #          mailgo -e filename
  12017. #  Filename should contain a mailgo go game
  12018. #  
  12019. #  -r resends the file to the opponent
  12020. #  -n start a new game, using data in filename to get address
  12021. #  -c removes temporary files left when abnormally terminated
  12022. #  -e edits the mailgo header and/or the game record
  12023. #
  12024. #  Invokes the game processor in the environment variable MAILGO, or attempts
  12025. #  to run mgt from the inherited path if MAILGO is not set.
  12026. #
  12027. #  System V Unix users should change the assignment to the MAILER variable
  12028. #  from 'mail' to 'mailx' or 'elm' or some other compatible mailer.
  12029. #
  12030.  
  12031. MAILER=mail
  12032.  
  12033. if [ $# -eq 0 ]
  12034. then
  12035.   echo ' '
  12036.   echo 'Syntax: mailgo [-r] filename'
  12037.   echo '        mailgo -n [filename]'
  12038.   echo '        mailgo -c '
  12039.   echo '        mailgo -e filename'
  12040.   echo ' '
  12041.   echo 'Mailgo is a program to manage email go games.'
  12042.   echo 'Filename should contain a mailgo go game'
  12043.   echo '  '
  12044.   echo '  -r resends the file to the opponent'
  12045.   echo '  -n start a new game, using data in filename to get address'
  12046.   echo '  -c removes temporary files left when abnormally terminated'
  12047.   echo '  -e edits the mailgo header and/or the game record'
  12048.   echo ' '
  12049.   exit
  12050. fi
  12051. case $1 in
  12052.   -c) if [ $# -ne 1 ]
  12053.        then
  12054.          echo Wrong number of parameters
  12055.          exit
  12056.        else
  12057.          rm -f MailGo* MailFile* MailOut*
  12058.          exit
  12059.        fi;;
  12060.   -r) if [ $# != 2 ]
  12061.        then
  12062.          echo Wrong number of parameters
  12063.          exit
  12064.        fi
  12065.        if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1
  12066.        then
  12067.          name=`sed -n '2,5s/TO: //p' $2`
  12068.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  12069.          echo Remailing response to $name, $hisfile
  12070.          $MAILER -s "Remailed Go Game: $hisfile" $name < $2
  12071.          exit
  12072.        else
  12073.          echo Invalid input file $2
  12074.          exit
  12075.        fi;;
  12076.   -e) if [ $# -ne 2 ]
  12077.        then
  12078.          echo Wrong number of parameters
  12079.          exit
  12080.        fi
  12081.        if [ ! -s $2 ]
  12082.        then
  12083.          echo File $2 not found.
  12084.          exit
  12085.        fi
  12086. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  12087. p
  12088. }' $2 > MailGo$$
  12089.        if [ ! -s MailGo$$ ]
  12090.        then
  12091.          echo Invalid input file $2
  12092.          exit
  12093.        fi
  12094.        opponent=`sed -n '2,5s/TO: //p' MailGo$$`
  12095.        echo To address: $opponent
  12096.        echo -n "new address, <ret> for no change: "
  12097.        read res
  12098.        if [ $res ]
  12099.        then
  12100.          opponent=$res
  12101.        fi
  12102.        hisfile=`sed -n '2,5s/TOFILE: //p' MailGo$$`
  12103.        echo To game file: $hisfile
  12104.        echo -n "new file name, <ret> for no change: "
  12105.        read res
  12106.        if [ $res ]
  12107.        then
  12108.          hisfile=$res
  12109.        fi
  12110.        me=`sed -n '2,5s/FROM: //p' MailGo$$`
  12111.        echo From address: $me
  12112.        echo -n "new address, <ret> for no change: "
  12113.        read res
  12114.        if [ $res ]
  12115.        then
  12116.          me=$res
  12117.        fi
  12118.        myfile=`sed -n '2,5s/FROMFILE: //p' MailGo$$`
  12119.        echo From game file: $myfile
  12120.        echo -n "new file name, <ret> for no change: "
  12121.        read res
  12122.        if [ $res ]
  12123.        then
  12124.          myfile=$res
  12125.        fi
  12126.        if sed -n 6,7p MailGo$$ | grep FORMAT > /dev/null 2>&1
  12127.        then
  12128.          format=`sed -n '6,7s/FORMAT: //p' MailGo$$`
  12129.          if [ ! \( $format = 'L' -o $format = 'E' \) ] 
  12130.          then
  12131.            format='S'
  12132.          fi
  12133.        else
  12134.          format='L'
  12135.        fi
  12136.        echo Old game record format: $format
  12137.        echo -n "New game record format (Long/Short/Extrashort): "
  12138.        read res
  12139.        case $res in
  12140.          L | l) format='L' ;;
  12141.          E | e) format='E' ;;
  12142.          S | s) format='S' ;;
  12143.          *)  ;;
  12144.        esac
  12145.        case $format in
  12146.          L) sflag='';;
  12147.          *) sflag=-s;;
  12148.        esac
  12149.        if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  12150.        then
  12151.          if [ -s MailOut$$ ]
  12152.          then
  12153.        echo >> MailOut$$
  12154.            cat <<END_END > MailFile$$
  12155. ---GoGaMeStArT---
  12156. TO: $opponent
  12157. TOFILE: $hisfile
  12158. FROM: $me
  12159. FROMFILE: $myfile
  12160. FORMAT: $format
  12161. END_END
  12162.            if [ $format = 'S' ]
  12163.            then
  12164.              sed 's/\(;[BC]\[\)/\
  12165. \1/g' MailOut$$ >>MailFile$$
  12166.            else
  12167.              cat MailOut$$ >> MailFile$$
  12168.            fi
  12169.            echo >> MailFile$$
  12170.            echo "---GoGaMeEnD---" >> MailFile$$
  12171.          else
  12172.            echo -n "---GoGaMeStArT---" > MailFile$$
  12173.            sed "s/TO:.*/TO: $opponent/
  12174.             s/TOFILE:.*/TOFILE: $hisfile/
  12175.                 s/FROM:.*/FROM: $me/
  12176.                 s/FROMFILE:.*/FROMFILE: $myfile/
  12177.                 s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$
  12178.            echo "---GoGaMeEnD---" >> MailFile$$
  12179.            echo -n "empty mgt file"
  12180.            exit
  12181.          fi
  12182.        else
  12183.            echo -n "---GoGaMeStArT---" > MailFile$$
  12184.            sed "s/TO:.*/TO: $opponent/
  12185.             s/TOFILE:.*/TOFILE: $hisfile/
  12186.                 s/FROM:.*/FROM: $me/
  12187.                 s/FROMFILE:.*/FROMFILE: $myfile/
  12188.                 s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$
  12189.            echo "---GoGaMeEnD---" >> MailFile$$
  12190.          echo "No move made, or mgt error"
  12191.        fi
  12192.        rm -f MailGo$$ MailOut$$
  12193.        echo -n "Do you wish to keep updates (y/N)? "
  12194.        read res
  12195.        case $res in
  12196.          Y | y) cat MailFile$$ > $2
  12197.             echo  Updates saved to: $2
  12198.             rm -f MailFile$$
  12199.             exit;;
  12200.          *) echo   NOT keeping updates.
  12201.             rm -f MailFile$$
  12202.             exit;;
  12203.        esac
  12204.   ;;
  12205.   -n) if [ $# -gt 2 ]
  12206.        then
  12207.          echo Wrong number of parameters
  12208.          exit
  12209.        fi
  12210.        if [ $# -eq 2 ]
  12211.        then
  12212.          if [ ! -s $2 ]
  12213.          then
  12214.            echo File $2 not found.
  12215.            exit
  12216.          fi
  12217.          opponent=`sed -n '2,5s/TO: //p' $2`
  12218.          echo Opponent address: $opponent
  12219.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  12220.          echo His game file: $hisfile
  12221.          me=`sed -n '2,5s/FROM: //p' $2`
  12222.          echo Your address: $me
  12223.          myfile=`sed -n '2,5s/FROMFILE: //p' $2`
  12224.          echo Your game file: $myfile
  12225.        else
  12226.          echo -n "Opponent address: "
  12227.          read opponent
  12228.          echo -n "Opponent game filename: "
  12229.          read hisfile
  12230.          echo -n "Your address: "
  12231.          read me
  12232.          echo -n "Your game filename: "
  12233.          read myfile
  12234.        fi
  12235.        echo -n "Black player name: "
  12236.        read bpname
  12237.        echo -n "             rank: "
  12238.        read bprank
  12239.        echo -n "White player name: "
  12240.        read wpname
  12241.        echo -n "             rank: "
  12242.        read wprank
  12243.        echo -n "Board size (return for 19): "
  12244.        read bsize
  12245.        if [ "$bsize" -lt 7 -o "$bsize" -gt 19 ]
  12246.        then
  12247.          bsize=19
  12248.        fi
  12249.        echo -n "Handicap: "
  12250.        read handicap
  12251.        echo -n "Komi: "
  12252.        read komi
  12253.        echo -n "Game record format (Long/Short/Extrashort): "
  12254.        read format
  12255.        case $format in
  12256.          L | l) format='L' ;;
  12257.          E | e) format='E' ;;
  12258.          *)     format='S' ;;
  12259.        esac
  12260.        started=`date|awk '{print $3, $2, $6}'`
  12261.        if grep "W\[\]" $myfile >/dev/null 2>&1  
  12262.        then
  12263.          echo -n "File $myfile contains game possibly in progress.  Clobber (y/N)? "
  12264.          read res
  12265.          case $res in
  12266.            Y | y) ;;
  12267.            *)  echo -n "Your game filename: "
  12268.                read myfile;;
  12269.          esac
  12270.        fi
  12271.        cat <<END_END >$myfile
  12272. ---GoGaMeStArT---
  12273. FROM: $me
  12274. FROMFILE: $myfile
  12275. TO: $opponent
  12276. TOFILE: $hisfile
  12277. NEWGAME
  12278. FORMAT: $format
  12279. END_END
  12280.        cat <<END_END > MailGo$$
  12281. (
  12282. ;
  12283. GaMe[1]
  12284. VieW[]
  12285. SiZe[$bsize]
  12286. Comment[Black: $bpname, $bprank
  12287. White: $wpname, $wprank
  12288. `if [ "$handicap" ] ; then echo "Handicap: $handicap" ; fi`
  12289. `if [ "$komi" ] ; then echo "Komi: $komi" ; fi`
  12290. Started: $started]
  12291. PB[$bpname]
  12292. BR[$bprank]
  12293. PW[$wpname]
  12294. WR[$wprank]
  12295. `if [ "$komi" ] ; then echo KoMi[$komi] ; fi`
  12296. DaTe[$started]
  12297. `      case $bsize.$handicap in
  12298.          19.2) echo "PL[W]HA[2]AB[dp][pd]" ;;
  12299.          19.3) echo "PL[W]HA[3]AB[dp][pd][pp]" ;;
  12300.          19.4) echo "PL[W]HA[4]AB[dd][dp][pd][pp]" ;;
  12301.          19.5) echo "PL[W]HA[5]AB[dd][dp][jj][pd][pp]" ;;
  12302.          19.6) echo "PL[W]HA[6]AB[dd][dj][dp][pd][pj][pp]" ;;
  12303.          19.7) echo "PL[W]HA[7]AB[dd][dj][dp][jj][pd][pj][pp]" ;;
  12304.          19.8) echo "PL[W]HA[8]AB[dd][dj][dp][jd][jp][pd][pj][pp]" ;;
  12305.          19.9) echo "PL[W]HA[9]AB[dd][dj][dp][jd][jj][jp][pd][pj][pp]" ;;
  12306.          13.2) echo "PL[W]HA[2]AB[dj][jd]" ;;
  12307.          13.3) echo "PL[W]HA[3]AB[dj][jd][jj]" ;;
  12308.          13.4) echo "PL[W]HA[4]AB[dd][dj][jd][jj]" ;;
  12309.          13.5) echo "PL[W]HA[5]AB[dd][dj][gg][jd][jj]" ;;
  12310.          9.2) echo "PL[W]HA[2]AB[cg][gc]" ;;
  12311.          9.3) echo "PL[W]HA[3]AB[cg][gc][gg]" ;;
  12312.          9.4) echo "PL[W]HA[4]AB[cc][cg][gc][gg]" ;;
  12313.        esac`
  12314. )
  12315. END_END
  12316.        case $format in
  12317.          L) sflag='';;
  12318.          *) sflag=-s;;
  12319.        esac
  12320.        if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  12321.        then
  12322.          if [ -s MailOut$$ ]
  12323.          then
  12324.            cat MailOut$$ >>$myfile
  12325.          else
  12326.            cat MailGo$$ >>$myfile
  12327.          fi
  12328.        else
  12329.          echo -n "No move made, or mgt error. Send anyway (y/N)? "
  12330.          read res
  12331.          case $res in
  12332.            Y | y) cat MailGo$$ >>$myfile;;
  12333.            *) echo   NOT mailing new game.
  12334.               rm -f MailGo$$ MailOut$$
  12335.               exit;;
  12336.          esac
  12337.        fi
  12338.        rm -f MailOut$$ MailGo$$
  12339.        echo Mailing new game to $opponent, $hisfile
  12340.        echo >> $myfile
  12341.        echo "---GoGaMeEnD---" >> $myfile
  12342.        $MAILER -s "New Go Game: $hisfile" $opponent <$myfile
  12343.        exit
  12344.        ;;
  12345. esac
  12346. retty=''
  12347. if [ $# -ne 1 ]
  12348. then
  12349.   echo Wrong number of parameters
  12350.   exit
  12351. fi
  12352. if [ $1 = -- ]
  12353. then
  12354.   cat > /tmp/mailgo$$
  12355.   set /tmp/mailgo$$
  12356.   retty='</dev/tty'
  12357. elif [ ! -s $1 ]
  12358. then
  12359.   echo File $1 not found
  12360.   exit
  12361. fi
  12362. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  12363. p
  12364. }' $1 > MailGo$$
  12365. if [ ! -s MailGo$$ ]
  12366. then
  12367.   echo Invalid input file $1
  12368.   exit
  12369. fi
  12370. eval `sed -n '/---GoGaMeStArT---/,/(/{
  12371.   s/^TOFILE: /fileout=/p
  12372.   s/^FROMFILE: /hisfile=/p
  12373.   s/^FORMAT: /format=/p
  12374.   s/^TO: /me=/p
  12375.   s/^FROM: /name=/p
  12376.   s/^NEWGAME/newgame=1/p
  12377.   }' $1`
  12378. if [ -z "$format" ] 
  12379. then
  12380.   format=L
  12381. elif [ "$format" != L -a "$format" != E ]
  12382. then
  12383.   format=S
  12384. fi
  12385. case $format in
  12386.   L) sflag='';;
  12387.   *) sflag='-s';;
  12388. esac
  12389. if eval ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$ $retty
  12390. then
  12391.   echo >> MailOut$$
  12392.   if [ "$newgame" = 1 -a -s $fileout ]
  12393.   then
  12394.     echo -n "File $fileout exists.  Clobber (y/N)? "
  12395.     read res
  12396.     case $res in
  12397.       Y | y) rm -f $fileout ;;
  12398.       *) echo -n "Output filename: "
  12399.          read fileout ;;
  12400.     esac
  12401.   fi
  12402.   cat <<EOF > MailFile$$
  12403. ---GoGaMeStArT---
  12404. TO: $name
  12405. TOFILE: $hisfile
  12406. FROM: $me
  12407. FROMFILE: $fileout
  12408. FORMAT: $format
  12409. EOF
  12410.   case $format in
  12411.     S) sed 's/\(;[BC]\[\)/\
  12412. \1/g' MailOut$$ >>MailFile$$;;
  12413.     *) cat MailOut$$ >>MailFile$$;;
  12414.   esac 
  12415.   echo "---GoGaMeEnD---" >> MailFile$$
  12416.   echo Mailing response to $name, $hisfile
  12417.   $MAILER -s "Go Game: $hisfile" $name < MailFile$$ 
  12418.   rm -f MailGo$$ MailOut$$ $1
  12419.   if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || [ ! -s $fileout ]
  12420.   then
  12421.     mv MailFile$$ $fileout
  12422.   else
  12423.     echo Save file $fileout doesn\'t look like a mailgo file.  
  12424.     echo "Overwrite it anyway (y/N)?"
  12425.     read res
  12426.     case $res in
  12427.       y | Y) mv -f MailFile$$ $fileout;;
  12428.       *)     echo Game record left in MailFile$$;;
  12429.     esac
  12430.   fi
  12431. else
  12432.   echo No move made, or mgt error.  NOT mailing response.
  12433.   rm -f MailGo$$ MailOut$$
  12434. fi
  12435.  
  12436. SHAR_EOF
  12437. chmod +x 'mailgo'
  12438. fi
  12439. if test -f 'mailgo.6'
  12440. then
  12441.     echo shar: "will not over-write existing file 'mailgo.6'"
  12442. else
  12443. cat << \SHAR_EOF > 'mailgo.6'
  12444. .TH MAILGO 6  "21 September 1992"
  12445. .SH NAME
  12446. mailgo - shell script for using mgt to automate email go games
  12447. .SH SYNOPSIS
  12448. .B mailgo [\-r] [\-n] [\-c] [\-e] [filename]
  12449. .SH DESCRIPTION
  12450. .B mailgo
  12451. helps manage email games by processing Smart-Go game records received by
  12452. mail, invoking mgt, and automatically sending your next move back.
  12453. .LP
  12454. Invoking 
  12455. .B mailgo 
  12456. with no flags instructs the program to search the specified file for a
  12457. go game, ignoring mail headers or other such garbage.  
  12458. .B mailgo 
  12459. will invoke the game processor specified in the environment variable
  12460. MAILGO or of this variable is undefined, will attempt to run 
  12461. .B mgt
  12462. from the inherited path.
  12463. .LP
  12464. If your opponent loses your move, you can resend the game with the \-r
  12465. switch.
  12466. .LP
  12467. To start a new game, use the \-n switch.  Without a file, you will be 
  12468. prompted for your address, your opponent's address, and the filename for
  12469. both your and your opponent's local game record.  The game processor will
  12470. then be invoked for you to make the first move.  If a filename is specified,
  12471. the address and filename data is taken from that file.
  12472. .LP
  12473. The \-c switch causes the program to delete any extraneous files it
  12474. might have created during a previous run which was abnormally
  12475. terminated.
  12476. .LP
  12477. To edit the mailgo headers (including mail addresses, file names and game
  12478. record format) or the game record, use the \-e switch with the file name
  12479. of the mailgo file you wish to edit.  The file may be a saved mailgo
  12480. mail message or a processed mailgo game file.  The \-e option will not
  12481. mail changes because of the possibility of confusing addresses.  To mail
  12482. edited files, use 'mailgo <file>' for edited mail messages and 'mailgo -r
  12483. <file>' for edited files which have been previously processed by
  12484. .B mailgo.
  12485. .LP
  12486. .B mailgo 
  12487. also supports go board sizes of 9x9, 13x13 and 19x19.  Handicaps
  12488. maybe set to values of 2-4 for 9x9 games, 2-5 for 13x13 games and 2-9
  12489. for 19x19 games.  Any other board size or handicap must be set behind
  12490. .B mailgo
  12491. 's back.
  12492. .SH FILE FORMAT
  12493. .LP
  12494. .sp
  12495. .if
  12496.  Leading garbage ignored
  12497.  
  12498.  ---GoGaMeStArT---
  12499.  TO: opponent@hissite
  12500.  TOFILE: his_game_record
  12501.  FROM: me@mysite
  12502.  FROMFILE: my_game_record
  12503.  FORMAT: format_code
  12504.  (
  12505.  Smart\-Go game data
  12506.  )
  12507.  ---GoGaMeEnD---
  12508.  
  12509.  Trailing garbage ignored
  12510. .fi
  12511. .LP
  12512. The game data file contains a leading tag to indicate the start of 
  12513. the data.  It contains both addresses, as should be used to mail the
  12514. game files, and it contains the files to store the games in.  In the
  12515. example above, you are playing opponent@hissite, and the game is being
  12516. stored in my_game_record.
  12517. .LP
  12518. The file format used can be either long, short, or extrashort indicated by L, 
  12519. S, and E respectively.  The long format uses the full size Smart-Go file 
  12520. saved with no options from mgt.  The extrashort format uses mgt with the \-s 
  12521. option to save short format files.  This format may cause problems for some
  12522. mailers, however, because the lines will grow longer than 512 bytes.
  12523. In any game record format, if very long comments are created, there is a
  12524. danger of causing mailer problems. 
  12525. The short format is similar to the extrashort format but has extra newlines
  12526. inserted.  The short format is the default when selecting format from
  12527. the prompt, but the long format is the default if a file contains no FORMAT
  12528. line.
  12529. When 
  12530. .B mailgo
  12531. is used normally, the file specified on the command line is removed at
  12532. successful completion, and the new game is saved to the file specified in
  12533. the received game record.  If the destination file does not look like
  12534. a mailgo file, 
  12535. .B mailgo
  12536. will query for confirmation.
  12537. .SH FILES
  12538. mgt
  12539. .LP
  12540. Smart-Go.def, the Smart\-Go format definition.
  12541. .sp
  12542. .SH BUGS
  12543. .LP
  12544. .B mailgo 
  12545. now handles the case where you attempt to start a new game, 
  12546. but are not the first player to make a real move. 
  12547. If after the first move you have a reason to convince mgt that you have 
  12548. changed the game record without really changing anything, you should
  12549. enter and exit the comment editor. 
  12550. .fi
  12551. .sp
  12552. .SH AUTHOR
  12553. Adrian Mariano (adrian@u.washington.edu)
  12554.  
  12555.  
  12556. SHAR_EOF
  12557. fi
  12558. if test -f 'mgt.6'
  12559. then
  12560.     echo shar: "will not over-write existing file 'mgt.6'"
  12561. else
  12562. cat << \SHAR_EOF > 'mgt.6'
  12563. .TH MGT 6  "21 September 1992"
  12564. .SH NAME
  12565. mgt - game record display/editor for the oriental game of go
  12566. .SH SYNOPSIS
  12567. .B mgt
  12568. [\-m filename] [\-s] [-t] [files]
  12569. .SH DESCRIPTION
  12570. Go is an ancient oriental strategy game based on the capturing of territory.
  12571. The players alternate putting stones on the board, 
  12572. trying to surround as many empty intersections as possible.  
  12573. .LP
  12574. .B Mgt
  12575. allows the user to examine Go game tree files created through the 
  12576. Macintosh(tm) programs 
  12577. .B Smart-Go (tm)
  12578. or
  12579. .B Go Explorer (tm). 
  12580. .B Mgt
  12581. also has basic Go game tree editing capabilities and may be used to
  12582. create or edit game tree files.
  12583. The on\-line material provided by a
  12584. rather extensive and growing database allows many hours of instructional
  12585. enjoyment of various studies and tutorials concerning the game of Go. 
  12586. .LP
  12587. .B Mailgo 
  12588. is a utility which manages E-mail Go games using  
  12589. .B mgt 
  12590. as the Go board editor.  It is included in the 
  12591. .B mgt 
  12592. package.  
  12593. .LP
  12594. The 
  12595. .B mgt 
  12596. program was originally developed to be a companion for the series, 
  12597. "From My Go Teacher",
  12598. archived at scam.berkeley.edu and ftp.u.washington.edu for ftp.
  12599. Also available is the Internet GO Board communications program, 'go',
  12600. also by Greg Hale, which connects up two terminals in real\-time
  12601. anywhere in the world.
  12602. .SH COMMAND LINE OPTIONS
  12603. .TP 8
  12604. .B \-m filename
  12605. Invoke a set of options used by the 
  12606. .B mailgo
  12607. program for managing email games.  If a filename is specified for
  12608. loading (see below), the game record is loaded, and 
  12609. .B mgt
  12610. automatically moves to the end of the main variation of the game record.
  12611. The game can be modified without confirmation.
  12612. If the game record has been modified, 
  12613. it will be automatically saved, on exit, to the filename 
  12614. specified after the \-m and 
  12615. .B mgt
  12616. will return success (zero).  If the game record has not been modified, 
  12617. or has not been allowed to be saved, then 
  12618. .B mgt 
  12619. will return failure (nonzero). 
  12620. .LP
  12621. .TP 8
  12622. .B \-s
  12623. Change save format used to write save files.  The default save format is
  12624. the long format Smart\-Go file.  Using this option results in 
  12625. short format Smart\-Go files.
  12626. .LP
  12627. .TP 8
  12628. .B \-t
  12629. Invoke tutor mode where you select variations by playing on the board.
  12630. The key for making a move has special behavior in this mode.  See the 
  12631. section on the "space or 0" keyboard command for a description.
  12632. .LP
  12633. .TP 8
  12634. .B files
  12635. These are the files to be loaded.  The Unix and IBM version support 
  12636. wildcards.  If no file is specified, 
  12637. .B mgt 
  12638. loads a blank board.  If you attempt to modify a file that was loaded,
  12639. .B mgt 
  12640. will prompt for confirmation the first time.  
  12641. .LP
  12642. .SH OPERATION
  12643. .B Mgt
  12644. can be used to view and edit game records, 
  12645. or as an electronic game board for a two person 
  12646. game.  There are many keyboard commands which execute 
  12647. the various editing and display functions.
  12648. .LP
  12649. .TP 8
  12650. Step down the game tree to the next move.  Stop at the end of a variation
  12651. and do not visit other variations.
  12652. .LP
  12653. .TP 8
  12654. <
  12655. Move back up the game tree.  (Previous move)
  12656. .LP
  12657. .TP 8
  12658.  .
  12659. Go to the next node using a tree traversal which will visit all nodes.
  12660. Sometimes the order of traversal can be confusing.
  12661. .LP
  12662. .TP 8
  12663. ,
  12664. Go to the previous node -- the opposite of "." forward movement.
  12665. .LP
  12666. .TP 8
  12667. e
  12668. Go to end of the current variation.
  12669. .LP
  12670. .TP 8
  12671. b
  12672. Go to beginning of the game tree. 
  12673. .LP
  12674. .TP 8
  12675. }
  12676. Go forward like the "." command until a comment.
  12677. .LP
  12678. .TP 8
  12679. {
  12680. Go backwards like the "," command until a comment.
  12681. .LP
  12682. .TP 8
  12683. g
  12684. Go to a specified node.  Type in the desired node number.
  12685. .LP
  12686. .TP 8
  12687. Move forward until there is a variation branch in the game tree.
  12688. .LP
  12689. .TP 8
  12690. Move backwards until there is a variation branch in the game tree.
  12691. .LP
  12692. .TP 8
  12693. k and i 
  12694. Scroll the game tree variation window up and down.
  12695. A \- at the top of the variation window, and 
  12696. a + at the bottom indicate that more variations are available.
  12697. .LP
  12698. .TP 8
  12699. j and u 
  12700. Scroll comment window up and down.
  12701. A \- at the top of the comment, and 
  12702. a + at the bottom indicate that more comments are available.
  12703. .LP
  12704. .TP 8
  12705. Load new file.  Will prompt for confirmation if the current file has been
  12706. modified.
  12707. .LP
  12708. .TP 8
  12709. r
  12710. Load previous file.  (Reverse through the file list)
  12711. .LP
  12712. .TP 8
  12713. f
  12714. Load next file.  (Forward through the file list)
  12715. .LP
  12716. .TP 8
  12717. Write out Smart\-Go file.  Will prompt for a filename.  The special 
  12718. filename * will save with the current name (which appears in the upper 
  12719. right corner).  
  12720. .LP
  12721. .TP 8
  12722. space or 0 
  12723. Make a move.  The current player turn is indicated by the > < 
  12724. around the captured stones on the lower right.
  12725. Normally, this adds the move to the game tree and moves to a new node.
  12726. In tutor mode, it checks the various game continuations.  If one of them 
  12727. contains the move you made, it moves to that variation.  If not, it prints 
  12728. an error message.  The game tree cannot be modified in tutor mode.
  12729. .LP
  12730. .TP 8
  12731. Pass.  Enter a pass move.
  12732. .LP
  12733. .TP 8
  12734. C
  12735. Display the number of captured stones, in the X11R4 version.
  12736. .LP
  12737. .TP 8
  12738. o
  12739. Other player.  Changes whose turn it is, adding a token in the game tree to 
  12740. force the change whenever this node is visited.  If the player is forced by 
  12741. such a token, the current player turn is indicated by } { characters on the 
  12742. lower right.  
  12743. .LP
  12744. .TP 8
  12745. t
  12746. Toggle stone color.  Changes whose turn it is without adding any tokens in 
  12747. the game tree.  This will not work if the game tree has a PLayer token 
  12748. (generated by the o key) at the current node.
  12749. .LP 
  12750. .TP 8 
  12751. Set/unset black stones. 
  12752. .LP 
  12753. .TP 8 
  12754. Set/unset white stones. 
  12755. .LP 
  12756. .TP 8 
  12757. q or ESC.  
  12758. Quit.  q will 
  12759. prompt for confirmation.  ESC will not prompt for confirmation.  
  12760. .LP 
  12761. .TP 8 
  12762. Create a variation below the current node.  The variation will initially
  12763. contain a null node.  You must move to that variation to make a move in
  12764. it.  If the "v" command is invoked at a node which is at the end of a
  12765. variation, variation "A" is created with a null node.  Subsequent
  12766. invocations of the "v" command will create the "B", "C"... variations. 
  12767. .LP 
  12768. .TP 8 
  12769. Cut tree.  Moves the 
  12770. current node and everything below it to a temporary holding buffer.  (Moves 
  12771. your location back to the parent of the node you are one when you invoke it.) 
  12772. .LP 
  12773. .TP 8 
  12774. Paste tree.  Pastes the temporary holding buffer in after the 
  12775. current node.  Usually the  opposite of cutting the tree. 
  12776. .LP 
  12777. .TP 8 
  12778. Edit the current comment.  
  12779. The editor has been modeled vaguely after emacs.
  12780. That means that the editors commands are either
  12781. 'control-key'  or 'escape-key'.
  12782. The controls are configurable through an environment variable. 
  12783. I will use ^key to indicate control keys, and ]key to indicate
  12784. keys which should be preceeded by escape.  
  12785.  
  12786. On some terminals, instead of ESC-key, you can press Alt-key or
  12787. Meta-key.  (On the IBM version, you can use the Alt key)
  12788. Under VMS, the ESC key does not work.  VMS users may need to redefine
  12789. the edit keys.  
  12790.  
  12791. Defaults are:
  12792. .in +4m
  12793. .ta
  12794. .ta \w'delete to end of line (kill)\ \ 'u + 3m +
  12795. .nf
  12796. cursor up    (previous line)    ^P
  12797. cursor down  (next line)    ^N
  12798. page up      (prev page)    ]p
  12799. page down    (next page)    ]n
  12800. cursor left  (back)    ^B
  12801. cursor right (forward)    ^F
  12802. begining of line    ^A 
  12803. end of line    ^E
  12804. beginning of comment    ]<
  12805. end of comment    ]>
  12806. delete one character    ^D
  12807. delete to end of line (kill)    ^K
  12808. toggle insert mode    ^I
  12809. save comment    ]z
  12810. exit, don't save comment    ^W
  12811. .fi
  12812. .in -4m
  12813.  
  12814. Pressing c on a comment larger than the 120 lines allocated for comments will 
  12815. cause the extra to be lost.  Also, on terminals which generate IBM PC arrow
  12816. key codes, the arrow keys will correctly move the cursor within the
  12817. comment editor.  
  12818. .LP 
  12819. .TP 8 
  12820. Delete node.  Deletes the current node, replacing it with its 
  12821. child.  If the current node has no child, then clear the properties of the 
  12822. current node. 
  12823. .LP 
  12824. .TP 8 
  12825. Name the current node.  You will be prompted for the 
  12826. name. 
  12827. .LP 
  12828. .TP 8 
  12829. Score the game.  After selecting this, move the cursor 
  12830. around and remove the dead groups with 0 or space.  You can undo one (and 
  12831. only one) kill with the u key.  Pressing return will 
  12832. score the game and print the (Japanese) score in the comment area.
  12833. If you missed some dead groups, continue removing them.  Press q when you 
  12834. wish to exit scoring mode.  You will be prompted to either keep the score 
  12835. information as a comment for the current node or restore the old comment.
  12836. .LP
  12837. .TP 8
  12838. Ctrl\-I
  12839. Enter info mode.  In this mode, the various informational properties of the 
  12840. current file are displayed and may be edited.  To edit an item, press the 
  12841. letter associated with it, and enter the new text.  This letter must be 
  12842. entered in upper case.  To see a list of letters, press ?.  
  12843. The comment window scrolling keys can be used to 
  12844. scroll the info display.  The supported info properties are:
  12845. Size,
  12846. Handicap,
  12847. playerBlack,
  12848. bLackrank,
  12849. playerWhite,
  12850. whIterank,
  12851. Gamename,
  12852. Event,
  12853. rouNd,
  12854. Date,
  12855. Place,
  12856. Time,
  12857. Result,
  12858. gameComment,
  12859. sOurce,
  12860. User,
  12861. Komi.  The capital letters in this list indicate which letter selects that 
  12862. info property.  
  12863. .LP
  12864. .TP 8
  12865. Ctrl\-T
  12866. Toggle tutor mode.  (See the section on space or 0 for explanation.)
  12867. .LP
  12868. .TP 8
  12869. Ctrl\-W
  12870. Toggle the format used for writing Smart\-Go files between long and short.  
  12871. .LP
  12872. .TP 8
  12873. Ctrl\-L 
  12874. Refresh the screen.
  12875. .LP
  12876. .TP 8
  12877. Ctrl\-F 
  12878. Save the current screen to a file.
  12879. .LP
  12880. .TP 8
  12881. Display a help screen.
  12882. .LP
  12883. .TP 8
  12884. 12346789 
  12885. Move the cursor around.  Assumes standard numeric keypad orientation.
  12886. .LP
  12887. .SH ENVIRONMENT SETTINGS
  12888. All of the characters used for the commands and the display are configurable 
  12889. via environment variables.  For the ascii interface, use:
  12890. .LP
  12891. .sp
  12892. .if n \{.nf
  12893. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdn
  12894.                     spotrfLWTFI012346789kiju&
  12895.             _ASCCHAR:@O:+\-.+|\-++++
  12896.             _ASCINV _ASCED:PNpnBFAE<>DKIzO'
  12897.        (command should appear all on one line with a 
  12898.         single space separating _ASC... from the
  12899.         previous string.)
  12900. .fi
  12901. \}
  12902. .if t \{.nf
  12903. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdnspotrfLWTFI012346789kiju&
  12904.             _ASCCHAR:@O=+\-.+|\-++++
  12905.             _ASCINV _ASCED:PNpnBFAE<>DKIzW' 
  12906. .fi 
  12907. .in +.25i 
  12908. (command should appear all 
  12909. on one line with a single space separating _ASC... from the previous string.) 
  12910. .in -.25i 
  12911. \} 
  12912. .LP 
  12913. to get the default characters.  (This is csh syntax.  For 
  12914. other shells, the syntax will be different.)  
  12915. Place this line in your .cshrc so the alternate characters are 
  12916. always in effect.  
  12917. .LP
  12918. The _ASCCOM string allows you to change the keyboard 
  12919. commands.  Upper case letters stand for control characters. 
  12920. .LP
  12921. The _ASCCHAR 
  12922. string specifies the display characters.  For example, to use # for black 
  12923. stones, change the @ to # in the _ASCCHAR string.
  12924. You need only include one of the two declarations ("_ASCCOM:" or 
  12925. "_ASCCHAR:") if you only want to change the commands or characters
  12926. but not both.
  12927. .LP
  12928. To set the default display type to inverse video, use _ASCINV in the 
  12929. MGT environment variable.
  12930. .LP
  12931. To set the comment editor commands, use _ASCED in the 
  12932. MGT environment variable.
  12933. For the _ASCED environment variable setting, 
  12934. control keys are specified with a 
  12935. capital letter, and ESC keys are anything which is not a capital letter.
  12936. This is the key string for the defaults: PNpnBFAE<>DKIzO.  
  12937. Note that ^V, ^O, ^C and ^Z are poor characters to use for
  12938. anything if you have berkeley unix 
  12939. because the berkeley tty drivers interpret these characters.
  12940. The ^V character is the quoting character which quotes the following
  12941. character.  You will need to press it twice for mgt to see it.
  12942. The other characters have to be quoted by first pressing ^V or mgt
  12943. will not recognize your keypress.
  12944. .LP
  12945. In all cases, when you set your own keys, you must set all of the keys, 
  12946. and they must appear in the correct order. 
  12947. If multiple contradictory specifications occur in the MGT
  12948. environment variable, the last that appear will be used by the program. 
  12949. Any option not specified will assume the default values identified above.
  12950. .LP
  12951. With the IBM version, the same effects may be achieved under DOS 4.0 or
  12952. DOS 5.0 with
  12953. a SET command placed in the AUTOEXEC.BAT file.  Under previous DOS 
  12954. versions, quotes were interpreted literally and "|", ">" and "<" characters
  12955. have special meanings and thus cannot be put into environment variables
  12956. with the SET command.
  12957. .LP
  12958. Under VMS, the command is just MGT = "_ASCCHAR:..."
  12959. .LP
  12960. In the X11 version the environment variables are not used.  I believe Xdefaults
  12961. are used.  I would be carfull setting the defaults you discover.
  12962. .LP
  12963. .LP
  12964. .SH COMMENT FORMATTING
  12965. Comments are expected to consist of long lines, each of which is one 
  12966. paragraph.  A single long line will be formatted to fit the display. 
  12967. Line breaks will be ignored if they are preceeded by a space, but will be 
  12968. respected otherwise. 
  12969. .SH DISPLAYS
  12970. All displays have in common the purpose of displaying a go tree.
  12971. .LP
  12972. ASCII display:
  12973. .LP
  12974. .sp
  12975. .ft CW
  12976. .nf
  12977.     A B C D E F G H  S T
  12978.    +---------------  ---+   -Suppose this is the second
  12979.  19|. . . @ . . . .  . .|19| line of the comment.  Since
  12980.  18|. O O @ @ @ O .  . .|18| there is some more of the
  12981.  17|. @ @ O O O O .  . .|17| comment above us unseen, 
  12982.  16|. @ O + . . . .  . .|16| the - appears to the left
  12983.  15|. @ O . O . . .  . .|15| of 'Suppose'.
  12984.  14|. . @ O . . . .  . .|14|
  12985.  13|. . @ . . . . .  . .|13|
  12986.  12|. . . . . . . .  . .|12|
  12987.  11|. . . . . . . .  . .|11| And here, when there is
  12988.  10|. . . + . . . .  . .|10| more of the comment
  12989.   9|. . . . . . . .  . .| 9| below, the '+'
  12990.   8|. . . . . . . .  . .| 8|+appears to our left.
  12991.   7|. . . . . . . .  . .| 7|
  12992.   6|. . . . . . . .  . .| 6|   Node #173: Name
  12993.   5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
  12994.   4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
  12995.   3|. . . . . . . .  . .| 3| D: variation 3 etc...            
  12996.   2|. . . . . . . .  . .| 2| E: variation 4
  12997.   1|. . . . . . . .  . .| 1|+F: variation 5
  12998.    +---------------  ---+    ? for help    read   long
  12999.     A B C D E F G H  S T     
  13000.  Black #11 at 'D19'               @: 0      > O: 0 <
  13001. .fi
  13002. .ft
  13003. .LP
  13004. The bottom line indicates that Black has just made move #11.  On the bottom 
  13005. right, the angle brackets around the white stone indicate that it is 
  13006. White's turn.  Above that, the word "read" indicates that the Smart\-Go file 
  13007. hasn't been modified, and "long" indicates that the default save format is 
  13008. the long format.  "Read" will change to "edit" if you modify the file, and 
  13009. it will say "tutor" if you enter tutor mode.
  13010. .LP
  13011. The X version does not do a lot of the 'neat' stuff the ascii client does.
  13012. There is no 'read', for example.  A lot of those types of things are not
  13013. documented by Adrian and are therefor hard to implement.  If you wish
  13014. to see the captured stones, in the board window type a 'C'.
  13015. .LP
  13016. .SH FILES
  13017. The 
  13018. .B From My Go Teacher
  13019. tutorial lessons, and many professional game records all available at 
  13020. ftp.u.washington.edu.
  13021. .LP
  13022. Internet go, a program to play go over internet, available on
  13023. ftp.u.washington.edu.
  13024. .LP 
  13025. Smart\-Go.def, the Smart\-Go format definition.
  13026. .sp
  13027. .SH BUGS
  13028. .LP
  13029. Comment editing is limited to 120 screen lines.
  13030. .LP
  13031. Most, but not all, of the Smart-Go properties are supported.
  13032. .LP
  13033. Send further bug reports to "adrian@u.washington.edu"
  13034. or "hale@scam.Berkeley.EDU"
  13035. .fi
  13036. .sp
  13037. .SH AUTHORS
  13038. Greg Hale (hale@scam.berkeley.edu)
  13039. .LP
  13040. Jeff Boscole
  13041. .LP
  13042. Adrian Mariano (adrian@u.washington.edu)
  13043. .sp
  13044. .SH SEE ALSO
  13045. rn rec.games.go \- a newsgroup on the game
  13046. .br
  13047. Graded go problems for beginners, vol 1-4,
  13048. Ishi Press (Highly recommended)
  13049. .br
  13050. In the Beginning, 
  13051. Ishi Press.
  13052. .br
  13053. The Treasure Chest Enigma, 
  13054. Ishi Press.
  13055. SHAR_EOF
  13056. fi
  13057. if test -f 'mgt.c'
  13058. then
  13059.     echo shar: "will not over-write existing file 'mgt.c'"
  13060. else
  13061. cat << \SHAR_EOF > 'mgt.c'
  13062. /* "mgt" Copyright (c) 1991 Shodan  */
  13063.  
  13064.  
  13065. #include <signal.h>
  13066. #include "mgt.h"
  13067.  
  13068. int retVal = 0;
  13069. interface *io;            /* current interface routines */
  13070. int boardsize;            /* global for board size */
  13071. char *info[LASTINFO - FIRSTINFO + 2];
  13072. int handicap;
  13073. char *commentBuf;        /* pointer to current node's comment */
  13074. extern interface asciiInterface;
  13075. int prisoners[2];
  13076. FILE *input = 0;
  13077. char name_buf[512];
  13078. char *files[MAX_FILES];
  13079. int filecount, currentfile;
  13080.  
  13081. #ifdef DEBUG
  13082. FILE *debug;
  13083. unsigned long totalmemory;
  13084. #endif
  13085.  
  13086. #ifdef MGT_IBM
  13087. extern unsigned _stklen = 32000;
  13088. #endif
  13089.  
  13090. typedef struct {
  13091.    char *arg;
  13092.    int *flag;
  13093.    char **str;
  13094. }  argType;
  13095.  
  13096.  
  13097. int mailFlag = 0;
  13098. int saveShort = 0;
  13099. int tutor = 0;
  13100. char *saveName;
  13101.  
  13102.  
  13103.  
  13104. static argType argTable[] =
  13105. {
  13106.    {"-m", &mailFlag, &saveName},
  13107.    {"-s", &saveShort, NULL},
  13108.    {"-t", &tutor, NULL}
  13109. };
  13110.  
  13111.  
  13112. FUNCTION main(argc, argv)
  13113. int argc;
  13114. char **argv;
  13115. {
  13116.  
  13117. #ifdef DEBUG
  13118.    debug = fopen("debug", "w");
  13119. #endif
  13120.  
  13121.    io = &asciiInterface;
  13122.    input = stdin;
  13123.    init(argv, &argc);
  13124.    parseLine(argc, argv);
  13125.    doit();
  13126.    myexit();
  13127. }
  13128.  
  13129.  
  13130.  
  13131. FUNCTION void die()
  13132. {
  13133.    signal(SIGINT, SIG_DFL);
  13134.    myexit();
  13135. }
  13136.  
  13137.  
  13138. FUNCTION void myexit()
  13139. {
  13140.    (*io->clearScreen) ();
  13141.    (*io->refreshIO) ();
  13142.    (*io->close) ();
  13143.    printf("Thank you for using mgt\n");
  13144.    exit(retVal);
  13145. }
  13146.  
  13147.  
  13148.  
  13149. FUNCTION void openfile(f)
  13150. char *f;
  13151. {
  13152. #ifdef MGT_LIB
  13153.    char game_lib[] = MGT_LIB;
  13154. #endif                /* MGT_LIB */
  13155.    strcpy(name_buf, f);
  13156.    if (!(input = fopen(f, "r")))
  13157.       strcpy(name_buf, "");
  13158. #ifdef MGT_LIB
  13159.    /* if not in local directory, try library */
  13160.    if (!input) {
  13161.       strcpy(name_buf, game_lib);
  13162.       strcat(name_buf, f);
  13163.       input = fopen(name_buf, "r");
  13164.    }
  13165. #endif                /* MGT_LIB */
  13166. }
  13167.  
  13168.  
  13169. FUNCTION void barf(s)
  13170. char *s;
  13171. {
  13172.    int i;
  13173.    for (i = 24; i--;)
  13174.       fprintf(stderr, "\n");
  13175.    fprintf(stderr, "%s\n", s);
  13176.    exit(1);
  13177. }
  13178.  
  13179.  
  13180. FUNCTION void initEnv()
  13181. {
  13182.    extern char *getenv();
  13183.    char *env;
  13184.  
  13185.    if (env = getenv("MGT"))
  13186.       while (*env) {
  13187.      while (*env && *env != '_')
  13188.         env++;
  13189.      if (*env)
  13190.         env++;
  13191.      if (*env)
  13192.         (*io->readEnv) (&env);
  13193.       }
  13194. }
  13195.  
  13196.  
  13197. FUNCTION void init(argv, argc)
  13198. char *argv[];
  13199. int *argc;
  13200. {
  13201.    initEnv();
  13202.    (*io->open) (argv, argc);
  13203.    signal(SIGINT, die);
  13204.    readInit();
  13205. }
  13206.  
  13207.  
  13208.  
  13209. FUNCTION void helpCommandLine(errMesg)
  13210. char *errMesg;
  13211. {
  13212.    (*io->close) ();
  13213.    fprintf(stderr, "\nERROR: %s\n\n", errMesg);
  13214.    fprintf(stderr, "                   MGT %s\n", VERSION);
  13215.    fprintf(stderr, "\nUsage: mgt [opts] [files]\n");
  13216.    fprintf(stderr, "[opts] is any of:\n");
  13217.    fprintf(stderr, "-m filename        mail mode.  Autosave on quit.\n");
  13218.    fprintf(stderr, "-s                 use short format when saving.\n\n");
  13219.    exit(2);
  13220. }
  13221.  
  13222.  
  13223. FUNCTION void parseLine(argc, argv)
  13224. int argc;
  13225. char **argv;
  13226. {
  13227.    int i;
  13228.  
  13229.    filecount = 0;
  13230.  
  13231.    while (++argv, --argc > 0) {
  13232.       if (**argv != '-') {
  13233.      files[filecount++] = *argv;
  13234.      if (filecount == MAX_FILES)
  13235.         helpCommandLine("Too many files specified");
  13236.       } else {
  13237.      for (i = 0; i < sizeof(argTable) / sizeof(argType); i++)
  13238.         if (!strcmp(argTable[i].arg, *argv)) {
  13239.            if (argTable[i].str)
  13240.           if (--argc)
  13241.              *(argTable[i].str) = (*++argv);
  13242.           else
  13243.              helpCommandLine("String expected on option");
  13244.            (*(argTable[i].flag))--;
  13245.            break;
  13246.         }
  13247.      if (i == sizeof(argTable) / sizeof(argType))
  13248.         helpCommandLine("Bad option");
  13249.       }
  13250.    }
  13251.    if (!filecount)
  13252.       input = stdin;
  13253.    else {
  13254.       currentfile = 0;
  13255.       openfile(files[0]);
  13256.       if (!input)
  13257.      helpCommandLine("File not found");
  13258.    }
  13259.  
  13260. }
  13261. SHAR_EOF
  13262. fi
  13263. if test -f 'mgt.h'
  13264. then
  13265.     echo shar: "will not over-write existing file 'mgt.h'"
  13266. else
  13267. cat << \SHAR_EOF > 'mgt.h'
  13268. /* "mgt" Copyright (c) 1991 Shodan  */
  13269.  
  13270. #define VERSION "2.3"
  13271.  
  13272. #ifdef DEBUG
  13273. #define BUG(s) fprintf(debug,s)
  13274. #else
  13275. #define BUG(s)
  13276. #endif
  13277.  
  13278. #define FUNCTION
  13279. #define false 0
  13280. #define true 1
  13281.  
  13282. #define MAX(a,b) ((a)>(b)?a:b)
  13283. #define MIN(a,b) ((a)<(b)?a:b)
  13284.  
  13285. #define MAX_FILES 200
  13286. #define MAX_LETTERS 12
  13287. #define MAXCOMMENT 4097
  13288. #define MAXCOMMENTLINES 300
  13289. #define MAXCOMMENTWIDTH 50
  13290.  
  13291. typedef int boolean;
  13292.  
  13293. typedef enum {
  13294.    C_QUIT = 0,
  13295.    C_DOWN, C_UP,
  13296.    C_WALKDOWN, C_WALKUP,
  13297.    C_END, C_BEGINNING,
  13298.    C_SEARCHCOMMENT, C_SEARCHBACKCOMMENT,
  13299.    C_DOWNFORK, C_UPFORK,
  13300.    C_GOTO,
  13301.    C_WRITE,
  13302.    C_ADDBLACK, C_ADDWHITE,
  13303.    C_ADDVAR,
  13304.    C_TREECUT,
  13305.    C_ADDLETTER, C_ADDMARK,
  13306.    C_LOAD, C_PASTE,
  13307.    C_EDCOMMENT,
  13308.    C_DELNODE, C_ADDNAME, C_SCORE, C_PASSMOVE, C_TOPLAY, C_TOGGLESTONE, C_BACKFILE, C_NEXTFILE,
  13309.    C_REDRAW, C_SAVESHORT, C_TUTORSWAP, C_SAVESCREEN, C_INFO, C_MOVE,
  13310.    C_DOWNLEFT, C_CURDOWN, C_DOWNRIGHT, C_CURLEFT,
  13311.    C_CURRIGHT, C_UPLEFT, C_CURUP, C_UPRIGHT,
  13312.    C_LASTCOMMAND, C_UNDO
  13313. }  command;
  13314.  
  13315.  
  13316. /* C_COMMENTSCROLLDOWN, C_COMMENTSCROLLUP, C_TREESCROLLDOWN, C_TREESCROLLUP, */
  13317.  
  13318. #define C_NOTHING ((command) 75)
  13319. #define C_CHOSECHILD ((command) 76)
  13320. #define C_NEXTCMD ((command) 127)
  13321.  
  13322. typedef enum {
  13323.    t_White,
  13324.    t_Black,
  13325.    t_Open,
  13326.    t_Close,
  13327.    t_NewNode,
  13328.    t_Comment,
  13329.    t_AddWhite,
  13330.    t_AddBlack,
  13331.    t_Letter,
  13332.    t_Mark,
  13333.    t_AddEmpty,
  13334.    t_Name,
  13335.    t_Pass,
  13336.    t_Player,
  13337.    t_Size,
  13338.    t_Handicap,
  13339.    t_PlayerBlack,
  13340.    t_BlackRank,
  13341.    t_PlayerWhite,
  13342.    t_WhiteRank,
  13343.    t_GameName,
  13344.    t_Event,
  13345.    t_Round,
  13346.    t_Date,
  13347.    t_Place,
  13348.    t_TimeLimit,
  13349.    t_Result,
  13350.    t_GameComment,
  13351.    t_Source,
  13352.    t_User,
  13353.    t_Komi,
  13354.  
  13355.    t_WS,
  13356.    t_EOF
  13357. }
  13358.    Token;
  13359.  
  13360.  
  13361. #define FIRSTINFO ((int)t_PlayerBlack)
  13362. #define LASTINFO  ((int)t_User)
  13363.  
  13364.  
  13365. typedef enum {
  13366.    P_NOTHING = 0, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR, P_WHITETERR, P_CHECKED
  13367. }
  13368.    piece;
  13369.  
  13370. typedef piece boardType[19][19];
  13371.  
  13372. typedef struct {
  13373.    boardType b;
  13374. }
  13375.    board, *pBoard;
  13376.  
  13377.  
  13378. typedef int (*pfi) ();
  13379.  
  13380. typedef struct {
  13381.    char *name;
  13382.    char *option;
  13383.    char *storage;
  13384.    pfi open, close, refreshIO, plotPiece, displayComment;
  13385.    pfi clearComment, initializeBoard, clearScreen, idle;
  13386.    pfi drawTree, highlightLast, readEnv, notifyMessage;
  13387.    pfi notifyClear, queryStr, setCursor, plotMark, plotLetter;
  13388.    pfi getPoint, editComment, askYN, notifyError, displayInfo;
  13389.    pfi getInfoToChange, editInfo;
  13390. }
  13391.    interface, *interfaceP;
  13392.  
  13393.  
  13394. typedef struct {
  13395.    char x, y;
  13396. }
  13397.    coord;
  13398.  
  13399.  
  13400. typedef struct coordstruct {
  13401.    char x, y;
  13402.    struct coordstruct *next;
  13403. }  coordList;
  13404.  
  13405.  
  13406. typedef struct propertyRec {
  13407.    struct propertyRec *next;
  13408.    Token t;
  13409.    union {
  13410.       coordList *stones;
  13411.       char *comment;
  13412.       Token player;
  13413.    }  data;
  13414. }
  13415.    property;
  13416.  
  13417.  
  13418. typedef struct noderec {
  13419.    property *p;
  13420.    int nodeNum;
  13421.    struct noderec *parent, *child, *nextSibling, *lastSibling;
  13422. }
  13423.    node, *nodep;
  13424.  
  13425.  
  13426. /* board coordinates used to indicate a pass */
  13427.  
  13428. #define PASSVAL 25
  13429.  
  13430.  
  13431.  
  13432. #include "proto.h"
  13433. #include <stdio.h>
  13434.  
  13435. #ifdef MGT_IBM
  13436. #include <alloc.h>
  13437. #endif
  13438.  
  13439.  
  13440. extern char *info[LASTINFO - FIRSTINFO + 2];
  13441. extern int handicap;
  13442.  
  13443. extern interface *io;
  13444. extern int boardsize;
  13445. extern int prisoners[2];
  13446. extern FILE *input;
  13447. extern int xcur, ycur;
  13448. extern Token curPlayer;
  13449. extern int mailFlag;
  13450. extern int saveShort;
  13451. extern int tutor;
  13452. extern char *saveName;
  13453. extern int retVal;
  13454. extern char name_buf[512];
  13455. extern filecount, currentfile;
  13456. extern char *files[MAX_FILES];
  13457.  
  13458. #ifdef DEBUG
  13459. extern FILE *debug;
  13460. extern unsigned long totalmemory;
  13461. #endif
  13462. SHAR_EOF
  13463. fi
  13464. if test -f 'parse.c'
  13465. then
  13466.     echo shar: "will not over-write existing file 'parse.c'"
  13467. else
  13468. cat << \SHAR_EOF > 'parse.c'
  13469. /* "mgt" Copyright (c) 1991 Shodan  */
  13470.  
  13471. #include <string.h>
  13472. #include "mgt.h"
  13473.  
  13474.  
  13475. struct {
  13476.    char *str;
  13477.    Token val;
  13478. }  tokens[] = {
  13479.    {
  13480.       "W", t_White
  13481.    },
  13482.    {
  13483.       "B", t_Black
  13484.    },
  13485.    {
  13486.       "C", t_Comment
  13487.    },
  13488.    {
  13489.       "AW", t_AddWhite
  13490.    },
  13491.    {
  13492.       "AB", t_AddBlack
  13493.    },
  13494.    {
  13495.       "L", t_Letter
  13496.    },
  13497.    {
  13498.       "AE", t_AddEmpty
  13499.    },
  13500.    {
  13501.       "N", t_Name
  13502.    },
  13503.    {
  13504.       "M", t_Mark
  13505.    },
  13506.    {
  13507.       "SZ", t_Size
  13508.    },
  13509.    {
  13510.       "GN", t_GameName
  13511.    },
  13512.    {
  13513.       "GC", t_GameComment
  13514.    },
  13515.    {
  13516.       "EV", t_Event
  13517.    },
  13518.    {
  13519.       "RO", t_Round
  13520.    },
  13521.    {
  13522.       "DT", t_Date
  13523.    },
  13524.    {
  13525.       "PC", t_Place
  13526.    },
  13527.    {
  13528.       "PB", t_PlayerBlack
  13529.    },
  13530.    {
  13531.       "PW", t_PlayerWhite
  13532.    },
  13533.    {
  13534.       "RE", t_Result
  13535.    },
  13536.    {
  13537.       "US", t_User
  13538.    },
  13539.    {
  13540.       "TM", t_TimeLimit
  13541.    },
  13542.    {
  13543.       "SO", t_Source
  13544.    },
  13545.    {
  13546.       "BR", t_BlackRank
  13547.    },
  13548.    {
  13549.       "WR", t_WhiteRank
  13550.    },
  13551.    {
  13552.       "HA", t_Handicap
  13553.    },
  13554.    {
  13555.       "KM", t_Komi
  13556.    }, {
  13557.       "PL", t_Player
  13558.    }
  13559.  
  13560. };
  13561.  
  13562.  
  13563. char buf[1028], *curin, started;
  13564.  
  13565. FUNCTION void readInit()
  13566. {
  13567.    int p;
  13568.    buf[0] = '\0';
  13569.    curin = &buf[0];
  13570.    started = 1;
  13571.    boardsize = 19;
  13572.    handicap = 0;
  13573.    for (p = 0; p <= LASTINFO - FIRSTINFO + 1; p++) {
  13574.       if (info[p])
  13575.      free(info[p]);
  13576.       info[p] = 0;
  13577.    }
  13578. }
  13579.  
  13580.  
  13581. static char *readLine()
  13582. {
  13583.    curin = &buf[0];
  13584.    buf[0] = '\0';
  13585.    return fgets(&buf[0], 1023, input);
  13586. }
  13587.  
  13588.  
  13589. static char readChar()
  13590. {
  13591.    if (*curin)
  13592.       return *(curin++);
  13593.    curin = &buf[0];
  13594.    buf[0] = '\0';
  13595.    fgets(&buf[0], 1023, input);
  13596.    return 0;
  13597. }
  13598.  
  13599.  
  13600.  
  13601. static int getCoordStr(co)
  13602. coord *co;
  13603. {
  13604.    if (strlen(curin) < 4 && curin[strlen(curin) - 1] != '\n') {
  13605.       char *dest;
  13606.       for (dest = buf; *curin; curin++, dest++)
  13607.      *dest = *curin;
  13608.       *dest = 0;
  13609.       fgets(dest, 1023, input);
  13610.       curin = buf;
  13611.    }
  13612.    if (curin[0] == '[' && curin[1] >= 'a' && curin[1] <= 's'
  13613.        && curin[2] >= 'a' && curin[2] <= 's' && curin[3] == ']') {
  13614.       co->x = curin[1] - 'a';
  13615.       co->y = curin[2] - 'a';
  13616.       curin += 4;
  13617.       while (*curin == ' ' || *curin == '\t')
  13618.      curin++;
  13619.       if (*curin == '\n')
  13620.      readLine();
  13621.       return 1;
  13622.    } else
  13623.       return 0;
  13624. }
  13625.  
  13626.  
  13627. static void getCoordList(clp)
  13628. coordList **clp;
  13629. {
  13630.    coord co;
  13631.    while (getCoordStr(&co)) {
  13632.       setCoord(co.x, co.y, clp);
  13633.    }
  13634. }
  13635.  
  13636. static void addPass(n, t)
  13637. nodep n;
  13638. Token t;
  13639. {
  13640.    property *p;
  13641.    if (!(p = (property *) calloc(1, sizeof(property))))
  13642.       barf("Memory allocation error (addPass)");
  13643.    p->t = t_Pass;
  13644.    p->data.player = t;
  13645.    addprop(n, p);
  13646.  
  13647. }
  13648.  
  13649.  
  13650.  
  13651. static void doPlayer(n)
  13652. nodep n;
  13653.  
  13654. {
  13655.    property *p;
  13656.  
  13657.    if (curin[0] == '[' && curin[2] == ']' && (curin[1] == 'B' || curin[1] == 'W')) {
  13658.       p = (property *) calloc(1, sizeof(property));
  13659.       if (!p)
  13660.      barf("Memory allocation failure (doPlayer)");
  13661.       p->t = t_Player;
  13662.       p->data.player = curin[1] == 'B' ? t_Black : t_White;
  13663.       curin += 3;
  13664.       addprop(n, p);
  13665.    }
  13666. }
  13667.  
  13668.  
  13669. static Token tokenize()
  13670. {
  13671.    int i, len;
  13672.    char buf[4];
  13673.  
  13674.    len = 0;
  13675.    do {
  13676.       if (!*curin || *curin == '\n') {
  13677.      if (!readLine())
  13678.         return t_EOF;
  13679.       }
  13680.       if (*curin == ')') {
  13681.      curin++;
  13682.      return t_Close;
  13683.       }
  13684.       if (*curin == '(') {
  13685.      curin++;
  13686.      return t_Open;
  13687.       }
  13688.       if (*curin == ';') {
  13689.      curin++;
  13690.      return t_NewNode;
  13691.       }
  13692.       if (*curin >= 'A' && *curin <= 'Z')
  13693.      buf[len++] = *curin;
  13694.       curin++;
  13695.    } while (len < 3 && *curin != '[');
  13696.    buf[len] = 0;
  13697.    if (len == 1 || len == 2)
  13698.       for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++)
  13699.      if (!strcmp(buf, tokens[i].str))
  13700.         return tokens[i].val;
  13701.    while (*curin != ']') {
  13702.       if (!*++curin) {
  13703.      if (!readLine())
  13704.         return t_EOF;
  13705.       }
  13706.    }
  13707.    return t_WS;
  13708. }
  13709.  
  13710.  
  13711.  
  13712. static void addMoveArrayProp(t, n)
  13713. Token t;
  13714. nodep n;
  13715. {
  13716.    property *p;
  13717.  
  13718. #ifdef DEBUG
  13719.    totalmemory += sizeof(property);
  13720.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  13721. #endif
  13722.    if (!(p = getprop(n, t))) {
  13723.       p = (property *) calloc(1, sizeof(property));
  13724.  
  13725. #ifdef DEBUG
  13726.       totalmemory += sizeof(coordList);
  13727.       fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  13728. #endif
  13729.  
  13730.       if (!p)
  13731.      barf("Memory allocation failure (addMoveArrayProp)");
  13732.  
  13733.       p->data.stones = 0;
  13734.       p->t = t;
  13735.       addprop(n, p);
  13736.    }
  13737.    getCoordList(&(p->data.stones));
  13738. }
  13739.  
  13740.  
  13741. static void doSize()
  13742. {
  13743.    int size;
  13744.    char *s, c, b[25];
  13745.    s = &b[0];
  13746.    readChar();
  13747.    while ((c = readChar()) != ']')
  13748.       if (c && c != '\\')
  13749.      *s++ = c;
  13750.    *s = 0;
  13751.    size = atoi(b);
  13752.    if ((size > 1) && (size <= 19))
  13753.       boardsize = size;
  13754. }
  13755.  
  13756.  
  13757.  
  13758. static void doHandicap()
  13759. {
  13760.    int size;
  13761.    char *s, c, b[25];
  13762.    s = &b[0];
  13763.    readChar();
  13764.    while ((c = readChar()) != ']')
  13765.       if (c && c != '\\')
  13766.      *s++ = c;
  13767.    *s = 0;
  13768.    size = atoi(b);
  13769.    if ((size > 1) && (size <= 17))
  13770.       handicap = size;
  13771. }
  13772.  
  13773.  
  13774.  
  13775. static void doComment(n, t)
  13776. nodep n;
  13777. Token t;
  13778. {
  13779.    char c, *s, *buffer;
  13780.    property *p;
  13781.    int space;
  13782.  
  13783.    buffer = (char *) malloc(MAXCOMMENT);
  13784.    p = (property *) calloc(1, sizeof(property));
  13785.    if (!(p && buffer))
  13786.       barf("Memory Allocation Failure (doComment)");
  13787.    s = buffer;
  13788.    space = MAXCOMMENT - 1;
  13789.    readChar();
  13790.    while ((c = readChar()) != ']') {
  13791.       if (!c && feof(input))
  13792.      break;
  13793.       if (c == '\\')
  13794.      c = readChar();
  13795.       if (c && space) {
  13796.      *s++ = c;
  13797.      space--;
  13798.       }
  13799.    }
  13800.    if (*(s - 1) == '\n')
  13801.       s--;
  13802.    *s = 0;
  13803.    p->t = t;
  13804.    p->data.comment = dupStr(buffer);
  13805.    addprop(n, p);
  13806.    free(buffer);
  13807. }
  13808.  
  13809.  
  13810. static void doInfo(t)
  13811. Token t;
  13812. {
  13813.    char *buffer, *s, c;
  13814.    int space;
  13815.    buffer = (char *) malloc(MAXCOMMENT);
  13816.    if (!buffer)
  13817.       barf("Memory allocation failure (doInfo)");
  13818.    s = buffer;
  13819.    space = MAXCOMMENT - 1;
  13820.    readChar();
  13821.    while (space && (c = readChar()) != ']') {
  13822.       if (c == '\\')
  13823.      c = readChar();
  13824.       if (c) {
  13825.      *s++ = c;
  13826.      space--;
  13827.       }
  13828.    }
  13829.    if (*(s - 1) == '\n')
  13830.       s--;
  13831.    *s = 0;
  13832.    info[(int) t - FIRSTINFO] = dupStr(buffer);
  13833.    free(buffer);
  13834. }
  13835.  
  13836. FUNCTION void addChild(n, c)    /* add child c to node n */
  13837. nodep n, c;
  13838. {
  13839.    if (n) {
  13840.       if (n->child) {
  13841.      nodep s;
  13842.      s = treeLastSibling(child(n));
  13843.      s->nextSibling = c;
  13844.      c->lastSibling = s;
  13845.      c->parent = n;
  13846.       } else {
  13847.      n->child = c;
  13848.      c->parent = n;
  13849.       }
  13850.    }
  13851. }
  13852.  
  13853.  
  13854. FUNCTION nodep parse(lev)
  13855. int lev;
  13856. {
  13857.    nodep r, n, new;
  13858.    Token t;
  13859.  
  13860.    if (started) {
  13861.       started = 0;
  13862.  
  13863.       while (*curin != '(') {
  13864.      if (!readLine())
  13865.         break;
  13866.       }
  13867.    }
  13868.    r = n = 0;
  13869.    for (;;) {
  13870.       t = tokenize();
  13871.       switch (t) {
  13872.      case t_Size:
  13873.         doSize();
  13874.         break;
  13875.      case t_White:
  13876.      case t_Black:
  13877.         if (curin[1] == 't' && curin[2] == 't' && curin[0] == '[' && curin[3] == ']') {
  13878.            addPass(n, t);
  13879.            break;
  13880.         }
  13881.      case t_AddWhite:
  13882.      case t_AddBlack:
  13883.      case t_AddEmpty:
  13884.      case t_Mark:
  13885.      case t_Letter:
  13886.         if (n)
  13887.            addMoveArrayProp(t, n);
  13888.         else
  13889.            fprintf(stderr, "Error - property w/o node in data\n");
  13890.         break;
  13891.      case t_Player:
  13892.         if (n)
  13893.            doPlayer(n);
  13894.         else
  13895.            fprintf(stderr, "Error - property w/o node in data\n");
  13896.         break;
  13897.      case t_Name:
  13898.      case t_Comment:
  13899.         if (n)
  13900.            doComment(n, t);
  13901.         else
  13902.            fprintf(stderr, "Error - property w/o node in data\n");
  13903.         break;
  13904.      case t_NewNode:
  13905.         new = newNode();
  13906.         if (!r)
  13907.            r = new;
  13908.         else
  13909.            addChild(n, new);
  13910.         n = new;
  13911.         break;
  13912.      case t_Open:
  13913.         if (lev == 1 && !r)
  13914.            n = r = newNode();
  13915.         if (new = parse(lev + 1)) {
  13916.            addChild(n, new);
  13917.            if (!r)
  13918.           r = new;
  13919.         }
  13920.         break;
  13921.      case t_Close:
  13922.      case t_EOF:
  13923.         return r;
  13924.  
  13925.      case t_GameName:
  13926.      case t_GameComment:
  13927.      case t_Event:
  13928.      case t_Round:
  13929.      case t_Date:
  13930.      case t_Place:
  13931.      case t_PlayerBlack:
  13932.      case t_PlayerWhite:
  13933.      case t_Result:
  13934.      case t_User:
  13935.      case t_TimeLimit:
  13936.      case t_Source:
  13937.      case t_BlackRank:
  13938.      case t_WhiteRank:
  13939.  
  13940.         doInfo(t);
  13941.         break;
  13942.      case t_Komi:{
  13943.            char *ch, *end;
  13944.            doInfo(t_Komi);
  13945.            end = ch = info[(int) t_Komi - FIRSTINFO];
  13946.            while (*end)
  13947.           end++;
  13948.            for (end--; *end == '0' && (end != ch); end--);
  13949.            *++end = 0;
  13950.         }
  13951.         break;
  13952.      case t_Handicap:
  13953.         doHandicap();
  13954.         break;
  13955.      default:
  13956.         break;
  13957.       }
  13958.    }
  13959. }
  13960. SHAR_EOF
  13961. fi
  13962. if test -f 'play.c'
  13963. then
  13964.     echo shar: "will not over-write existing file 'play.c'"
  13965. else
  13966. cat << \SHAR_EOF > 'play.c'
  13967. /* "mgt" Copyright (c) 1991 Shodan  */
  13968.  
  13969.  
  13970. #include "mgt.h"
  13971. #include <string.h>
  13972. #include <stdio.h>
  13973.  
  13974. /* void printboard(char *s,pBoard b) { FILE *fil; int i,j;
  13975.  * fil=fopen("dump","a+"); if (!fil) {printf("can't open file");getch();}
  13976.  * fprintf(fil,"%s\n",s); for(i=0;i<boardsize;i++){ for(j=0;j<boardsize;j++)
  13977.  * fputc( b->b[i][j]==P_NOTHING?'.':(b->b[i][j]==P_BLACK?'*':'O'),fil);
  13978.  * fputc('\n',fil); } fclose(fil); } */
  13979.  
  13980.  
  13981.  
  13982.  
  13983. FUNCTION int legal(b, n, player, i, j)
  13984. pBoard b;
  13985. nodep n;
  13986. int i, j;
  13987. Token player;
  13988. {
  13989.    board a, copy;
  13990.    int same, x, y, savex, savey, savemove;
  13991.    boolean islegal;
  13992.    extern int moveNum;
  13993.    int savepris[2];
  13994.    extern int prisoners[];
  13995.  
  13996.    savemove = moveNum;
  13997.    savex = xcur;
  13998.    savey = ycur;
  13999.    savepris[0] = prisoners[0];
  14000.    savepris[1] = prisoners[1];
  14001.    copyBoard(b, ©);
  14002.  
  14003.    islegal = true;
  14004.  
  14005.    if (b->b[i][j] != P_NOTHING) {
  14006.       (*io->notifyError) ("There's already a piece there.");
  14007.       return false;
  14008.    }
  14009.    placeStone(©, i, j, (player == t_Black) ? P_BLACK : P_WHITE);
  14010.    if (!alive(©, i, j)) {
  14011.       (*io->notifyError) ("That move is suicide.");
  14012.       islegal = false;
  14013.    }
  14014.    if (islegal && (n = n->parent)) {
  14015.       boardClear(&a);
  14016.       buildTree0(n, &a);
  14017.       same = true;
  14018.       for (x = boardsize; same && x--;)
  14019.      for (y = boardsize; same && y--;) {
  14020.         same = (copy.b[x][y] == a.b[x][y]);
  14021.      }
  14022.       if (same) {
  14023.      (*io->notifyError) ("Can't retake the ko yet.");
  14024.      islegal = false;
  14025.       }
  14026.    }
  14027.    xcur = savex;
  14028.    ycur = savey;
  14029.    prisoners[0] = savepris[0];
  14030.    moveNum = savemove;
  14031.    prisoners[1] = savepris[1];
  14032.  
  14033.    return islegal;
  14034. }
  14035.  
  14036.  
  14037.  
  14038.  
  14039. FUNCTION boolean inRange(i, j)
  14040. {
  14041.    return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
  14042. }
  14043.  
  14044. FUNCTION boolean alive0(b, m, i, j, t)
  14045. pBoard b;
  14046. pBoard m;
  14047. int i, j;
  14048. piece t;
  14049. {
  14050.    piece pt;
  14051.  
  14052.    pt = b->b[i][j];
  14053.    if ((pt != P_NOTHING && pt != t) || m->b[i][j] != P_NOTHING)
  14054.       return 0;
  14055.    m->b[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
  14056.    if (pt == P_NOTHING)
  14057.       return 1;
  14058.    return
  14059.       (j < boardsize - 1 && alive0(b, m, i, j + 1, t)) ||
  14060.       (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) ||
  14061.       (i && alive0(b, m, i - 1, j, t)) ||
  14062.       (j && alive0(b, m, i, j - 1, t));
  14063. }
  14064.  
  14065. FUNCTION boolean alive(b, i, j)    /* Does group at i,j have liberties? */
  14066. pBoard b;
  14067. int i, j;
  14068. {
  14069.    board m;
  14070.  
  14071.    boardClear(&m);
  14072.    return alive0(b, &m, i, j, b->b[i][j]);
  14073. }
  14074.  
  14075. void removeStones0(b, i, j, t)
  14076. pBoard b;
  14077. int i, j;
  14078. piece t;
  14079. {
  14080.    extern int prisoners[];
  14081.  
  14082.    if (b->b[i][j] != t)
  14083.       return;
  14084.    b->b[i][j] = P_NOTHING;
  14085.    prisoners[(int) t - 1]++;
  14086.    if (j < boardsize - 1)
  14087.       removeStones0(b, i, j + 1, t);
  14088.    if (i < boardsize - 1)
  14089.       removeStones0(b, i + 1, j, t);
  14090.    if (i)
  14091.       removeStones0(b, i - 1, j, t);
  14092.    if (j)
  14093.       removeStones0(b, i, j - 1, t);
  14094. }
  14095.  
  14096.  
  14097.  
  14098. FUNCTION void removeStones(b, i, j)
  14099. pBoard b;
  14100. int i, j;
  14101. {
  14102.    removeStones0(b, i, j, b->b[i][j]);
  14103. }
  14104.  
  14105. FUNCTION boolean tryKill(b, i, j, t)
  14106. pBoard b;
  14107. int i, j;
  14108. piece t;
  14109. {
  14110.    piece w;
  14111.    if (!inRange(i, j))
  14112.       return false;
  14113.    w = b->b[i][j];
  14114.    if (w != P_NOTHING && w != t && !alive(b, i, j)) {
  14115.       removeStones(b, i, j);
  14116.       return true;
  14117.    }
  14118.    return false;
  14119. }
  14120.  
  14121. FUNCTION void placeStone(b, i, j, t)
  14122. pBoard b;
  14123. int i, j;
  14124. piece t;
  14125. {
  14126.    if (inRange(i, j)) {
  14127.       b->b[i][j] = t;
  14128.       xcur = i;
  14129.       ycur = j;
  14130.       if (j)
  14131.      tryKill(b, i, j - 1, t);
  14132.       if (j < boardsize - 1)
  14133.      tryKill(b, i, j + 1, t);
  14134.       if (i)
  14135.      tryKill(b, i - 1, j, t);
  14136.       if (i < boardsize - 1)
  14137.      tryKill(b, i + 1, j, t);
  14138.    }
  14139. }
  14140.  
  14141. FUNCTION void boardSet(b, i, j, p)
  14142. pBoard b;
  14143. int i, j;
  14144. piece p;
  14145. {
  14146.    b->b[i][j] = p;
  14147. }
  14148.  
  14149. FUNCTION piece boardGet(b, i, j)
  14150. pBoard b;
  14151. int i, j;
  14152. {
  14153.    return b->b[i][j];
  14154. }
  14155.  
  14156.  
  14157. FUNCTION void boardClear(b)
  14158. pBoard b;
  14159. {
  14160.    memset((char *) (b->b), 0, 361 * sizeof(piece));
  14161.  
  14162.    /* int i, j; for (i = boardsize; i--;) for (j = boardsize; j--;) b->b[i][j]
  14163.     * = P_NOTHING; */
  14164. }
  14165.  
  14166. FUNCTION void copyBoard(a, b)
  14167. pBoard a, b;
  14168. {
  14169.    int i, j;
  14170.    for (i = boardsize; i--;)
  14171.       for (j = boardsize; j--;)
  14172.      b->b[i][j] = a->b[i][j];
  14173. }
  14174.  
  14175.  
  14176. int look(stone, array, index, i)
  14177. int stone, array[], *index, i;
  14178. {
  14179.    if (stone == P_NOTHING)
  14180.       array[(*index)++] = i;
  14181.    else if (stone == P_BLACK)
  14182.       return 1;
  14183.    else if (stone == P_WHITE)
  14184.       return 2;
  14185.    return 0;
  14186. }
  14187.  
  14188.  
  14189. int fillregion(b, x, y)
  14190. pBoard b;
  14191. int x, y;
  14192. {
  14193.    int goup[19], godown[19], up = 0, down = 0, found = 0, i;
  14194.  
  14195.    for (i = x; i < boardsize && b->b[i][y] == P_NOTHING; i++) {
  14196.       b->b[i][y] = P_CHECKED;
  14197.       if (y > 0)
  14198.      found |= look(b->b[i][y - 1], goup, &up, i);
  14199.       if (y < boardsize - 1)
  14200.      found |= look(b->b[i][y + 1], godown, &down, i);
  14201.    }
  14202.    if (i != boardsize) {
  14203.       if (b->b[i][y] == P_BLACK)
  14204.      found |= 1;
  14205.       if (b->b[i][y] == P_WHITE)
  14206.      found |= 2;
  14207.    }
  14208.    for (i = x - 1; i >= 0 && b->b[i][y] == P_NOTHING; i--) {
  14209.       b->b[i][y] = P_CHECKED;
  14210.       if (y > 0)
  14211.      found |= look(b->b[i][y - 1], goup, &up, i);
  14212.       if (y < boardsize - 1)
  14213.      found |= look(b->b[i][y + 1], godown, &down, i);
  14214.    }
  14215.    if (i != -1) {
  14216.       if (b->b[i][y] == P_BLACK)
  14217.      found |= 1;
  14218.       if (b->b[i][y] == P_WHITE)
  14219.      found |= 2;
  14220.    }
  14221.    while (up)
  14222.       found |= fillregion(b, goup[--up], y - 1);
  14223.    while (down)
  14224.       found |= fillregion(b, godown[--down], y + 1);
  14225.    return found;
  14226. }
  14227.  
  14228.  
  14229. FUNCTION void scoreBoard(b, score)
  14230. pBoard b;
  14231. int score[];
  14232. {
  14233.    int x, y, i, j, owner;
  14234.    piece newval;
  14235.  
  14236.    score[0] = 0;
  14237.    score[1] = 0;
  14238.    for (i = 0; i < boardsize; i++)
  14239.       for (j = 0; j < boardsize; j++) {
  14240.      owner = fillregion(b, i, j);
  14241.      if (!owner)
  14242.         owner = 3;
  14243.      switch (owner) {
  14244.         case 3:
  14245.            newval = P_DAME;
  14246.            break;
  14247.         case 2:
  14248.            newval = P_WHITETERR;
  14249.            break;
  14250.         case 1:
  14251.            newval = P_BLACKTERR;
  14252.            break;
  14253.      }
  14254.      for (x = 0; x < boardsize; x++)
  14255.         for (y = 0; y < boardsize; y++)
  14256.            if (b->b[x][y] == P_CHECKED) {
  14257.           b->b[x][y] = newval;
  14258.           if (owner != 3)
  14259.              score[owner - 1]++;
  14260.            }
  14261.       }
  14262. }
  14263. SHAR_EOF
  14264. fi
  14265. if test -f 'proto.h'
  14266. then
  14267.     echo shar: "will not over-write existing file 'proto.h'"
  14268. else
  14269. cat << \SHAR_EOF > 'proto.h'
  14270. extern void clearLast();
  14271. extern void highlightLast();
  14272. extern void doPlace();
  14273. extern void doProps();
  14274. extern void doPropComment();
  14275. extern void buildTree0();
  14276. extern void buildTree();
  14277. extern void setPiece();
  14278. extern void updateBoard();
  14279. extern char *commentGet();    /* int */
  14280. extern int commentLines();
  14281. extern void formatComment();
  14282. extern int okChange();
  14283. extern int okExit();
  14284. extern nodep search();        /* return 0 on failure */
  14285. extern void step();
  14286. extern void stepDown();
  14287. extern void doScore();
  14288. extern nodep loadFile();
  14289. extern nodep makeTutor();
  14290. extern void doit();
  14291. extern void writeStrEscaped();
  14292. extern void writeNode();
  14293. extern void WriteSubTree();
  14294. extern int writeCoordList();
  14295. extern int writeTree();
  14296. extern int addMark();
  14297. extern void addStone();
  14298. extern int makeMove();
  14299. extern int passMove();
  14300. extern void addPlayer();
  14301. extern void makeVariation();
  14302. extern void cutTree();
  14303. extern boolean pasteTree();
  14304. extern void edComment();
  14305. extern void deleteNode();
  14306. extern void makeName();
  14307. extern void replaceComment();
  14308. extern main();
  14309. extern void die();
  14310. extern void myexit();
  14311. extern void openfile();
  14312. extern void barf();
  14313. extern void initEnv();
  14314. extern void init();
  14315. extern void helpCommandLine();
  14316. extern void parseLine();
  14317. extern void readInit();
  14318. extern void addChild();        /* add child c to node n */
  14319. extern nodep parse();
  14320. extern int legal();
  14321. extern boolean inRange();
  14322. extern boolean alive0();
  14323. extern boolean alive();        /* Does group at i,j have liberties? */
  14324. extern void removeStones();
  14325. extern boolean tryKill();
  14326. extern void placeStone();
  14327. extern void boardSet();
  14328. extern piece boardGet();
  14329. extern void boardClear();
  14330. extern void copyBoard();
  14331. extern void scoreBoard();
  14332. extern boolean getCoord();
  14333. extern coordList *addCoord();
  14334. extern void setCoord();
  14335. extern void clearCoord();
  14336. extern void initNodes();
  14337. extern nodep newNode();
  14338. extern void freeNode();
  14339. extern char *dupStr();
  14340. extern void freeProps();
  14341. extern void delNode();
  14342. extern void addprop();
  14343. extern property *getprop();
  14344. extern int treeCountSiblings();
  14345. extern nodep nthChild();    /* nodep, int */
  14346. extern nodep parent();
  14347. extern nodep child();
  14348. extern nodep lastSibling();
  14349. extern nodep nextSibling();
  14350. extern nodep treeLastSibling();
  14351. extern nodep treeDown();
  14352. extern nodep treeUp();
  14353. extern nodep treeNextUp();
  14354. extern nodep treeNext();
  14355. extern nodep lastChildOfLastSibling();
  14356. extern nodep treeLast();
  14357. SHAR_EOF
  14358. fi
  14359. if test -f 'shared.h'
  14360. then
  14361.     echo shar: "will not over-write existing file 'shared.h'"
  14362. else
  14363. cat << \SHAR_EOF > 'shared.h'
  14364. /* shared.h
  14365.  * S.Coffin  USWAT   1/93
  14366.  *
  14367.  * bits for compatibility with the IGS
  14368.  *
  14369.  * adapted from tcasey@leo.unm.edu
  14370.  */
  14371.  
  14372. #ifndef SHARED_H
  14373. #define SHARED_H
  14374.  
  14375. #define MAX_BRD_SZ 25
  14376.  
  14377. typedef enum {
  14378.     UNKNOWN    =  0,
  14379.     BEEP    =  2,     /* \7 telnet         */
  14380.     BOARD    =  3,    /* Board being drawn     */
  14381.     DOWN    =  4,    /* The server is going down */
  14382.     ERROR    =  5,    /* An error reported    */
  14383.           FIL    =  6,    /* File being sent    */
  14384.     GAMES    =  7,    /* Games listing    */
  14385.           HELP    =  8,    /* Help file        */
  14386.     INFO    =  9,    /* Generic info        */
  14387.     LAST    = 10,    /* Last command        */
  14388.           KIBITZ    = 11,    /* Kibitz strings    */
  14389.     LOAD    = 12,    /* Loading a game    */
  14390.     LOOK_M    = 13,    /* Look         */
  14391.           MESSAGE    = 14,    /* Message lising    */
  14392.           MOVE    = 15,    /* Move #:(B) A1    */
  14393.     OBSERVE    = 16,    /* Observe report    */
  14394.           PROMPT    =  1,    /* A Prompt (never)    */
  14395.     REFRESH    = 17,    /* Refresh of a board    */
  14396.           SAVED    = 18,    /* Stored command    */
  14397.           SAY    = 19,    /* Say string        */
  14398.           SCORE    = 20,    /* Score report        */
  14399.           SHOUT    = 21,    /* Shout string        */
  14400.           STATUS    = 22,    /* Current Game status    */
  14401.     STORED    = 23,    /* Stored games        */
  14402.           TELL    = 24,    /* Tell string        */
  14403.     THIST    = 25,    /* Thist report        */
  14404.     TIM    = 26,    /* times command    */
  14405.     WHO    = 27,    /* who command        */
  14406.     UNDO    = 28,    /* Undo report        */
  14407.     SHOW    = 29,
  14408.     TRANS   = 30   /* Translation info     <=== last value */
  14409. } MessageType;
  14410.  
  14411. #define LOGGEDON WAITING
  14412. typedef enum {
  14413.     LOGON        = 0,
  14414.     PASSWORD    = 1,
  14415.     PASSWD_NEW    = 2,
  14416.     PASSWD_CONFIRM    = 3, 
  14417.     REGISTER    = 4, 
  14418.     WAITING        = 5,
  14419.     PLAYING        = 6,
  14420.     SCORING        = 7,
  14421.     OBSERVING    = 8
  14422. } State;
  14423.  
  14424. #define NUM_RANKS num_ranks
  14425. #define NUM_SPECIAL 2
  14426.  
  14427. /*
  14428.  * verticies
  14429.  */
  14430. #define TOP 0
  14431. #define MID 1
  14432. #define BOT 2
  14433.  
  14434. #endif /* SHARED_H */
  14435. SHAR_EOF
  14436. fi
  14437. if test -f 'tree.c'
  14438. then
  14439.     echo shar: "will not over-write existing file 'tree.c'"
  14440. else
  14441. cat << \SHAR_EOF > 'tree.c'
  14442. /* "mgt" Copyright (c) 1991 Shodan  */
  14443.  
  14444. #include "mgt.h"
  14445.  
  14446.  
  14447. static int newNodeNum;
  14448.  
  14449.  
  14450. FUNCTION boolean getCoord(x, y, list)
  14451. int x, y;
  14452. coordList *list;
  14453. {
  14454.    for (; list; list = list->next)
  14455.       if (list->x == x && list->y == y)
  14456.      return true;
  14457.    return false;
  14458. }
  14459.  
  14460.  
  14461.  
  14462. FUNCTION coordList *addCoord(x, y)
  14463. int x, y;
  14464. {
  14465.    coordList *co;
  14466.  
  14467.    if (!(co = (coordList *) malloc(sizeof(coordList))))
  14468.       barf("Memory allocation failure (addCoord)");
  14469.    co->next = 0;
  14470.    co->x = x;
  14471.    co->y = y;
  14472.    return co;
  14473. }
  14474.  
  14475.  
  14476.  
  14477. FUNCTION void setCoord(x, y, startlist)
  14478. int x, y;
  14479. coordList **startlist;
  14480. {
  14481.    coordList *list;
  14482.    if (!*startlist)
  14483.       *startlist = addCoord(x, y);
  14484.    else {
  14485.       for (list = *startlist; list->next; list = list->next)
  14486.      if (x == list->x && y == list->y)
  14487.         return;
  14488.       list->next = addCoord(x, y);
  14489.    }
  14490. }
  14491.  
  14492.  
  14493. FUNCTION void clearCoord(x, y, startlist)
  14494. int x, y;
  14495. coordList **startlist;
  14496.  
  14497. {
  14498.    coordList *last, *list;
  14499.  
  14500.    last = 0;
  14501.    list = *startlist;
  14502.    while (list && (x != list->x || y != list->y)) {
  14503.       last = list;
  14504.       list = list->next;
  14505.    }
  14506.    if (list) {
  14507.       if (last)
  14508.      last->next = list->next;
  14509.       else
  14510.      *startlist = list->next;
  14511.       free(list);
  14512.    }
  14513. }
  14514.  
  14515.  
  14516. FUNCTION void initNodes()
  14517. {
  14518.    newNodeNum = 0;
  14519. }
  14520.  
  14521. FUNCTION nodep newNode()
  14522. {
  14523.    nodep new;
  14524. #ifdef DEBUG
  14525.    totalmemory += sizeof(node);
  14526.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  14527. #endif
  14528.    new = (nodep) calloc(1, sizeof(node));
  14529.    if (!new)
  14530.       barf("Memory allocation failure (newnode)");
  14531.    new->nodeNum = newNodeNum++;
  14532.    return new;
  14533. }
  14534.  
  14535. FUNCTION void freeNode(n)
  14536. nodep n;
  14537. {
  14538.    if (n) {
  14539.       freeNode(n->nextSibling);
  14540.       freeNode(n->child);
  14541.       delNode(n);
  14542.    }
  14543. }
  14544.  
  14545. FUNCTION char *dupStr(s)
  14546. char *s;
  14547. {
  14548.    char *c;
  14549. #ifdef DEBUG
  14550.    totalmemory += strlen(s) + 1;
  14551.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  14552. #endif
  14553.    c = (char *) malloc((unsigned) strlen(s) + 1);
  14554.    if (!c)
  14555.       barf("Memory allocation failure (dupstr)");
  14556.    strcpy(c, s);
  14557.    return c;
  14558. }
  14559.  
  14560.  
  14561.  
  14562. FUNCTION void freeProps(n)
  14563. nodep n;
  14564. {
  14565.    property *prop, *lastprop;
  14566.    coordList *cl, *lastcl;
  14567.    prop = n->p;
  14568.    while (prop) {
  14569.       switch (prop->t) {
  14570.      case t_AddEmpty:
  14571.      case t_AddBlack:
  14572.      case t_AddWhite:
  14573.      case t_Mark:
  14574.      case t_Letter:
  14575.      case t_Black:
  14576.      case t_White:
  14577.         cl = prop->data.stones;
  14578.         while (cl) {
  14579.            lastcl = cl;
  14580.            cl = cl->next;
  14581.            free(lastcl);
  14582.         }
  14583.         break;
  14584.      case t_Name:
  14585.      case t_Comment:
  14586.         free(prop->data.comment);
  14587.         break;
  14588.  
  14589.       }
  14590.  
  14591.       lastprop = prop;
  14592.       prop = prop->next;
  14593.       free(lastprop);
  14594.    }
  14595. }
  14596.  
  14597.  
  14598. FUNCTION void delNode(n)
  14599. nodep n;
  14600. {
  14601.    freeProps(n);
  14602.    free(n);
  14603. }
  14604.  
  14605. FUNCTION void addprop(n, p)
  14606. nodep n;
  14607. property *p;
  14608. {
  14609.    p->next = n->p;
  14610.    n->p = p;
  14611. }
  14612.  
  14613. FUNCTION property *getprop(n, t)
  14614. nodep n;
  14615. Token t;
  14616. {
  14617.    property *p;
  14618.    p = n->p;
  14619.    while (p && p->t != t)
  14620.       p = p->next;
  14621.    return p;
  14622. }
  14623.  
  14624. FUNCTION int treeCountSiblings(n)
  14625. nodep n;
  14626. {
  14627.    int i;
  14628.    nodep n1;
  14629.  
  14630.    n1 = n->child;
  14631.    i = 0;
  14632.    while (n1) {
  14633.       n1 = n1->nextSibling;
  14634.       i++;
  14635.    }
  14636.    return i;
  14637. }
  14638.  
  14639. FUNCTION nodep nthChild(n, c)    /* nodep, int */
  14640. nodep n;
  14641. int c;
  14642. {
  14643.  
  14644.    if (n->child) {
  14645.       n = child(n);
  14646.       while (c-- && n)
  14647.      n = nextSibling(n);
  14648.    } else {
  14649.       n = 0;
  14650.    }
  14651.    return n;
  14652. }
  14653.  
  14654. /* TREE WALK functions KEEP TRACK OF DEPTH AS WELL */
  14655.  
  14656. FUNCTION nodep parent(n)
  14657. nodep n;
  14658. {
  14659.    return n->parent;
  14660. }
  14661.  
  14662. FUNCTION nodep child(n)
  14663. nodep n;
  14664. {
  14665.    return n->child;
  14666. }
  14667.  
  14668. FUNCTION nodep lastSibling(n)
  14669. nodep n;
  14670. {
  14671.    return n->lastSibling;
  14672. }
  14673.  
  14674. FUNCTION nodep nextSibling(n)
  14675. nodep n;
  14676. {
  14677.    return n->nextSibling;
  14678. }
  14679.  
  14680. FUNCTION nodep treeLastSibling(n)
  14681. nodep n;
  14682. {
  14683.    while (n->nextSibling) {
  14684.       n = n->nextSibling;
  14685.    }
  14686.    return n;
  14687. }
  14688.  
  14689. /* go to next node down the tree. Stop if at bottom. */
  14690. FUNCTION nodep treeDown(n)
  14691. nodep n;
  14692. {
  14693.    if (n->child) {
  14694.       BUG("treeDown: going down\n");
  14695.       return child(n);
  14696.    } else {
  14697.       BUG("treeDown: stop\n");
  14698.       return n;
  14699.    }
  14700. }
  14701.  
  14702. /* backup, stop if at top */
  14703. FUNCTION nodep treeUp(n)
  14704. nodep n;
  14705. {
  14706.    if (n->parent) {
  14707.       BUG("treeUp: going up\n");
  14708.       return parent(n);
  14709.    } else {
  14710.       BUG("treeUp: staying\n");
  14711.       return n;
  14712.    }
  14713. }
  14714.  
  14715.  
  14716. /* go to next node backing up the tree only */
  14717. FUNCTION nodep treeNextUp(n)
  14718. nodep n;
  14719. {
  14720.    if (n->nextSibling) {
  14721.       BUG("nextSibling ");
  14722.       return nextSibling(n);
  14723.    } else if (n->parent) {
  14724.       BUG("nextup-parent ");
  14725.       while (n->parent && !n->nextSibling)
  14726.      n = parent(n);
  14727.       if (n->nextSibling)
  14728.      return nextSibling(n);
  14729.       else
  14730.      return n;
  14731.    } else if (n->child) {
  14732.       BUG("child ");
  14733.       return child(n);
  14734.    } else {
  14735.       BUG("current ");
  14736.       return n;
  14737.    }
  14738. }
  14739.  
  14740.  
  14741. /* go to next node, backup if neccessary */
  14742. FUNCTION nodep treeNext(n)
  14743. nodep n;
  14744. {
  14745.    nodep r;
  14746.  
  14747.    BUG("treeNext:");
  14748.    if (n != (r = treeDown(n))) {
  14749.       BUG("going down ");
  14750.    } else {
  14751.       BUG("going up ");
  14752.       r = treeNextUp(n);
  14753.    }
  14754.    BUG("\n");
  14755.    return r;
  14756. }
  14757.  
  14758.  
  14759.  
  14760. FUNCTION nodep lastChildOfLastSibling(n)
  14761. nodep n;
  14762. {
  14763.  
  14764.    while (n->nextSibling)
  14765.       n = nextSibling(n);
  14766.    if (n->child)
  14767.       return lastChildOfLastSibling(child(n));
  14768.    else
  14769.       return n;
  14770. }
  14771.  
  14772. /* go to next node, backup if neccessary */
  14773. FUNCTION nodep treeLast(n)
  14774. nodep n;
  14775. {
  14776.    nodep r;
  14777.  
  14778.    if (n->lastSibling) {
  14779.       n = lastSibling(n);
  14780.       if (n->child)
  14781.      r = lastChildOfLastSibling(child(n));
  14782.       else
  14783.      r = n;
  14784.    } else if (n->parent) {
  14785.       r = parent(n);
  14786.    } else if (n->child) {
  14787.       r = lastChildOfLastSibling(child(n));
  14788.    } else {
  14789.       r = n;
  14790.    }
  14791.    return r;
  14792. }
  14793. SHAR_EOF
  14794. fi
  14795. if test -f 'wrapmgt.6'
  14796. then
  14797.     echo shar: "will not over-write existing file 'wrapmgt.6'"
  14798. else
  14799. cat << \SHAR_EOF > 'wrapmgt.6'
  14800. .TH WRAPMGT 6  "23 November 1992"
  14801. .SH NAME
  14802. wrapmgt - wraps long lines in Smart-Go files to make them safe to post
  14803. or email
  14804. .SH SYNOPSIS
  14805. .B wrapmgt [nn]
  14806. .SH DESCRIPTION
  14807. .B Wrapmgt
  14808. formats Smart-Go files as generated by
  14809. .B mgt
  14810. so that the lines are shorter than nn, the number specified on the
  14811. command line.  The default format width is 79 characters.
  14812. .B Wrapmgt
  14813. reads its input from stdin and writes to stdout.  This means you
  14814. should invoke it using I/O redirection which is done under unix and
  14815. DOS with wrapmgt < infile > outfile.
  14816. .LP
  14817. The files are formatted in such a way that if the files are viewed in
  14818. mgt after being formatted, they will look the same as the original.
  14819. The new line breaks will be visible from
  14820. within the editor, however. 
  14821. .SH AUTHOR
  14822. Adrian Mariano (adrian@u.washington.edu)
  14823.  
  14824. SHAR_EOF
  14825. fi
  14826. if test -f 'wrapmgt.c'
  14827. then
  14828.     echo shar: "will not over-write existing file 'wrapmgt.c'"
  14829. else
  14830. cat << \SHAR_EOF > 'wrapmgt.c'
  14831. #include<stdio.h>
  14832.  
  14833. main(argc,argv)
  14834. int argc;
  14835. char *argv[];
  14836. {
  14837.   char *last,line[100];
  14838.   int cur,limit;
  14839.   int intext,incomment;
  14840.  
  14841.   limit=79;
  14842.  
  14843.   if (argc>2){
  14844.     fprintf(stderr,"Wrong number of arguments.\n\n");
  14845.     exit(1);
  14846.   }
  14847.   if (argc==2){
  14848.     limit=atoi(argv[1]);
  14849.     if (!limit){
  14850.       fprintf(stderr,"Invalid limit\n\n");
  14851.       exit(2);
  14852.     }
  14853.   }
  14854.   last=0;
  14855.   cur=0;
  14856.   intext=0;
  14857.   incomment=0;
  14858.   
  14859.  
  14860.   do{
  14861.     line[cur]=getchar();
  14862.  
  14863. /* This next line makes the program aggressively eat up white space  */
  14864. /* found outside the text sections */
  14865.  
  14866.     if (!intext && 
  14867.       (line[cur]==' ' || line[cur]=='\n' || line[cur]=='\r'))
  14868.       continue;
  14869.  
  14870. /* These tests come first because they don't look at the current character */
  14871. /* They need to be checked before the flags (next section) are reset */
  14872.  
  14873.       /* line breaks at spaces within comments only */
  14874.     if (incomment && cur && line[cur-1]==' ') last= &line[cur];
  14875.  
  14876.       /* line breaks at after ']' if followed by capital letter */
  14877.     if (!intext && cur>2 && line[cur-1]>='A' && line[cur-1]<='Z' &&
  14878.           line[cur-2]==']' && line[cur-3]!='\\') last= &line[cur-1];
  14879.  
  14880. /* These change the various flags */
  14881.  
  14882.       /* Check for start of comment 'C[' */
  14883.     if (cur && line[cur-1]=='C' && line[cur]=='[') incomment=intext=1;
  14884.  
  14885.       /* Check for start of non-comment bracketed section */
  14886.     if (line[cur]=='[' && (cur==0 || line[cur-1]!='\\')) intext=1;
  14887.  
  14888.       /* check for end of bracketed sections ']' */
  14889.     if (intext && line[cur]==']' && (cur==0 || line[cur-1]!='\\')) 
  14890.       intext=incomment=0;
  14891.  
  14892. /* This test does use current character */
  14893.  
  14894.       /* line breaks at ';' outside of text */
  14895.     if (!intext && line[cur]==';') last= &line[cur];
  14896.  
  14897.        
  14898.     if (line[cur]=='\n'){
  14899.       line[cur+1]=0;
  14900.       fputs(line,stdout);
  14901.       last=line;
  14902.       cur= -1;
  14903.     }
  14904.     cur++;
  14905.     if (cur>=limit && last){
  14906.       char *loc,*end;
  14907.       for(loc=line;loc<last;loc++) putchar(*loc);
  14908.       putchar('\n');
  14909.       loc=line;
  14910.       line[cur]=0;
  14911.       strcpy(line,last);
  14912.       last=0;
  14913.       cur=strlen(line);
  14914.     }
  14915.   }while(!feof(stdin));
  14916.   line[cur]=0;
  14917.   fputs(line,stdout);
  14918. }  
  14919.       
  14920.       
  14921.  
  14922. SHAR_EOF
  14923. fi
  14924. if test -f 'x11.4.c'
  14925. then
  14926.     echo shar: "will not over-write existing file 'x11.4.c'"
  14927. else
  14928. cat << \SHAR_EOF > 'x11.4.c'
  14929. /*  x11.4.c
  14930.  *
  14931.  *  Copyright (c) 1992 by Chien-Min Wang and Tim Casey.
  14932.  *  All rights reserved.
  14933.  */
  14934.  
  14935. #include <stdio.h>
  14936. #include <math.h>
  14937. #include <assert.h>
  14938. #include <X11/Xlib.h>
  14939. #include <X11/Intrinsic.h>
  14940. #include <X11/StringDefs.h>
  14941. #include <X11/Shell.h>
  14942. #include <X11/bitmaps/xlogo11>
  14943. #include <X11/Xaw/MenuButton.h>
  14944. #include <X11/Xaw/SimpleMenu.h>
  14945. #include <X11/Xaw/SmeBSB.h>
  14946. #include <X11/Xaw/SmeLine.h>
  14947. #include <X11/Xaw/Command.h>
  14948. #include <X11/Xaw/Form.h>
  14949. #include <X11/Xaw/AsciiText.h>
  14950. #include <X11/Xaw/Viewport.h>
  14951. #include "Board.h"
  14952. #include "mgt.h"
  14953. #include "xutil.h"
  14954.  
  14955. #define INDEX_TO_POS(n)    (boardsize-1-(n))
  14956. #define NEXTSIBLING(n)    ((n)->nextSibling)
  14957. #define EMPTY_STR    ""
  14958. #define MAX_VARS    26
  14959. #define BUF_SIZE    200
  14960.  
  14961. Res reses;
  14962. ResPtr resp = &reses;
  14963.  
  14964. XtResource resources[] = {
  14965. #define offset(field)   XtOffset(ResPtr,field)
  14966. #define DefaultFont    "-misc-fixed-bold-r-*-*-13-*-*-*-*-70-*-*"
  14967. #define FontWidth    7
  14968.     { "commHeight", "CommHeight", XtRInt, sizeof(int),
  14969.        offset(comm_ht), XtRImmediate, (caddr_t) 500 },
  14970.     { "commWidth", "CommWidth", XtRInt, sizeof(int),
  14971.        offset(comm_wd), XtRImmediate, (caddr_t) 656 },
  14972.     { "noteHeight", "NoteHeight", XtRInt, sizeof(int),
  14973.        offset(note_ht), XtRImmediate, (caddr_t) 20 },
  14974.     { "noteWidth", "NoteWidth", XtRInt, sizeof(int),
  14975.        offset(note_wd), XtRImmediate, (caddr_t) 674 },
  14976.     { "variationWidth", "VariationWidth", XtRInt, sizeof(int),
  14977.        offset(var_wd), XtRImmediate, (caddr_t) 300 },
  14978.     { "menuWidth", "MenuWidth", XtRInt, sizeof(int),
  14979.        offset(men_wd), XtRImmediate, (caddr_t) 130 },
  14980.     { "buttonWidth", "ButtonWidth", XtRInt, sizeof(int),
  14981.        offset(but_wd), XtRImmediate, (caddr_t) 164 },
  14982.     { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  14983.        offset(fptr), XtRString, DefaultFont }
  14984. };
  14985.  
  14986. XtAppContext app_context;
  14987.  
  14988. extern int madechanges;
  14989. extern void exit();
  14990.  
  14991. static Widget toplevel, brd, notify, comm, buts, vars, title;
  14992. static Pixmap mark;
  14993. static int move_x = -1, move_y = -1;
  14994. static int theCommand, AmHelping;
  14995. static XtActionProc HandleKeyDown();
  14996. static void SetCommand(), HandleScoring(), DoVariation(), ShowCaptured();
  14997. static void notifyMessage();
  14998. static void notifyClear();
  14999. static void HandleHelp(), HelpCommand();
  15000. static char comment_backup[MAXCOMMENT];
  15001.  
  15002. static String menu_name[] = {
  15003.     "File",
  15004.     "Edit",
  15005.     "Score",
  15006.     "Others",
  15007.     "Help",
  15008.     0    /* sentinel */
  15009. };
  15010.  
  15011. static Buttons menu_entry[] = {
  15012.     {"Load File",         (char *)SetCommand, (caddr_t)C_LOAD },
  15013.     {"Save File",        (char *)SetCommand, (caddr_t)C_WRITE },
  15014.     {"Next File",         (char *)SetCommand, (caddr_t)C_NEXTFILE },
  15015.     {"Back File",        (char *)SetCommand, (caddr_t)C_BACKFILE },
  15016.     {"Save Short",         (char *)SetCommand, (caddr_t)C_SAVESHORT },
  15017.     {"Save Screen",     (char *)SetCommand, (caddr_t)C_SAVESCREEN },
  15018.     {"Quit",         (char *)SetCommand, (caddr_t)C_QUIT },
  15019.     {0, NULL, 0},    /* sentinel */
  15020.     {"Add Black",         (char *)SetCommand, (caddr_t)C_ADDBLACK },
  15021.     {"Add White",         (char *)SetCommand, (caddr_t)C_ADDWHITE },
  15022.     {"Add Letter",         (char *)SetCommand, (caddr_t)C_ADDLETTER },
  15023.     {"Add Mark",         (char *)SetCommand, (caddr_t)C_ADDMARK },
  15024.     {"Add Name",         (char *)SetCommand, (caddr_t)C_ADDNAME },
  15025.     {"Add Variation",    (char *)SetCommand, (caddr_t)C_ADDVAR },
  15026.     {"Edit Comment",    (char *)SetCommand, (caddr_t)C_EDCOMMENT },
  15027.     {"Delete Node",     (char *)SetCommand, (caddr_t)C_DELNODE },
  15028.     {"Cut Tree",         (char *)SetCommand, (caddr_t)C_TREECUT },
  15029.     {"Paste",         (char *)SetCommand, (caddr_t)C_PASTE },
  15030.     {0, NULL, 0},    /* sentinel */
  15031.     {"Start Scoring",     (char *)HandleScoring, (caddr_t)C_SCORE },
  15032.     {"Remove Dead Group",     (char *)HandleScoring, (caddr_t)C_MOVE },
  15033.     {"Abandon Removals",     (char *)HandleScoring, (caddr_t)C_UNDO },
  15034.     {"Quit Scoring",     (char *)HandleScoring, (caddr_t)C_QUIT },
  15035.     {0, NULL, 0},    /* sentinel */
  15036.     {"Move",         (char *)SetCommand, (caddr_t)C_MOVE },
  15037.     {"Pass",         (char *)SetCommand, (caddr_t)C_PASSMOVE },
  15038.     {"Redraw",         (char *)SetCommand, (caddr_t)C_REDRAW },
  15039.     {"Toggle Color",     (char *)SetCommand, (caddr_t)C_TOGGLESTONE },
  15040.     {"Play",         (char *)SetCommand, (caddr_t)C_TOPLAY },
  15041.     {"Tutor Swap",         (char *)SetCommand, (caddr_t)C_TUTORSWAP },
  15042.     {"Information",     (char *)SetCommand, (caddr_t)C_INFO },
  15043.     {0, NULL, 0},    /* sentinel */
  15044.     {"On Short",         (char *)HandleHelp,  (caddr_t)1 },
  15045.     {"On Long",         (char *)HandleHelp,  (caddr_t)3 }, /* use next bit */
  15046.     {"Off",         (char *)HandleHelp,(caddr_t)0 },
  15047.     {0, NULL, 0}    /* sentinel */
  15048. };
  15049.  
  15050. static Buttons buttons[] = {
  15051.     {"Move Forward",     (char *)SetCommand, (caddr_t)C_DOWN },
  15052.     {"Move Backward",     (char *)SetCommand, (caddr_t)C_UP },
  15053.     {"Next Node",         (char *)SetCommand, (caddr_t)C_WALKDOWN },
  15054.     {"Previous Node",     (char *)SetCommand, (caddr_t)C_WALKUP },
  15055.     {"Next Comment",     (char *)SetCommand, (caddr_t)C_SEARCHCOMMENT },
  15056.     {"Previous Comment", (char *)SetCommand, (caddr_t)C_SEARCHBACKCOMMENT },
  15057.     {"Next Variation",     (char *)SetCommand, (caddr_t)C_DOWNFORK },
  15058.     {"Previous Variation",     (char *)SetCommand, (caddr_t)C_UPFORK },
  15059.     {"End Variation",     (char *)SetCommand, (caddr_t)C_END },
  15060.     {"Beginning Variation", (char *)SetCommand, (caddr_t)C_BEGINNING },
  15061.     {"Go to Node",         (char *)SetCommand, (caddr_t)C_GOTO },
  15062.     {0, NULL, 0}, /* sentinel */
  15063. };
  15064.  
  15065. static Buttons variations[MAX_VARS] = {
  15066.     {"unused",     (char *)DoVariation, (caddr_t)0 },
  15067.     {"unused",     (char *)DoVariation, (caddr_t)1 },
  15068.     {"unused",     (char *)DoVariation, (caddr_t)2 },
  15069.     {"unused",     (char *)DoVariation, (caddr_t)3 },
  15070.     {"unused",     (char *)DoVariation, (caddr_t)4 },
  15071.     {"unused",     (char *)DoVariation, (caddr_t)5 },
  15072.     {"unused",     (char *)DoVariation, (caddr_t)6 },
  15073.     {"unused",     (char *)DoVariation, (caddr_t)7 },
  15074.     {"unused",     (char *)DoVariation, (caddr_t)8 },
  15075.     {"unused",     (char *)DoVariation, (caddr_t)9 },
  15076.     {"unused",     (char *)DoVariation, (caddr_t)10 },
  15077.     {"unused",     (char *)DoVariation, (caddr_t)11 },
  15078.     {"unused",     (char *)DoVariation, (caddr_t)12 },
  15079.     {"unused",     (char *)DoVariation, (caddr_t)13 },
  15080.     {"unused",     (char *)DoVariation, (caddr_t)14 },
  15081.     {"unused",     (char *)DoVariation, (caddr_t)15 },
  15082.     {"unused",     (char *)DoVariation, (caddr_t)16 },
  15083.     {"unused",     (char *)DoVariation, (caddr_t)17 },
  15084.     {"unused",     (char *)DoVariation, (caddr_t)18 },
  15085.     {"unused",     (char *)DoVariation, (caddr_t)19 },
  15086.     {"unused",     (char *)DoVariation, (caddr_t)20 },
  15087.     {"unused",     (char *)DoVariation, (caddr_t)21 },
  15088.     {"unused",     (char *)DoVariation, (caddr_t)22 },
  15089.     {"unused",     (char *)DoVariation, (caddr_t)23 },
  15090.     {"unused",     (char *)DoVariation, (caddr_t)24 },
  15091.     {"unused",     (char *)DoVariation, (caddr_t)25 },
  15092. };
  15093.  
  15094. static void Beep()
  15095. {
  15096.     if( !XtIsRealized(toplevel) )
  15097.     return;
  15098.  
  15099.     XBell(XtDisplay( toplevel ), 50);
  15100. }
  15101.  
  15102. static XtActionProc HandleKeyDown(w, cli, e)
  15103. Widget w;
  15104. caddr_t cli, e;
  15105. {
  15106.     XKeyEvent *evnt = (XKeyEvent *)e;
  15107.     char buf[BUF_SIZE];
  15108.     KeySym ksym;
  15109.     XComposeStatus status;
  15110.  
  15111. #ifdef DEBUG
  15112.     fprintf(stderr, "HandleKeyDown:  ");
  15113. #endif
  15114.     XLookupString(evnt, buf, BUF_SIZE, &ksym, &status);
  15115. #ifdef DEBUG
  15116.     fprintf(stderr, "-%s-\n", buf);
  15117. #endif
  15118.  
  15119.     switch(*buf) {
  15120.     case '>':
  15121.     theCommand = C_DOWN;
  15122.     break;
  15123.     case '<':
  15124.     theCommand = C_UP;
  15125.     break;
  15126.     case ',':
  15127.     theCommand = C_WALKUP;
  15128.     break;
  15129.     case '{':
  15130.     theCommand = C_SEARCHBACKCOMMENT;
  15131.     break;
  15132.     case '.':
  15133.     theCommand = C_WALKDOWN;
  15134.     break;
  15135.     case '}':
  15136.     theCommand = C_SEARCHCOMMENT;
  15137.     break;
  15138.     case '[':
  15139.     theCommand = C_DOWNFORK;
  15140.     break;
  15141.     case ']':
  15142.     theCommand = C_UPFORK;
  15143.     break;
  15144.     case '#':
  15145.     theCommand = C_LOAD;
  15146.     break;
  15147.     case ' ': /* drop through */
  15148.     case '0':
  15149.     if( move_x == -1 ) {
  15150.         Beep();
  15151.         theCommand = C_NOTHING;
  15152.     } else {
  15153.         theCommand = C_MOVE;
  15154.         xcur = move_x;
  15155.         ycur = move_y;
  15156.     }
  15157.     break;
  15158.     case '!':
  15159.     theCommand = C_TREECUT;
  15160.     break;
  15161.     case '^':
  15162.     theCommand = C_PASTE;
  15163.     break;
  15164.     case 'a':
  15165.     Beep();
  15166.     break;
  15167.     case 'b':
  15168.     theCommand = C_BEGINNING;
  15169.     break;
  15170.     case 'C':
  15171.     theCommand = C_NOTHING;
  15172.     ShowCaptured();
  15173.     break;
  15174.     case 'c':
  15175.     theCommand = C_EDCOMMENT;
  15176.     break;
  15177.     case 'd':
  15178.     theCommand = C_DELNODE;
  15179.     break;
  15180.     case 'e':
  15181.     theCommand = C_END;
  15182.     break;
  15183.     case 'f':
  15184.     theCommand = C_NEXTFILE;
  15185.     break;
  15186.     case 'g':
  15187.     theCommand = C_GOTO;
  15188.     break;
  15189.     case 'l':
  15190.     if( move_x == -1 ) {
  15191.         Beep();
  15192.         theCommand = C_NOTHING;
  15193.     } else {
  15194.         theCommand = C_ADDLETTER;
  15195.         xcur = move_x;
  15196.         ycur = move_y;
  15197.     }
  15198.     break;
  15199.     case 'm':
  15200.     if( move_x == -1 ) {
  15201.         Beep();
  15202.         theCommand = C_NOTHING;
  15203.     } else {
  15204.         theCommand = C_ADDMARK;
  15205.         xcur = move_x;
  15206.         ycur = move_y;
  15207.     }
  15208.     break;
  15209.     case 'n':
  15210.     theCommand = C_ADDNAME;
  15211.     break;
  15212.     case 'p':
  15213.     theCommand = C_PASSMOVE;
  15214.     break;
  15215.     case 'q':
  15216.     theCommand = C_QUIT;
  15217.     break;
  15218.     case 'r':
  15219.     theCommand = C_BACKFILE;
  15220.     break;
  15221.     case 's':
  15222.     theCommand = C_SCORE;
  15223.     break;
  15224.     case 'v':
  15225.     theCommand = C_ADDVAR;
  15226.     break;
  15227.     case 'w':
  15228.     theCommand = C_WRITE;
  15229.     break;
  15230.     case 'x':
  15231.     if( move_x == -1 ) {
  15232.         Beep();
  15233.         theCommand = C_NOTHING;
  15234.     } else {
  15235.         theCommand = C_ADDWHITE;
  15236.         xcur = move_x;
  15237.         ycur = move_y;
  15238.     }
  15239.     break;
  15240.     case 'z':
  15241.     if( move_x == -1 ) {
  15242.         Beep();
  15243.         theCommand = C_NOTHING;
  15244.     } else {
  15245.         theCommand = C_ADDBLACK;
  15246.         xcur = move_x;
  15247.         ycur = move_y;
  15248.     }
  15249.     break;
  15250.     /*
  15251.      * These letter apear to not do anything in ascii mgt.
  15252.      */
  15253.     case 'h':
  15254.     case 'i':
  15255.     case 'j':
  15256.     case 'k':
  15257.     case 'o':
  15258.     case 't':
  15259.     case 'u':
  15260.     case 'y':
  15261.     Beep();
  15262.     break;
  15263.     default:
  15264.     XtAppWarning(app_context, "Unknow character to the X Version");
  15265.     break;
  15266.     }
  15267. }
  15268.  
  15269. static void dobuttondown(w, cli, call)
  15270. Widget w;
  15271. caddr_t cli, call;
  15272.  
  15273. {
  15274.     XButtonEvent *evnt = (XButtonEvent *)call;
  15275.  
  15276. #ifdef DEBUG
  15277.     fprintf(stderr, "dobuttondown:  %d  %d\n", evnt->x, evnt->y);
  15278. #endif /* DEBUG */
  15279.  
  15280.     if (evnt->x < 0 || evnt->y < 0) {
  15281.         theCommand = C_NOTHING;
  15282.     return;
  15283.     }
  15284.  
  15285.     if ((move_x == evnt->x) && (move_y == INDEX_TO_POS(evnt->y))) {
  15286.     xcur = move_x;
  15287.     ycur = move_y;
  15288.     theCommand = C_MOVE;
  15289.     return;
  15290.     }
  15291.  
  15292.     move_x = evnt->x;
  15293.     move_y = INDEX_TO_POS(evnt->y);
  15294.     theCommand = C_NOTHING;
  15295.     BWHighlightPiece(brd, move_x, INDEX_TO_POS(move_y));
  15296. }
  15297.  
  15298. static void HandleHelp(w, cli, call)
  15299.     Widget w;
  15300.     caddr_t cli, call;
  15301. {
  15302.     AmHelping = (int)cli;
  15303.     theCommand = C_NOTHING;
  15304. }
  15305.  
  15306. static void DoVariation(w, cli, call)
  15307. Widget w;
  15308. caddr_t cli, call;
  15309. {
  15310. #ifdef DEBUG
  15311.     fprintf(stderr, "DoVariation\n");
  15312. #endif /* DEBUG */
  15313.  
  15314.     theCommand = C_CHOSECHILD + (int)cli;
  15315. }
  15316.  
  15317. static Widget CreateVariationsButtons(parent, left, top)
  15318. Widget parent, left, top;
  15319. {
  15320.     Widget ret, form, nextto;
  15321.     int i, j;
  15322.     Arg arg[10];
  15323.  
  15324. #ifdef DEBUG
  15325.     fprintf(stderr, "CreateVariationsButtons\n");
  15326. #endif /* DEBUG */
  15327.  
  15328.     i = 0;
  15329.     XtSetArg(arg[i], XtNfromVert,     top);         i++;
  15330.     XtSetArg(arg[i], XtNfromHoriz,     left);         i++;
  15331.     XtSetArg(arg[i], XtNwidth,        174);        i++;
  15332.     XtSetArg(arg[i], XtNheight,        240);        i++;
  15333.     XtSetArg(arg[i], XtNtop,        XtChainTop);    i++;
  15334.     XtSetArg(arg[i], XtNbottom,        XtChainBottom);    i++;
  15335.     XtSetArg(arg[i], XtNright,        XtChainRight);    i++;
  15336.     XtSetArg(arg[i], XtNallowVert,    True);         i++;
  15337.     XtSetArg(arg[i], XtNallowHoriz,    True);         i++;
  15338.     ret = XtCreateManagedWidget("variations", viewportWidgetClass, 
  15339.                         parent, arg, i);
  15340.     i = 0;
  15341.     form = XtCreateManagedWidget("form", formWidgetClass, ret, arg, i);
  15342.  
  15343.     i = 0;
  15344.     XtSetArg(arg[i], XtNwidth,        300);        i++;
  15345.     XtSetArg(arg[i], XtNborderWidth,    0);        i++;
  15346.     XtSetArg(arg[i], XtNfont,        reses.fptr);    i++;
  15347.     title = XtCreateManagedWidget("title", labelWidgetClass, form, arg, i);
  15348.  
  15349.     for (j=0, nextto=title; j < MAX_VARS; nextto=variations[j].w, j++) {
  15350.     i = 0;
  15351.         XtSetArg(arg[i], XtNfromVert,     nextto);    i++;
  15352.         XtSetArg(arg[i], XtNwidth,    300);         i++;
  15353.         XtSetArg(arg[i], XtNfont,    reses.fptr);    i++;
  15354.     variations[j].w = XtCreateManagedWidget(variations[j].name,     
  15355.                      commandWidgetClass, form, arg, i);
  15356.     XtAddCallback(variations[j].w, XtNcallback, variations[j].callback, 
  15357.                     variations[j].cmd);
  15358.     }
  15359.  
  15360.     return ret;
  15361. }
  15362.  
  15363. static Widget CreateMenus (parent)
  15364. Widget parent;
  15365. {
  15366.     int i, j, k;
  15367.     Widget ret, button, menu, entry, nextto;
  15368.     Arg arg[10];
  15369.  
  15370. #ifdef DEBUG
  15371.     fprintf(stderr, "CreateMenus\n");
  15372. #endif /* DEBUG */
  15373.  
  15374.     j = 0;
  15375.     XtSetArg(arg[j], XtNtop,            XtChainTop);    j++;
  15376.     XtSetArg(arg[j], XtNbottom,            XtChainTop);    j++;
  15377.     XtSetArg(arg[j], XtNleft,            XtChainLeft);    j++;
  15378.     XtSetArg(arg[j], XtNright,            XtChainRight);    j++;
  15379.     ret = XtCreateManagedWidget("menus", formWidgetClass, parent, arg, j);
  15380.  
  15381.     for (i=0, k=0, nextto=NULL; menu_name[i]; i++, k++, nextto=button) {
  15382.  
  15383.     j = 0;
  15384.         XtSetArg(arg[j], XtNfromHoriz,         nextto);    j++;
  15385.         XtSetArg(arg[j], XtNwidth,         reses.men_wd);    j++;
  15386.         XtSetArg(arg[j], XtNfont,        reses.fptr);    j++;
  15387.     button = XtCreateManagedWidget(menu_name[i], menuButtonWidgetClass, 
  15388.                         ret, arg, j);
  15389.  
  15390.     j = 0;
  15391.         XtSetArg(arg[j], XtNwidth,         reses.men_wd);    j++;
  15392.         XtSetArg(arg[j], XtNborderWidth,     3);        j++;
  15393.         XtSetArg(arg[j], XtNborderColor,     "black");    j++;
  15394.         XtSetArg(arg[j], XtNrowHeight,        20);        j++;
  15395.     menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, 
  15396.                         button, arg, j);
  15397.  
  15398.     for (; menu_entry[k].name; k++) {
  15399.         j = 0;
  15400.             XtSetArg(arg[j], XtNleftMargin,     20);        j++;
  15401.             XtSetArg(arg[j], XtNfont,        reses.fptr);    j++;
  15402.         entry = XtCreateManagedWidget(menu_entry[k].name, 
  15403.                     smeBSBObjectClass, 
  15404.                     menu, arg, j);
  15405.         XtAddCallback(entry, XtNcallback, menu_entry[k].callback, 
  15406.                     menu_entry[k].cmd);
  15407.     }
  15408.  
  15409.     }
  15410.  
  15411.     return ret;
  15412. }
  15413.  
  15414. static Widget CreateButtons(parent, left, top )
  15415. Widget parent, left, top;
  15416. {
  15417.     int i, j;
  15418.     Widget ret, nextto, tmp;
  15419.     Arg arg[10];
  15420.  
  15421. #ifdef DEBUG
  15422.     fprintf(stderr, "CreateButtons\n");
  15423. #endif /* DEBUG */
  15424.  
  15425.     i = 0;
  15426.     XtSetArg(arg[i], XtNfromVert,         top);        i++;
  15427.     XtSetArg(arg[i], XtNfromHoriz,         left);        i++;
  15428.     XtSetArg(arg[i], XtNtop,            XtChainTop);    i++;
  15429.     XtSetArg(arg[i], XtNbottom,            XtChainTop);    i++;
  15430.     XtSetArg(arg[i], XtNright,            XtChainRight);    i++;
  15431.     ret = XtCreateManagedWidget("buttons", formWidgetClass, parent, arg, i);
  15432.  
  15433.     for(j = 0, nextto = NULL; buttons[j].name; j++, nextto = tmp) {
  15434.         i = 0;
  15435.         XtSetArg(arg[i], XtNfromVert,         nextto);    i++;
  15436.         XtSetArg(arg[i], XtNwidth,        reses.but_wd);    i++;
  15437.         XtSetArg(arg[i], XtNleft,        XtChainLeft);    i++;
  15438.         XtSetArg(arg[i], XtNright,        XtChainRight);    i++;
  15439.     XtSetArg(arg[i], XtNfont,        reses.fptr);    i++;
  15440.     tmp = XtCreateManagedWidget(buttons[j].name,     
  15441.                         commandWidgetClass, ret, arg, i);
  15442.     XtAddCallback(tmp, XtNcallback, buttons[j].callback, buttons[j].cmd);
  15443.     }
  15444.  
  15445.     return ret;
  15446. }
  15447.  
  15448. static void openX11()
  15449. {
  15450.     int i;
  15451.     Arg arg[10];
  15452.     Widget form, m_holder, t_holder, c_viewer;
  15453.     int argc = 1;
  15454.  
  15455. #ifdef XMGT_IGS
  15456.  
  15457. #ifdef XMGT_HFS
  15458.     static char *argv[1] = { "Xmgt + HFS + IGS" };
  15459. #else
  15460.     static char *argv[1] = { "Xmgt + IGS" };
  15461. #endif /* XMGT_HFS */
  15462.  
  15463. #else
  15464.  
  15465. #ifdef XMGT_HFS
  15466.     static char *argv[1] = { "Xmgt + HFS" };
  15467. #else
  15468.     static char *argv[1] = { "Xmgt" };
  15469. #endif /* XMGT_HFS */
  15470.  
  15471. #endif /* XMGT_IGS */
  15472.  
  15473. #ifdef DEBUG
  15474.     fprintf(stderr, "openX11\n");
  15475. #endif /* DEBUG */
  15476.  
  15477.     toplevel = XtAppInitialize(&app_context, "XMgt", NULL, 0, 
  15478.                    &argc, argv, NULL, NULL, 0);
  15479.  
  15480.     i=0;
  15481.     form = XtCreateManagedWidget("form", formWidgetClass, toplevel, arg, i);
  15482.  
  15483.     XtGetApplicationResources(toplevel, &reses, resources, 
  15484.                         XtNumber(resources), NULL, 0);
  15485.     
  15486.     m_holder = CreateMenus(form);
  15487.  
  15488.     i=0;
  15489.     XtSetArg(arg[i], XtNfromVert,         m_holder);    i++;
  15490.     XtSetArg(arg[i], XtNtop,            XtChainTop);    i++;
  15491.     XtSetArg(arg[i], XtNbottom,            XtChainBottom);    i++;
  15492.     XtSetArg(arg[i], XtNleft,            XtChainLeft);    i++;
  15493.     brd = XtCreateManagedWidget("board", boardWidgetClass, form, arg, i);
  15494.     XtAddCallback(brd, XtNbuttonDown, dobuttondown, 0);
  15495.     XtAddCallback(brd, XtNkeyDown, HandleKeyDown, 0);
  15496.  
  15497.     buts = CreateButtons(form, brd, m_holder);
  15498.  
  15499.     vars = CreateVariationsButtons(form, brd, buts);
  15500.  
  15501.     i=0;
  15502.     XtSetArg(arg[i], XtNfromVert,         brd);        i++;
  15503.     XtSetArg(arg[i], XtNwidth,             684);        i++;
  15504.     XtSetArg(arg[i], XtNtop,            XtChainBottom);    i++;
  15505.     XtSetArg(arg[i], XtNbottom,            XtChainBottom);    i++;
  15506.     XtSetArg(arg[i], XtNleft,            XtChainLeft);    i++;
  15507.     XtSetArg(arg[i], XtNright,            XtChainRight);    i++;
  15508.     t_holder = XtCreateManagedWidget("text", formWidgetClass, form, arg, i);
  15509.  
  15510.     i=0;
  15511.     XtSetArg(arg[i], XtNdisplayCaret,        False);        i++;
  15512.     XtSetArg(arg[i], XtNwidth,             reses.note_wd);    i++;
  15513.     XtSetArg(arg[i], XtNheight,            reses.note_ht);    i++;
  15514.     XtSetArg(arg[i], XtNleft,            XtChainLeft);    i++;
  15515.     XtSetArg(arg[i], XtNright,            XtChainRight);    i++;
  15516.     XtSetArg(arg[i], XtNfont,            reses.fptr);    i++;
  15517.     notify = XtCreateManagedWidget("notify", asciiTextWidgetClass,     
  15518.                             t_holder, arg, i);
  15519.  
  15520.     i=0;
  15521.     XtSetArg(arg[i], XtNallowVert,         True);        i++;
  15522.     XtSetArg(arg[i], XtNfromVert,         notify);    i++;
  15523.     XtSetArg(arg[i], XtNwidth,             reses.note_wd); i++;
  15524.     XtSetArg(arg[i], XtNheight,            173);        i++;
  15525.     XtSetArg(arg[i], XtNleft,            XtChainLeft);    i++;
  15526.     XtSetArg(arg[i], XtNright,            XtChainRight);    i++;
  15527.     c_viewer = XtCreateManagedWidget("c_viewer", viewportWidgetClass, 
  15528.                             t_holder, arg, i);
  15529.  
  15530.     i=0;
  15531.     XtSetArg(arg[i], XtNdisplayCaret,        False);        i++;
  15532.     XtSetArg(arg[i], XtNlength,            MAXCOMMENT);    i++;
  15533.     XtSetArg(arg[i], XtNwidth,             reses.comm_wd); i++;
  15534.     XtSetArg(arg[i], XtNheight,            reses.comm_ht);    i++;
  15535.     XtSetArg(arg[i], XtNfont,            reses.fptr);    i++;
  15536.     comm = XtCreateManagedWidget("comment", asciiTextWidgetClass, 
  15537.                             c_viewer, arg, i);
  15538.  
  15539.     CreateDialog(toplevel);
  15540.  
  15541.     mark = XCreateBitmapFromData(XtDisplay(toplevel),
  15542.                 RootWindowOfScreen(XtScreen(toplevel)),
  15543.                 xlogo11_bits,
  15544.                 xlogo11_width,
  15545.                 xlogo11_height);
  15546.  
  15547.     XtRealizeWidget(toplevel);
  15548. }
  15549.  
  15550. static void closeX11()
  15551. {
  15552. #ifdef DEBUG
  15553.     fprintf(stderr, "closeX11\n");
  15554. #endif /* DEBUG */
  15555.  
  15556.     XtDestroyWidget(toplevel);
  15557. }
  15558.  
  15559. static void refreshIOX11()
  15560. {
  15561. #ifdef DEBUG
  15562.     fprintf(stderr, "refreshIOX11\n");
  15563. #endif /* DEBUG */
  15564. }
  15565.  
  15566. static void plotPiece(b, i, j)
  15567. pBoard b;
  15568. int i, j;
  15569. {
  15570.     piece p;
  15571.     BWPiece bwp;
  15572.  
  15573. #ifdef DEBUG
  15574.     fprintf(stderr, "plotPiece\n");
  15575. #endif /* DEBUG */
  15576.  
  15577.     p = boardGet(b, i, j);
  15578.     switch( p ) {
  15579.     case P_NOTHING:
  15580.     bwp = Empty;
  15581.     break;
  15582.     case P_BLACK:
  15583.     bwp = Black;
  15584.     break;
  15585.     case P_WHITE:
  15586.     bwp = White;
  15587.     break;
  15588.     case P_DAME:
  15589.     bwp = Dame;
  15590.     break;
  15591.     case P_BLACKTERR:
  15592.     bwp = BlackTerritory;
  15593.     break;
  15594.     case P_WHITETERR:
  15595.     bwp = WhiteTerritory;
  15596.     break;
  15597.     default:
  15598.     assert(0);
  15599.     break;
  15600.     }
  15601.     BWPutPiece( brd, i, INDEX_TO_POS(j), bwp );
  15602. }
  15603.  
  15604. static void displayComment(s)
  15605. char *s;
  15606. {
  15607.     static char comment_buffer[MAXCOMMENT];
  15608.     int i, maxcol;
  15609.     Arg arg[10];
  15610.     Dimension width;
  15611.  
  15612. #ifdef DEBUG
  15613.     fprintf(stderr, "displayComment\n");
  15614. #endif /* DEBUG */
  15615.  
  15616.     /*  Save unformatted comment so that it can be redisplayed  */
  15617.     strcpy(comment_backup, s);
  15618.  
  15619.     /*  Determine the maximum number of characters in a line  */
  15620.     GetSize(comm, &width, NULL);
  15621.     maxcol = (width - 4) / FontWidth;
  15622.  
  15623.     /*  Reformat comment so that it is properly wordwrapped  */
  15624.     format(s, comment_buffer, maxcol);
  15625.  
  15626.     /*  Display the formatted comment  */
  15627.     SetText(comm, comment_buffer);
  15628. }
  15629.  
  15630. static void clearComment()
  15631. {
  15632. #ifdef DEBUG
  15633.     fprintf(stderr, "clearComment\n");
  15634. #endif /* DEBUG */
  15635.  
  15636.     SetText(comm, EMPTY_STR);
  15637. }
  15638.  
  15639. static void clearBoard()
  15640. {
  15641. #ifdef DEBUG
  15642.     fprintf(stderr, "clearBoard\n");
  15643. #endif /* DEBUG */
  15644.  
  15645.     BWReset(brd);
  15646. }
  15647.  
  15648. static void clearScreen()
  15649. {
  15650. #ifdef DEBUG
  15651.     fprintf(stderr, "clearScreen\n");
  15652. #endif /* DEBUG */
  15653. }
  15654.  
  15655. static void HandleScoring(w, cli, call)
  15656. Widget w;
  15657. caddr_t cli, call;
  15658. {
  15659.     static int clkst = 0;
  15660.     static Widget score;
  15661.     Arg args[10];
  15662.  
  15663. #ifdef DEBUG
  15664.     fprintf(stderr, "HandleScoring\n");
  15665. #endif /* DEBUG */
  15666.  
  15667.     theCommand = (int) cli;
  15668.     if (clkst == 0) {
  15669.     if (theCommand == C_SCORE) {
  15670.         score = w;
  15671.         clkst = 1;
  15672.         XtSetArg(args[0], XtNlabel, "Calculate Score");
  15673.         XtSetValues(score, args, 1);
  15674.     } else {
  15675.         theCommand = C_NOTHING;
  15676.     }
  15677.     } else {
  15678.     if (theCommand == C_QUIT) {
  15679.             if (DoAsk(toplevel, "Do you want to quit scoring?") != YES) {
  15680.             theCommand = C_NOTHING;
  15681.         return;
  15682.         }
  15683.         clkst = 0;
  15684.         XtSetArg(args[0], XtNlabel, "Start Scoring");
  15685.         XtSetValues(score, args, 1);
  15686.     }
  15687.     }
  15688. }
  15689.  
  15690. static void SetCommand(w, cli, call)
  15691. Widget w;
  15692. caddr_t cli, call;
  15693. {
  15694.     Arg arglist[5];
  15695.     Cardinal num_args;
  15696.  
  15697. #ifdef DEBUG
  15698.     fprintf(stderr, "SetCommand\n");
  15699. #endif /* DEBUG */
  15700.  
  15701.     if( theCommand != C_NOTHING ) {
  15702.     Beep();
  15703.     return;
  15704.     }
  15705.  
  15706.     switch ((int) cli) {
  15707.     case C_MOVE:
  15708.     case C_ADDBLACK:
  15709.     case C_ADDWHITE:
  15710.     case C_ADDMARK:
  15711.     case C_ADDLETTER:
  15712.     if( move_x == -1 ) {
  15713.         Beep();
  15714.         theCommand = C_NOTHING;
  15715.         return;
  15716.     }
  15717.     xcur = move_x;
  15718.     ycur = move_y;
  15719.     break;
  15720.     case C_SAVESHORT:
  15721.     if( ! AmHelping ) {
  15722.         num_args = 0;
  15723.         if (saveShort) {
  15724.             XtSetArg(arglist[num_args], XtNleftBitmap, None); num_args++;
  15725.         } else {
  15726.             XtSetArg(arglist[num_args], XtNleftBitmap, mark); num_args++;
  15727.         }
  15728.         XtSetValues(w, arglist, num_args);
  15729.     }
  15730.     break;
  15731.     case C_TUTORSWAP:
  15732.     num_args = 0;
  15733.     if (tutor) {
  15734.         XtSetArg(arglist[num_args], XtNleftBitmap, None); num_args++;
  15735.     } else {
  15736.         XtSetArg(arglist[num_args], XtNleftBitmap, mark); num_args++;
  15737.     }
  15738.     XtSetValues(w, arglist, num_args);
  15739.     break;
  15740.     case C_QUIT:
  15741.         if( ! AmHelping ) {
  15742.         if (DoAsk(toplevel, "Do you want to quit?") != YES) {
  15743.             theCommand = C_NOTHING;
  15744.             return;
  15745.         }
  15746.     } else {
  15747.         HelpCommand((int)C_QUIT);
  15748.         theCommand = C_NOTHING;
  15749.     }
  15750.     break;
  15751.     }
  15752.     theCommand = (int)cli;
  15753. }
  15754.  
  15755. static void HelpCommand(cmd)
  15756.     int cmd;
  15757. {
  15758.     extern char *shortHelpStr[];
  15759.     extern char *longHelpStr[];
  15760.  
  15761.     if( cmd == C_NOTHING )
  15762.     return;
  15763. #ifdef DEBUG
  15764.     fprintf(stderr, "HelpCommand\n");
  15765. #endif /* DEBUG */
  15766.  
  15767.     if( cmd > 0 && cmd < 45 ) {
  15768.     if( AmHelping & 0x2 )
  15769.         displayComment(longHelpStr[cmd]);
  15770.     else
  15771.         notifyMessage(shortHelpStr[cmd]);
  15772.     }
  15773. #ifdef DEBUG
  15774.     else
  15775.     fprintf(stderr, "Unknown cmd %d\n", cmd);
  15776. #endif /* DEBUG */
  15777. }
  15778.  
  15779. static int getCommand(curnode)
  15780. nodep curnode;
  15781. {
  15782.     XEvent evnt;
  15783.  
  15784.     move_x = move_y = -1;
  15785.     theCommand = C_NOTHING;
  15786.     
  15787.     do {
  15788.         if (XtAppPending(app_context)) {
  15789.             XtAppNextEvent(app_context, &evnt);
  15790.             XtDispatchEvent(&evnt);
  15791. #ifdef XMGT_IGS
  15792.         } else {
  15793.         theCommand = goserver(curnode);
  15794. #endif /* XMGT_IGS */
  15795.         }
  15796.     
  15797.     /*  Redraw the window if just resized  */
  15798.         if (resized) {
  15799.         reconfig(brd, buts, vars);
  15800.         displayComment(comment_backup);
  15801.         resized = 0;
  15802.         }
  15803.         if( AmHelping ) {
  15804.         HelpCommand(theCommand);
  15805.         theCommand = C_NOTHING;
  15806.     }
  15807.     } while (theCommand == C_NOTHING);
  15808.  
  15809.     return theCommand;
  15810. }
  15811.  
  15812. static int getPoint()
  15813. {
  15814. #ifdef DEBUG
  15815.     fprintf(stderr, "getPoint\n");
  15816. #endif /* DEBUG */
  15817.  
  15818.     return getCommand(NULL);
  15819. }
  15820.  
  15821. static int idle(curnode)
  15822. nodep curnode;
  15823. {
  15824. #ifdef DEBUG
  15825.     fprintf(stderr, "idle\n");
  15826. #endif /* DEBUG */
  15827.  
  15828.     highlightLast();
  15829.  
  15830.     return getCommand(curnode);
  15831. }
  15832.  
  15833. static void drawTree(nd)
  15834. nodep nd;
  15835. {
  15836.     property *p;
  15837.     int index;
  15838.     nodep ch;
  15839.     char line[BUF_SIZE];
  15840.     Arg args[10];
  15841.     int i;
  15842.  
  15843. #ifdef DEBUG
  15844.     fprintf(stderr, "drawTree\n");
  15845. #endif /* DEBUG */
  15846.  
  15847.     /* display node number */
  15848.     XtUnmapWidget(vars);
  15849.     if (p = getprop(nd, t_Name))
  15850.     sprintf(line, "Node %d: %s", nd->nodeNum, p->data.comment);
  15851.     else
  15852.     sprintf(line, "Node %d:", nd->nodeNum);
  15853.     i=0;
  15854.     XtSetArg(args[i], XtNjustify,    XtJustifyLeft);    i++;
  15855.     XtSetArg(args[i], XtNlabel,        line);        i++;
  15856.     XtSetValues(title, args, i);
  15857.  
  15858.     /* display variation buttons */
  15859.     index = 0;
  15860.     ch = nthChild(nd, 0);
  15861.     while (ch && (index < MAX_VARS)) {
  15862.     XtUnmanageChild(variations[index].w);
  15863.     if (p = getprop(ch, t_Name))
  15864.         sprintf(line, "Var. %d: %s", index, p->data.comment);
  15865.     else
  15866.         sprintf(line, "Var. %d", index);
  15867.     i = 0;
  15868.     XtSetArg(args[i], XtNjustify,    XtJustifyLeft);    i++;
  15869.     XtSetArg(args[i], XtNlabel,    line);        i++;
  15870.     XtSetValues(variations[index].w, args, i);
  15871.     XtManageChild(variations[index].w);
  15872.  
  15873.     ch = NEXTSIBLING(ch);
  15874.     index++;
  15875.     }
  15876.  
  15877.     for( ; index < MAX_VARS ; index++ ) {
  15878.     if( XtIsManaged(variations[index].w) )
  15879.         XtUnmanageChild(variations[index].w);
  15880.     }
  15881.  
  15882.     XtMapWidget(vars);
  15883. }
  15884.  
  15885. static void highlightLastX11(i, j, movenum, turn)
  15886. int i, j, movenum, turn;
  15887. {
  15888.     char buf[BUF_SIZE], str[BUF_SIZE];
  15889.  
  15890. #ifdef DEBUG
  15891.     fprintf(stderr, "highlightLastX11\n");
  15892. #endif /* DEBUG */
  15893.  
  15894.     if( i == -1 ) { /* I hate this convention */
  15895.     notifyClear();
  15896.     return;
  15897.     }
  15898.  
  15899.     if (i == PASSVAL && j == PASSVAL) {
  15900.     sprintf(buf, "%s: %d Pass", turn ? "White" : "Black", movenum);
  15901.     } else {
  15902.     sprintf(buf, "%s: %d @ %c%d", turn ? "White" : "Black", movenum,
  15903.         INDEX_TO_CHAR(i), INDEX_TO_POS(j)+1);
  15904.     BWHighlightPiece(brd, i, INDEX_TO_POS(j));
  15905.     }
  15906.  
  15907.     sprintf(str, "   \tPrisoners:  White %d   Black %d", prisoners[0], prisoners[1]);
  15908.     strcat(buf, str);
  15909.  
  15910.     if (tutor)
  15911.         strcat(buf,"   \tMode:  tutor");
  15912.     else if (madechanges)
  15913.         strcat(buf,"   \tMode:  edit ");
  15914.     else
  15915.         strcat(buf,"   \tMode:  read ");
  15916.  
  15917.     if (saveShort) 
  15918.         strcat(buf, "  short");
  15919.     else
  15920.     strcat(buf, "  long ");
  15921.  
  15922.     notifyMessage((char *)buf);
  15923. }
  15924.  
  15925. /*
  15926.  * Any thing here should be in resources.
  15927.  */
  15928. static void readEnv()
  15929. {
  15930. #ifdef DEBUG
  15931.     fprintf(stderr, "readEnv\n");
  15932. #endif /* DEBUG */
  15933. }
  15934.  
  15935. static void notifyMessage(s)
  15936. char *s;
  15937. {
  15938.     static char message_buffer[BUF_SIZE];
  15939.  
  15940. #ifdef DEBUG
  15941.     fprintf(stderr, "notifyMessage:  -%s-\n", s);
  15942. #endif /* DEBUG */
  15943.  
  15944.     strcpy(message_buffer, s);
  15945.     SetText(notify, message_buffer);
  15946. }
  15947.  
  15948. static void notifyClear()
  15949. {
  15950. #ifdef DEBUG
  15951.     fprintf(stderr, "notifyClear\n");
  15952. #endif /* DEBUG */
  15953.  
  15954.     SetText(notify, EMPTY_STR);
  15955. }
  15956.  
  15957. static int queryStr(question, answer, len)
  15958. char *question, *answer;
  15959. int len;    /* bugs, who cares, this is ignored */
  15960. {
  15961. #ifdef DEBUG
  15962.     fprintf(stderr, "queryStr\n");
  15963. #endif /* DEBUG */
  15964.  
  15965.     answer[0] = '\0';
  15966.     return DoDialog(toplevel, question, answer);
  15967. }
  15968.  
  15969. /*
  15970.  * What do I do for this?
  15971.  */
  15972. static void setCursor()
  15973. {
  15974. #ifdef DEBUG
  15975.     fprintf(stderr, "setCursor\n");
  15976. #endif /* DEBUG */
  15977. }
  15978.  
  15979. static void plotMark(b, i, j)
  15980.     pBoard b;
  15981.     int i, j;
  15982. {
  15983. #ifdef DEBUG
  15984.     fprintf(stderr, "plotMark\n");
  15985. #endif /* DEBUG */
  15986.  
  15987.     BWSetMark(brd, i, INDEX_TO_POS(j), DiamondMark);
  15988. }
  15989.  
  15990. static void plotLetter(i, j, c)
  15991.     int i, j;
  15992.     char c;
  15993. {
  15994. #ifdef DEBUG
  15995.     fprintf(stderr, "plotLetter\n");
  15996. #endif /* DEBUG */
  15997.  
  15998.     BWSetLetter(brd, i, INDEX_TO_POS(j), c);
  15999. }
  16000.  
  16001. static void editComment(in, out)
  16002. char *in, **out;
  16003. {
  16004.     static char comment_buffer[MAXCOMMENT];
  16005.     char *str;
  16006.     int i;
  16007.     Arg arg[10];
  16008.     Dimension width;
  16009.  
  16010. #ifdef DEBUG
  16011.     fprintf(stderr, "editComment\n");
  16012. #endif /* DEBUG */
  16013.  
  16014.     /*  Determine the maximum number of characters in a line  */
  16015.     /*  Reformat comment so that it is properly wordwrapped  */
  16016.     GetSize(comm, &width, NULL);
  16017.     format(in, comment_buffer, width/FontWidth);
  16018.  
  16019.     i = 0;
  16020.     XtSetArg(arg[i], XtNeditType,    XawtextEdit);        i++;
  16021.     XtSetArg(arg[i], XtNdisplayCaret,    True);            i++;
  16022.     XtSetArg(arg[i], XtNstring,        comment_buffer);    i++;
  16023.     XtSetValues(comm, arg, i);
  16024.  
  16025.     notifyMessage("Edit comment in the comment window directly.");
  16026.  
  16027.     if (DoAsk2(toplevel, "Update comment?", XtGrabNone) == YES) {
  16028.         XtSetArg(arg[0], XtNstring,    (XtArgVal)(&str));
  16029.         XtGetValues(comm, arg, 1);
  16030.         free(in);
  16031.     *out = (char *) malloc(sizeof(char) * strlen(str) + 1);
  16032.     if (*out)
  16033.         strcpy(*out, str);
  16034.     else
  16035.         XtAppWarning(app_context, "Could not alloc in editComment");
  16036.     } else {
  16037.     *out = in;
  16038.     }
  16039.  
  16040.     notifyClear();
  16041.  
  16042.     i = 0;
  16043.     XtSetArg(arg[i], XtNeditType,    XawtextRead);        i++;
  16044.     XtSetArg(arg[i], XtNdisplayCaret,    False);            i++;
  16045.     XtSetValues(comm, arg, i);
  16046. }
  16047.  
  16048. static int askYN(query, deflt)
  16049. char *query;
  16050. int deflt;    /* will be ignored for now */
  16051. {
  16052. #ifdef DEBUG
  16053.     fprintf(stderr, "askYN\n");
  16054. #endif /* DEBUG */
  16055.  
  16056.     return DoAsk(toplevel, query);
  16057. }
  16058.  
  16059. static void notifyError(errormsg)
  16060. char *errormsg;
  16061. {
  16062. #ifdef DEBUG
  16063.     fprintf(stderr, "notifyError\n");
  16064. #endif /* DEBUG */
  16065.  
  16066.     DoWarning(toplevel, errormsg);
  16067. }
  16068.  
  16069. static void ShowCaptured()
  16070. {
  16071.     static char capted[BUF_SIZE];
  16072.  
  16073.     sprintf(capted, "White  %d    Black  %d", prisoners[0], prisoners[1]);
  16074.     DoWarning(toplevel, capted);
  16075. }
  16076.  
  16077. static void displayInfo(s)
  16078. char *s;
  16079. {
  16080. #ifdef DEBUG
  16081.     fprintf(stderr, "displayInfo\n");
  16082. #endif /* DEBUG */
  16083.  
  16084.     displayComment(s);
  16085. }
  16086.  
  16087. static char *editName[] = {
  16088.     "Size",
  16089.     "Handicap",
  16090.     "Black's name",
  16091.     "Black's rank",
  16092.     "White's name",
  16093.     "White's rank",
  16094.     "Game name",
  16095.     "Event",
  16096.     "Round",
  16097.     "Date",
  16098.     "Place",
  16099.     "Time limit",
  16100.     "Result",
  16101.     "Game comment",
  16102.     "Source",
  16103.     "User",
  16104.     "Komi"
  16105. };
  16106.  
  16107. static Token getInfoToChange()
  16108. {
  16109.     static int flag = 0;
  16110.     int code;
  16111.  
  16112. #ifdef DEBUG
  16113.     fprintf(stderr, "getInfoToChange\n");
  16114. #endif /* DEBUG */
  16115.  
  16116.     if (flag == 1) {
  16117.         flag = 0;
  16118.         return t_BlackRank;
  16119.     }
  16120.     if (flag == 2) {
  16121.         flag = 0;
  16122.         return t_WhiteRank;
  16123.     }
  16124.     code = DoChoice(toplevel);
  16125.     if (code == 0)
  16126.        return t_EOF;
  16127.     else if (code == (t_PlayerBlack-t_Size+1))
  16128.     flag = 1;
  16129.     else if (code == (t_PlayerWhite-t_Size+1))
  16130.     flag = 2;
  16131.     return code + t_Size - 1;
  16132. }
  16133.  
  16134. static void editInfo(input, output, info_item)
  16135. char *input;
  16136. char **output;
  16137. Token info_item;
  16138. {
  16139.     char ret[MAXCOMMENT];
  16140.  
  16141. #ifdef DEBUG
  16142.     fprintf(stderr, "editInfo\n");
  16143. #endif /* DEBUG */
  16144.  
  16145.     ret[0] = '\0';
  16146.     if (DoDialog(toplevel, editName[info_item-FIRSTINFO+2], ret) == YES) {
  16147.         if (input)
  16148.         free(input);
  16149.     *output = (char *) malloc(sizeof(char) * strlen(ret) + 1);
  16150.     if (*output)
  16151.         strcpy(*output, ret);
  16152.     else
  16153.         XtAppWarning(app_context, "Could not alloc in editInfo");
  16154.     } else if (input) {
  16155.     *output = input;
  16156.     } else {
  16157.     *output = (char *) malloc(sizeof(char));
  16158.     if (!*output)
  16159.         XtAppWarning(app_context, "Could not alloc in editInfo");
  16160.     **output = '\0';
  16161.     }
  16162. }
  16163.  
  16164. interface asciiInterface = {
  16165.     (char *)0,
  16166.     (char *)0,
  16167.     (char *)0,
  16168.     (pfi) openX11, 
  16169.     (pfi) closeX11, 
  16170.     (pfi) refreshIOX11, 
  16171.     (pfi) plotPiece, 
  16172.     (pfi) displayComment, 
  16173.     (pfi) clearComment, 
  16174.     (pfi) clearBoard,
  16175.     (pfi) clearScreen, 
  16176.     (pfi) idle, 
  16177.     (pfi) drawTree, 
  16178.     (pfi) highlightLastX11, 
  16179.     (pfi) readEnv, 
  16180.     (pfi) notifyMessage,
  16181.     (pfi) notifyClear, 
  16182.     (pfi) queryStr, 
  16183.     (pfi) setCursor, 
  16184.     (pfi) plotMark, 
  16185.     (pfi) plotLetter, 
  16186.     (pfi) getPoint, 
  16187.     (pfi) editComment,
  16188.     (pfi) askYN,
  16189.     (pfi) notifyError,
  16190.     (pfi) displayInfo,
  16191.     (pfi) getInfoToChange,
  16192.     (pfi) editInfo
  16193. };
  16194.  
  16195. SHAR_EOF
  16196. fi
  16197. if test -f 'xutil.c'
  16198. then
  16199.     echo shar: "will not over-write existing file 'xutil.c'"
  16200. else
  16201. cat << \SHAR_EOF > 'xutil.c'
  16202. /*******************************************************************************
  16203.  *
  16204.  *  xutil.c
  16205.  *
  16206.  *******************************************************************************
  16207.  */
  16208.  
  16209. /*******************************************************************************
  16210.  *
  16211.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  16212.  *
  16213.  *  This program is distributed in the hope that it will be useful.
  16214.  *  Use and copying of this software and preparation of derivative works
  16215.  *  based upon this software are permitted, so long as the following
  16216.  *  conditions are met:
  16217.  *       o credit to the authors is acknowledged following current
  16218.  *         academic behaviour
  16219.  *       o no fees or compensation are charged for use, copies, or
  16220.  *         access to this software
  16221.  *       o this copyright notice is included intact.
  16222.  *  This software is made available AS IS, and no warranty is made about 
  16223.  *  the software or its performance. 
  16224.  * 
  16225.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  16226.  *  Send them to    dumesnil@etca.fr   or to:
  16227.  *       
  16228.  *       Antoine de Maricourt
  16229.  *       ETCA CREA-SP
  16230.  *       16 bis, avenue Prieur de la Cote d'Or
  16231.  *       94114 Arcueil Cedex
  16232.  *       France
  16233.  *
  16234.  *******************************************************************************
  16235.  */
  16236.  
  16237. /*******************************************************************************
  16238.  *
  16239.  *  Rewritten by Chien-Min Wang for xmgt
  16240.  *
  16241.  *******************************************************************************
  16242.  */
  16243.  
  16244. #include <stdio.h>
  16245. #include <ctype.h>
  16246.  
  16247. #include <X11/Intrinsic.h>
  16248. #include <X11/Shell.h>
  16249. #include <X11/StringDefs.h>
  16250. #include <X11/Xlib.h>
  16251. #include <X11/Xos.h>
  16252. #include <X11/Xatom.h>
  16253. #include <X11/IntrinsicP.h>
  16254. #include <X11/ShellP.h>
  16255.  
  16256. #include <X11/Xaw/Command.h>
  16257. #include <X11/Xaw/Form.h>
  16258. #include <X11/Xaw/Label.h>
  16259. #include <X11/Xaw/AsciiText.h>
  16260. #include <X11/Xaw/Cardinals.h>
  16261.  
  16262. #include "xutil.h"
  16263. #include "FileSel.h"
  16264.  
  16265. extern Res        reses;
  16266. extern XtAppContext    app_context;
  16267.  
  16268. static Widget   f_top;
  16269. static Widget   f_form;
  16270. static Widget   f_msg;
  16271. static Widget   f_sel;
  16272.  
  16273. static Widget   d_top;
  16274. static Widget   d_form;
  16275. static Widget   d_msg;
  16276. static Widget   d_text;
  16277. static Widget   d_confirm;
  16278. static Widget   d_cancel;
  16279.  
  16280. static Widget   a_top;
  16281. static Widget   a_form;
  16282. static Widget   a_msg;
  16283. static Widget   a_confirm;
  16284. static Widget   a_cancel;
  16285.  
  16286. static Widget   w_top;
  16287. static Widget   w_form;
  16288. static Widget   w_msg;
  16289. static Widget   w_confirm;
  16290.  
  16291. static Widget   c_top;
  16292. static Widget   c_form;
  16293. static Widget   c_msg;
  16294. static Widget   c_buttons[20];
  16295.  
  16296. static Widget   pshell;
  16297.  
  16298. static int    mode;
  16299. static int      done = NO;
  16300. static int      code;
  16301.  
  16302. static char     *choice[] = {
  16303.         "Size",
  16304.         "Handicap",
  16305.         "Black's name",
  16306.         "Black's rank",
  16307.         "White's name",
  16308.         "White's rank",
  16309.         "Game name",
  16310.         "Event",
  16311.         "Round",
  16312.         "Date",
  16313.         "Place",
  16314.         "Time limit",
  16315.         "Result",
  16316.         "Game comment",
  16317.         "Source",
  16318.         "User",
  16319.         "Komi",
  16320.     "Quit",
  16321.     NULL
  16322. };
  16323.  
  16324. static void dialogConfirm(w, cli, call)
  16325. Widget w;
  16326. caddr_t cli, call;
  16327. {
  16328.     XtPopdown(pshell);
  16329.     done = YES;
  16330.     code = YES;
  16331. }
  16332.  
  16333. static void dialogCancel(w, cli, call)
  16334. Widget w;
  16335. caddr_t cli, call;
  16336. {
  16337.     XtPopdown(pshell);
  16338.     done = YES;
  16339.     code = NO;
  16340. }
  16341.  
  16342. static void DoDialogButton(w, cli, call)
  16343. Widget w;
  16344. caddr_t cli, call;
  16345. {
  16346.     XtPopdown(pshell);
  16347.     done = YES;
  16348.     code = (int) cli;
  16349. }
  16350.  
  16351. void CreateDialog (toplevel)
  16352. Widget        toplevel;
  16353. {
  16354.     static XtActionsRec   actions[] = {
  16355.       { "dialogConfirm"   , dialogConfirm           , },
  16356.       { "dialogCancel"    , dialogCancel            , },
  16357.     }; 
  16358.     
  16359.     Arg            args[10];
  16360.     int            i, j;
  16361.     XtTranslations translations;
  16362.     
  16363.     XtAppAddActions (app_context, actions, XtNumber(actions));
  16364.  
  16365.     /*
  16366.      *    File Selector
  16367.      */
  16368.     
  16369.     f_top      = XtCreatePopupShell    ("file"   , transientShellWidgetClass,
  16370.                     toplevel , NULL, 0);
  16371.  
  16372.     i = 0;
  16373.     f_form     = XtCreateManagedWidget ("form"     , formWidgetClass, 
  16374.                     f_top      , args, i);
  16375.  
  16376.     i = 0;
  16377.     XtSetArg (args[i], XtNwidth            , (XtArgVal) 500         ); i++;
  16378.     XtSetArg (args[i], XtNborderWidth      , (XtArgVal) 0           ); i++;
  16379.     XtSetArg (args[i], XtNfont             , (XtArgVal) reses.fptr  ); i++;
  16380.     f_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass,
  16381.                     f_form     , args, i);
  16382.     
  16383.     i = 0;
  16384.     XtSetArg (args[i], XtNfromVert         , (XtArgVal) f_msg       ); i++;  
  16385.     XtSetArg (args[i], XtNheight           , (XtArgVal) 400         ); i++;
  16386.     XtSetArg (args[i], XtNcheckExistence   , (XtArgVal) False       ); i++;
  16387.     f_sel      = XtCreateManagedWidget ("select" , xfwfFileSelectorWidgetClass,
  16388.                     f_form   , args, i);
  16389.  
  16390.     XtAddCallback (f_sel, XtNokButtonCallback, 
  16391.         (XtCallbackProc)dialogConfirm, NULL);
  16392.     XtAddCallback (f_sel, XtNcancelButtonCallback,
  16393.         (XtCallbackProc)dialogCancel, NULL);
  16394.  
  16395.     XtRealizeWidget (f_top);
  16396.  
  16397.     /*
  16398.      *    Dialog Window.
  16399.      */
  16400.     
  16401.     translations = XtParseTranslationTable 
  16402.       ("#override                        \
  16403.         <Key> Escape   : dialogCancel()  \n\
  16404.         <Key> Linefeed : dialogConfirm() \n\
  16405.         <Key> Return   : dialogConfirm() \n\
  16406.         Ctrl <Key> J   : dialogConfirm() \n\
  16407.         Ctrl <Key> M   : dialogConfirm()");
  16408.     
  16409.     d_top      = XtCreatePopupShell    ("dialog"   , transientShellWidgetClass,
  16410.                     toplevel   , NULL, 0);
  16411.     
  16412.     i = 0;
  16413.     XtSetArg (args[i], XtNdefaultDistance  , (XtArgVal) 12          ); i++;
  16414.     XtSetArg (args[i], XtNtranslations     , (XtArgVal) translations); i++;
  16415.     d_form     = XtCreateManagedWidget ("form"     , formWidgetClass, 
  16416.                     d_top      , args, i);
  16417.  
  16418.     i = 0;
  16419.     XtSetArg (args[i], XtNwidth            , (XtArgVal) 334         ); i++;
  16420.     XtSetArg (args[i], XtNborderWidth      , (XtArgVal) 0           ); i++;
  16421.     XtSetArg (args[i], XtNfont             , (XtArgVal) reses.fptr  ); i++;
  16422.     d_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass,
  16423.                     d_form     , args, i);
  16424.     
  16425.     i = 0;
  16426.     XtSetArg (args[i], XtNfromVert         , (XtArgVal) d_msg       ); i++;  
  16427.     XtSetArg (args[i], XtNwidth            , (XtArgVal) 334         ); i++;  
  16428.     XtSetArg (args[i], XtNvertDistance     , (XtArgVal) 8           ); i++;  
  16429.     XtSetArg (args[i], XtNeditType         , (XtArgVal) XawtextEdit ); i++;  
  16430.     XtSetArg (args[i], XtNtranslations     , (XtArgVal) translations); i++;  
  16431.     XtSetArg (args[i], XtNfont             , (XtArgVal) reses.fptr  ); i++;
  16432.     d_text     = XtCreateManagedWidget ("text"     , asciiTextWidgetClass,
  16433.                     d_form     , args, i);
  16434.     
  16435.     i = 0;
  16436.     XtSetArg (args[i], XtNfromVert         , (XtArgVal) d_text      ); i++;  
  16437.     XtSetArg (args[i], XtNwidth            , (XtArgVal) 160         ); i++;  
  16438.     XtSetArg (args[i], XtNfont             , (XtArgVal) reses.fptr  ); i++;
  16439. #ifndef NO_EXTENSION
  16440.     XtSetArg (args[i], XtNshapeStyle       , (XtArgVal) XmuShapeOval); i++;  
  16441. #endif
  16442.     d_cancel   = XtCreateManagedWidget ("cancel"   , commandWidgetClass,
  16443.                     d_form     , args, i);
  16444.     
  16445.     i = 0;
  16446.     XtSetArg (args[i], XtNfromVert         , (XtArgVal) d_text      ); i++;  
  16447.     XtSetArg (args[i], XtNfromHoriz        , (XtArgVal) d_cancel    ); i++;  
  16448.     XtSetArg (args[i], XtNwidth            , (XtArgVal) 160         ); i++;  
  16449.     XtSetArg (args[i], XtNfont             , (XtArgVal) reses.fptr  ); i++;
  16450. #ifndef NO_EXTENSION
  16451.     XtSetArg (args[i], XtNshapeStyle       , (XtArgVal) XmuShapeOval); i++;  
  16452. #endif
  16453.     d_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass,
  16454.                     d_form     , args, i);
  16455.     
  16456.     XtAddCallback (d_cancel , XtNcallback, dialogCancel , NULL);
  16457.     XtAddCallback (d_confirm, XtNcallback, dialogConfirm, NULL);
  16458.  
  16459.     XtRealizeWidget (d_top);
  16460.  
  16461.     /*
  16462.      *    Ask Window.
  16463.      */
  16464.      
  16465.     a_top      = XtCreatePopupShell    ("ask"      , transientShellWidgetClass,
  16466.                     toplevel   , NULL, 0);
  16467.     
  16468.     i = 0;
  16469.     XtSetArg (args[i], XtNdefaultDistance, (XtArgVal) 12          ); i++;  
  16470.     XtSetArg (args[i], XtNtranslations   , (XtArgVal) translations); i++;  
  16471.     a_form     = XtCreateManagedWidget ("form"     , formWidgetClass,
  16472.                     a_top        , args, i);
  16473.     
  16474.     i = 0;
  16475.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 334         ); i++;  
  16476.     XtSetArg (args[i], XtNheight         , (XtArgVal) 30          ); i++;  
  16477.     XtSetArg (args[i], XtNborderWidth    , (XtArgVal) 0           ); i++;  
  16478.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16479.     a_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass,
  16480.                     a_form     , args, i);
  16481.     
  16482.     i = 0;
  16483.     XtSetArg (args[i], XtNfromVert       , (XtArgVal) a_msg       ); i++;  
  16484.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 160         ); i++;  
  16485.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16486. #ifndef NO_EXTENSION
  16487.     XtSetArg (args[i], XtNshapeStyle     , (XtArgVal) XmuShapeOval); i++;  
  16488. #endif
  16489.     a_cancel   = XtCreateManagedWidget ("cancel"   , commandWidgetClass,
  16490.                     a_form     , args, i);
  16491.     
  16492.     i = 0;
  16493.     XtSetArg (args[i], XtNfromVert       , (XtArgVal) a_msg       ); i++;  
  16494.     XtSetArg (args[i], XtNfromHoriz      , (XtArgVal) a_cancel    ); i++;  
  16495.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 160         ); i++;  
  16496.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16497. #ifndef NO_EXTENSION
  16498.     XtSetArg (args[i], XtNshapeStyle     , (XtArgVal) XmuShapeOval); i++;  
  16499. #endif
  16500.     a_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass,
  16501.                     a_form   , args, i);
  16502.     
  16503.     XtAddCallback (a_cancel , XtNcallback, dialogCancel , NULL);
  16504.     XtAddCallback (a_confirm, XtNcallback, dialogConfirm, NULL);
  16505.     
  16506.     XtRealizeWidget (a_top);
  16507.  
  16508.     /*
  16509.      *    Warning Window.
  16510.      */
  16511.     
  16512.     translations = XtParseTranslationTable 
  16513.       ("#override                    \
  16514.         <BtnDown>  : dialogCancel()  \n\
  16515.         <Key>      : dialogCancel()");
  16516.     
  16517.     w_top     = XtCreatePopupShell     ("warning"  , transientShellWidgetClass,
  16518.                     toplevel   , NULL, 0);
  16519.      
  16520.     i = 0;
  16521.     XtSetArg (args[i], XtNdefaultDistance, (XtArgVal) 12          ); i++;  
  16522.     XtSetArg (args[i], XtNtranslations   , (XtArgVal) translations); i++;  
  16523.     w_form     = XtCreateManagedWidget ("form"     , formWidgetClass,
  16524.                     w_top      , args, i);
  16525.     
  16526.     i = 0;
  16527.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 334         ); i++;  
  16528.     XtSetArg (args[i], XtNheight         , (XtArgVal) 30          ); i++;  
  16529.     XtSetArg (args[i], XtNborderWidth    , (XtArgVal) 0           ); i++;  
  16530.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16531.     w_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass,
  16532.                     w_form     , args, i);
  16533.     
  16534.     i = 0;
  16535.     XtSetArg (args[i], XtNfromVert       , (XtArgVal) w_msg       ); i++;  
  16536.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 160         ); i++;  
  16537.     XtSetArg (args[i], XtNhorizDistance  , (XtArgVal) 90          ); i++;  
  16538.     XtSetArg (args[i], XtNlabel          , (XtArgVal) "Continue"  ); i++;  
  16539.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16540. #ifndef NO_EXTENSION
  16541.     XtSetArg (args[i], XtNshapeStyle     , (XtArgVal) XmuShapeOval); i++;  
  16542. #endif
  16543.     w_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass,
  16544.                     w_form     , args, i);
  16545.     
  16546.     XtAddCallback (w_confirm, XtNcallback, dialogCancel, NULL);
  16547.  
  16548.     XtRealizeWidget (w_top);
  16549.  
  16550.     /*
  16551.      *    Choice Window.
  16552.      */
  16553.     
  16554.     translations = XtParseTranslationTable 
  16555.       ("#override                    \
  16556.         <BtnDown>  : dialogCancel()  \n\
  16557.         <Key>      : dialogCancel()");
  16558.     
  16559.     c_top     = XtCreatePopupShell     ("choice"   , transientShellWidgetClass,
  16560.                     toplevel   , NULL, 0);
  16561.      
  16562.     i = 0;
  16563.     XtSetArg (args[i], XtNdefaultDistance, (XtArgVal) 12          ); i++;  
  16564.     XtSetArg (args[i], XtNtranslations   , (XtArgVal) translations); i++;  
  16565.     c_form     = XtCreateManagedWidget ("form"     , formWidgetClass,
  16566.                     c_top      , args, i);
  16567.     
  16568.     i = 0;
  16569.     XtSetArg (args[i], XtNwidth          , (XtArgVal) 334         ); i++;  
  16570.     XtSetArg (args[i], XtNborderWidth    , (XtArgVal) 0           ); i++;  
  16571.     XtSetArg (args[i], XtNfont           , (XtArgVal) reses.fptr  ); i++;
  16572.     c_msg      = XtCreateManagedWidget ("Edit which item?", labelWidgetClass,
  16573.                     c_form            , args, i);
  16574.    
  16575.     for (j = 0; choice[j]; j++) {
  16576.         i = 0;
  16577.         if (j >= 2) {
  16578.             XtSetArg (args[i], XtNfromVert  , (XtArgVal) c_buttons[j-2]); i++;
  16579.     } else {
  16580.             XtSetArg (args[i], XtNfromVert  , (XtArgVal) c_msg         ); i++;
  16581.         }
  16582.     if (j & 1) {
  16583.             XtSetArg (args[i], XtNfromHoriz , (XtArgVal) c_buttons[j-1]); i++;
  16584.     }
  16585.         XtSetArg (args[i]    , XtNwidth     , (XtArgVal) 160           ); i++;
  16586.         XtSetArg (args[i]    , XtNfont      , (XtArgVal) reses.fptr    ); i++;
  16587. #ifndef NO_EXTENSION
  16588.         XtSetArg (args[i]    , XtNshapeStyle, (XtArgVal) XmuShapeOval  ); i++;
  16589. #endif
  16590.         c_buttons[j] = XtCreateManagedWidget (choice[j], commandWidgetClass,
  16591.                           c_form   , args, i);
  16592.         if (choice[j+1])
  16593.             XtAddCallback (c_buttons[j], XtNcallback, DoDialogButton, j+1);
  16594.     else
  16595.             XtAddCallback (c_buttons[j], XtNcallback, DoDialogButton, 0);
  16596.     }
  16597.     
  16598.     XtRealizeWidget (c_top);
  16599. }
  16600.  
  16601. void ClearText(w)
  16602. Widget w;
  16603. {
  16604.     SetText(w, "");
  16605. }
  16606.  
  16607. void SetText(w, str)
  16608. AsciiWidget w;
  16609. char *str;
  16610. {
  16611.     int i;
  16612.     Arg args[10];
  16613.  
  16614.     i = 0;
  16615.     XtSetArg(args[i], XtNstring, str); i++;
  16616.     XtSetValues(w, args, i);
  16617. }
  16618.  
  16619. void GetSize(w, width, height)
  16620. Widget w;
  16621. Dimension *width, *height;
  16622. {
  16623.     int i;
  16624.     Arg args[10];
  16625.  
  16626.     i = 0;
  16627.     XtSetArg(args[i], XtNwidth,  width);  i++;
  16628.     XtSetArg(args[i], XtNheight, height); i++;
  16629.     XtGetValues(w, args, i);
  16630. }
  16631.  
  16632. void format(p1, p2, maxcol)
  16633. char *p1, *p2;
  16634. int maxcol;
  16635. {
  16636.     int count;
  16637.     char *p3;
  16638.  
  16639.     if (p1 == NULL) {
  16640.     *p2 = '\0';
  16641.     return;
  16642.     }
  16643.  
  16644.     /*  Reformat *p1 into *p2 so that the string is properly wordwrapped  */
  16645.     for (count = 0; *p1; p1++, p2++) {
  16646.     *p2 = *p1;
  16647.     count++;
  16648.     if (*p2 == ' ')
  16649.         p3 = p2;
  16650.     if (*p2 == '\n') {
  16651.         p3 = p2;
  16652.         count = 0;
  16653.     }
  16654.     if (count > maxcol) {
  16655.         *p3 = '\n';
  16656.         count = p2 - p3;
  16657.     }
  16658.     }
  16659.     *p2 = '\0';
  16660. }
  16661.  
  16662. int DoPopupShell(parent, title, query, option)
  16663. Widget parent;
  16664. char   *title;
  16665. char   *query;
  16666. XtGrabKind option;
  16667. {
  16668.     String str;
  16669.     Position x, y;
  16670.     Dimension width, height;
  16671.     Arg arg[10];
  16672.     int i;
  16673.     XfwfFileSelectorStatusStruct ss;
  16674.  
  16675.     /*    get the coords of the middle of parent widget    */
  16676.     GetSize(parent, &width, &height);
  16677.  
  16678.     /*    translate coords in application top-level window    */
  16679.     /*    into coords from root window origin.            */
  16680.     XtTranslateCoords(parent,
  16681.               (Position) width/4,
  16682.               (Position) height/4,
  16683.               &x,
  16684.               &y);
  16685.  
  16686.     switch (mode) {
  16687.     case LoadFileBox:
  16688.     case SaveFileBox:
  16689.         XtTranslateCoords(parent,(Position)width/8,(Position)height/4,&x,&y);
  16690.     pshell = f_top;
  16691.         XtSetArg(arg[0], XtNlabel, title);
  16692.         XtSetValues(f_msg, arg, 1);
  16693.     /*  re-read the current directory and refresh the widget  */
  16694.     XfwfFileSelectorGetStatus(f_sel, &ss);
  16695.     XfwfFileSelectorChangeDirectory(f_sel, ss.path);
  16696.     break;
  16697.     case DialogBox:
  16698.     pshell = d_top;
  16699.         XtSetArg(arg[0], XtNlabel, title);
  16700.         XtSetValues(d_msg, arg, 1);
  16701.         XtSetArg(arg[0], XtNstring, "");
  16702.         XtSetValues(d_text, arg, 1);
  16703.     break;
  16704.     case AskBox:
  16705.     pshell = a_top;
  16706.         XtSetArg(arg[0], XtNlabel, title);
  16707.         XtSetValues(a_msg, arg, 1);
  16708.     break;
  16709.     case WarningBox:
  16710.     pshell = w_top;
  16711.         XtSetArg(arg[0], XtNlabel, title);
  16712.         XtSetValues(w_msg, arg, 1);
  16713.     break;
  16714.     case ChoiceBox:
  16715.     pshell = c_top;
  16716.     break;
  16717.     }
  16718.     i = 0;
  16719.     XtSetArg(arg[i], XtNx,        x);    i++;
  16720.     XtSetArg(arg[i], XtNy,        y);    i++;
  16721.     XtSetValues(pshell, arg, i);
  16722.  
  16723.     XtPopup(pshell, option);
  16724.  
  16725.     while(!done){ 
  16726.     XEvent  evnt;
  16727.     
  16728.     XtAppNextEvent(app_context, &evnt);
  16729.     XtDispatchEvent(&evnt);
  16730.     }
  16731.     done = NO;
  16732.  
  16733.     if ((mode == LoadFileBox || mode == SaveFileBox) && (code == YES)) {
  16734.     XfwfFileSelectorGetStatus(f_sel, &ss);
  16735.     strcpy(query, ss.path);
  16736.     strcat(query, ss.file_box_text);
  16737.     } else if ((mode == DialogBox) && (code == YES)) {
  16738.         XtSetArg(arg[0], XtNstring, &str);
  16739.         XtGetValues(d_text, arg, 1);
  16740.     strcpy(query, str);
  16741.     }
  16742.     
  16743.     return code;
  16744. }
  16745.  
  16746. int DoDialog(parent, title, query)
  16747. Widget parent;
  16748. char   *title;
  16749. char   *query;
  16750. {
  16751. #ifdef XMGT_HFS
  16752.     if (strcmp(title, "Load file? ") == 0) {
  16753.     mode = LoadFileBox;
  16754.         return DoPopupShell(parent, title, query, XtGrabNonexclusive);
  16755.     } else if (strcmp(title, "Save name? ") == 0) {
  16756.     mode = SaveFileBox;
  16757.         return DoPopupShell(parent, title, query, XtGrabNonexclusive);
  16758.     } else if (strcmp(title, "Save screen: ") == 0) {
  16759.     mode = SaveFileBox;
  16760.         return DoPopupShell(parent, title, query, XtGrabNonexclusive);
  16761.     } else {
  16762.     mode = DialogBox;
  16763.         return DoPopupShell(parent, title, query, XtGrabNonexclusive);
  16764.     }
  16765. #else
  16766.     mode = DialogBox;
  16767.     return DoPopupShell(parent, title, query, XtGrabNonexclusive);
  16768. #endif /* XMGT_HFS */
  16769. }
  16770.  
  16771. int DoAsk(parent, title)
  16772. Widget parent;
  16773. char   *title;
  16774. {
  16775.     mode = AskBox;
  16776.     return DoPopupShell(parent, title, NULL, XtGrabNonexclusive);
  16777. }
  16778.  
  16779. int DoAsk2(parent, title, option)
  16780. Widget parent;
  16781. char   *title;
  16782. XtGrabKind option;
  16783. {
  16784.     mode = AskBox;
  16785.     return DoPopupShell(parent, title, NULL, option);
  16786. }
  16787.  
  16788. void DoWarning(parent, errmsg)
  16789. Widget parent;
  16790. char*  errmsg;
  16791. {
  16792.     mode = WarningBox;
  16793.     DoPopupShell(parent, errmsg, NULL , XtGrabNonexclusive);
  16794. }
  16795.  
  16796. int DoChoice(parent)
  16797. Widget parent;
  16798. {
  16799.     mode = ChoiceBox;
  16800.     return DoPopupShell(parent, NULL , NULL , XtGrabNonexclusive);
  16801. }
  16802.  
  16803. SHAR_EOF
  16804. fi
  16805. if test -f 'xutil.h'
  16806. then
  16807.     echo shar: "will not over-write existing file 'xutil.h'"
  16808. else
  16809. cat << \SHAR_EOF > 'xutil.h'
  16810. /*  xutil.h
  16811.  *
  16812.  *  Copyright (c) 1992 by Chien-Min Wang and Tim Casey.
  16813.  *  All rights reserved.
  16814.  */
  16815.  
  16816. #define    YES    1
  16817. #define    NO    0
  16818.  
  16819. #define    DialogBox    1
  16820. #define    AskBox        2
  16821. #define WarningBox    3
  16822. #define ChoiceBox    4
  16823. #define LoadFileBox    5
  16824. #define SaveFileBox    6
  16825.  
  16826. typedef struct {
  16827.     char *name;
  16828.     char *callback;
  16829.     caddr_t cmd;
  16830.     Widget w;
  16831. } Buttons;
  16832.  
  16833. typedef struct {
  16834.     int comm_wd, comm_ht, note_wd, note_ht, var_wd, but_wd, men_wd;
  16835.     XFontStruct *fptr;
  16836. } Res, *ResPtr;
  16837.  
  16838. void format();
  16839. void ClearText();
  16840. void SetText();
  16841. void CreateDialog();
  16842. int  DoDialog();
  16843. int  DoAsk();
  16844. int  DoAsk2();
  16845. void DoWarning();
  16846. int  DoChoice();
  16847.  
  16848. SHAR_EOF
  16849. fi
  16850. exit 0
  16851. #    End of shell archive
  16852.