home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xgoban10.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  315.8 KB  |  10,719 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 the files:
  6. #    Goban.c
  7. #    node.c
  8. #    sg.c
  9. #    read.c
  10. #    write.c
  11. #    play.c
  12. #    event.c
  13. #    dialog.c
  14. #    xgoban.c
  15. #    action.c
  16. #    misc.c
  17. #    display.c
  18. #    game.c
  19. #    blackstone.bm
  20. #    graystone.bm
  21. #    stonemask.bm
  22. #    whitestone.bm
  23. #    icon.bm
  24. #    Goban.h
  25. #    GobanP.h
  26. #    sg.h
  27. #    xgoban.h
  28. #    Goban.doc
  29. #    xgoban.doc
  30. #    xgoban.man
  31. #    xgoban.6
  32. #    xgoban.ad
  33. #    README
  34. #    CHANGE.Goban
  35. #    Imakefile
  36. #    xmailgo
  37. #    mailgo.6
  38. # This archive created: Wed Jul  8 08:46:20 1992
  39. export PATH; PATH=/bin:$PATH
  40. if test -f 'Goban.c'
  41. then
  42.     echo shar: will not over-write existing file "'Goban.c'"
  43. else
  44. cat << \SHAR_EOF > 'Goban.c'
  45. /****************************************************************************************************************
  46.  *
  47.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  48.  *
  49.  *  This program is distributed in the hope that it will be useful.
  50.  *  Use and copying of this software and preparation of derivative works
  51.  *  based upon this software are permitted, so long as the following
  52.  *  conditions are met:
  53.  *       o credit to the authors is acknowledged following current
  54.  *         academic behaviour
  55.  *       o no fees or compensation are charged for use, copies, or
  56.  *         access to this software
  57.  *       o this copyright notice is included intact.
  58.  *  This software is made available AS IS, and no warranty is made about 
  59.  *  the software or its performance. 
  60.  * 
  61.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  62.  *  Send them to    dumesnil@etca.fr   or to:
  63.  *       
  64.  *       Antoine de Maricourt
  65.  *       ETCA CREA-SP
  66.  *       16 bis, avenue Prieur de la Cote d'Or
  67.  *       94114 Arcueil Cedex
  68.  *       France
  69.  */
  70.  
  71. #include <X11/IntrinsicP.h>
  72. #include <X11/StringDefs.h>
  73. #include <X11/Xlib.h>
  74. #include <X11/cursorfont.h>
  75.  
  76. #include "GobanP.h"
  77.  
  78. #include "whitestone.bm"
  79. #include "blackstone.bm"
  80. #include "graystone.bm"
  81. #include "stonemask.bm"
  82.  
  83. #define offset(field) XtOffset (GobanWidget, goban.field)
  84.  
  85. static XtResource resources[] = {
  86.   { XtNautoRedisplay     , XtCAutoRedisplay     , XtRBoolean   , sizeof (Boolean)      ,
  87.       offset (auto_redisplay)     , XtRImmediate     , (caddr_t) TRUE         },
  88.   { XtNviewBottom        , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  89.       offset (bottom)             , XtRImmediate     , (caddr_t) 1            },
  90.   { XtNcursor            , XtCCursor            , XtRInt       , sizeof (int)          ,
  91.       offset (cursor)             , XtRImmediate     , (caddr_t) GbCGrayStone },
  92.   { XtNfont              , XtCFont              , XtRFontStruct, sizeof (XFontStruct *),
  93.       offset (font)               , XtRString        , "fixed"                },
  94.   { XtNforeground        , XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  95.       offset (foreground)         , XtRString   , XtDefaultForeground    },
  96.   { XtNgameSize          , XtCSize              , XtRDimension , sizeof (Dimension)    ,
  97.       offset (game_size)          , XtRImmediate, (caddr_t) 19           },
  98.   { XtNviewLeft          , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  99.       offset (left)               , XtRImmediate, (caddr_t) 1            },
  100.   { XtNdisplayCoordinates, XtCDisplayCoordinates, XtRBoolean   , sizeof (Boolean)      ,
  101.       offset (display_coordinates), XtRImmediate, (caddr_t) TRUE         },
  102.   { XtNpointSize         , XtCSize              , XtRDimension , sizeof (Dimension)    ,
  103.       offset (point_size)         , XtRImmediate     , (caddr_t) 26           },
  104.   { XtNviewRight         , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  105.       offset (right)              , XtRImmediate     , (caddr_t) 19           },
  106.   { XtNviewTop           , XtCPosition          , XtRPosition  , sizeof (Position)     , 
  107.       offset (top)                , XtRImmediate     , (caddr_t) 19           },
  108.   { XtNwhiteStoneForeground, XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  109.       offset (white_fg)           , XtRString   , "black"    },
  110.   { XtNwhiteStoneBackground, XtCBackground        , XtRPixel     , sizeof (Pixel)        ,
  111.       offset (white_bg)           , XtRString   , "white"    },
  112.   { XtNwhiteStoneBorder    , XtCBorderColor       , XtRPixel     , sizeof (Pixel)        ,
  113.       offset (white_bd)           , XtRString   , "black"    },
  114.   { XtNblackStoneForeground, XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  115.       offset (black_fg)           , XtRString   , "white"    },
  116.   { XtNblackStoneBackground, XtCBackground        , XtRPixel     , sizeof (Pixel)        ,
  117.       offset (black_bg)           , XtRString   , "black"    },
  118.   { XtNblackStoneBorder    , XtCBorderColor       , XtRPixel     , sizeof (Pixel)        ,
  119.       offset (black_bd)           , XtRString   , "black"    },
  120. };
  121.  
  122. static void    ClassInitialize ();
  123. static void    Initialize      ();
  124. static void    Redisplay       ();
  125. static void    Realize         ();
  126. static void    Destroy         ();
  127. static void    Resize          ();
  128. static void    DrawPoint       ();
  129. static Boolean SetValues       ();
  130.  
  131. GobanClassRec gobanClassRec = {
  132.   { /* core fields */
  133.     /* superclass        */    (WidgetClass) &widgetClassRec,
  134.     /* class_name        */    "Goban",
  135.     /* widget_size        */    sizeof (GobanRec),
  136.     /* class_initialize        */    ClassInitialize,
  137.     /* class_part_initialize    */    NULL,
  138.     /* class_inited        */    FALSE,
  139.     /* initialize        */    Initialize,
  140.     /* initialize_hook        */    NULL,
  141.     /* realize            */    Realize,
  142.     /* actions            */    NULL,
  143.     /* num_actions        */    0,
  144.     /* resources        */    resources,
  145.     /* num_resources        */    XtNumber (resources),
  146.     /* xrm_class        */    NULLQUARK,
  147.     /* compress_motion        */    TRUE,
  148.     /* compress_exposure    */    TRUE,
  149.     /* compress_enterleave    */    TRUE,
  150.     /* visible_interest        */    FALSE,
  151.     /* destroy            */    Destroy,
  152.     /* resize            */    Resize,
  153.     /* expose            */    Redisplay,
  154.     /* set_values        */    SetValues,
  155.     /* set_values_hook        */    NULL,
  156.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  157.     /* get_values_hook        */    NULL,
  158.     /* accept_focus        */    NULL,
  159.     /* version            */    XtVersion,
  160.     /* callback_private        */    NULL,
  161.     /* tm_table            */    NULL,
  162.     /* query_geometry        */    XtInheritQueryGeometry,
  163.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  164.     /* extension        */    NULL
  165.   }
  166. };
  167.  
  168. WidgetClass gobanWidgetClass = (WidgetClass) &gobanClassRec;
  169.  
  170. /****************************************************************************************************************
  171.  */
  172.  
  173. void GbRedisplayBoard (w)
  174. Widget w;
  175. {
  176.   GobanWidget gw      = (GobanWidget) w;
  177.   Dimension   width   = w->core.width;
  178.   Dimension   height  = w->core.height;
  179.  
  180.   if (XtIsRealized (w))
  181.     XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, 0, 0, width, height, 0, 0);
  182. }
  183.  
  184. /****************************************************************************************************************
  185.  */
  186.  
  187. void GbClearBoard (w)
  188. Widget w;
  189. {
  190.   GobanWidget gw        = (GobanWidget) w;
  191.   Boolean     redisplay = gw->goban.auto_redisplay;
  192.   Position    x;
  193.   Position    y;
  194.  
  195.   gw->goban.auto_redisplay = FALSE;
  196.  
  197.   for (x = 1; x <= gw->goban.game_size; x++)
  198.     for (y = 1; y <= gw->goban.game_size; y++)
  199.       GbSetPoint (w, x, y, GbEmptyPoint);
  200.  
  201.   gw->goban.auto_redisplay = redisplay;
  202.  
  203.   if (redisplay == TRUE)
  204.     GbRedisplayBoard (w);
  205. }
  206.  
  207. /****************************************************************************************************************
  208.  */
  209.  
  210. void GbClearMarks (w)
  211. Widget w;
  212. {
  213.   GobanWidget gw        = (GobanWidget) w;
  214.   Boolean     redisplay = gw->goban.auto_redisplay;
  215.   Position    x;
  216.   Position    y;
  217.  
  218.   gw->goban.auto_redisplay = FALSE;
  219.  
  220.   for (x = 1; x <= gw->goban.game_size; x++)
  221.     for (y = 1; y <= gw->goban.game_size; y++) {
  222.  
  223.       gw->goban.points[x][y].mark1 = 0;
  224.       gw->goban.points[x][y].mark2 = 0;
  225.       gw->goban.points[x][y].num   = 0;
  226.     
  227.       if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
  228.     if (gw->goban.points[x][y].free == 1)
  229.       DrawPoint (w, x, y, GbEmptyPoint);
  230.     else
  231.       if (gw->goban.points[x][y].black == 1)
  232.         DrawPoint (w, x, y, GbBlackStone);
  233.       else
  234.         DrawPoint (w, x, y, GbWhiteStone);
  235.     }
  236.  
  237.   gw->goban.auto_redisplay = redisplay;
  238.  
  239.   if (redisplay == TRUE)
  240.     GbRedisplayBoard (w);
  241. }
  242.  
  243. /****************************************************************************************************************
  244.  */
  245.  
  246. /* ARGSUSED */
  247.  
  248. void GbSetPoint (w, x, y, color)
  249. Widget       w;
  250. Position     x;
  251. Position     y;
  252. GbPointState color;
  253. {
  254.   GobanWidget gw = (GobanWidget) w;
  255.  
  256.   if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  257.     switch (color) {
  258.  
  259.     case GbBlackStone :
  260.       gw->goban.points[x][y].free  = 0;
  261.       gw->goban.points[x][y].black = 1;
  262.       break;
  263.  
  264.     case GbWhiteStone :
  265.       gw->goban.points[x][y].free  = 0;
  266.       gw->goban.points[x][y].black = 0;
  267.       break;
  268.  
  269.     case GbEmptyPoint :
  270.       gw->goban.points[x][y].free  = 1;
  271.       break;
  272.     }
  273.     
  274.     gw->goban.points[x][y].num   = 0;
  275.     gw->goban.points[x][y].mark1 = 0;
  276.     gw->goban.points[x][y].mark2 = 0;
  277.  
  278.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
  279.       DrawPoint (w, x, y, color);
  280.   }
  281. }
  282.  
  283. /****************************************************************************************************************
  284.  */
  285.  
  286. /* ARGSUSED */
  287.  
  288. Boolean GbGetPositionFromStone (w, x, y)
  289. GobanWidget   w;
  290. Position     *x;
  291. Position     *y;
  292. {
  293.   if (*x >= w->goban.left && *y >= w->goban.bottom && *x <= w->goban.right && *y <= w->goban.top) {
  294.     
  295.     *x = ((w->goban.x_offset + w->goban.point_size * *x) * 2 + w->goban.point_size) / 2;
  296.     *y = ((w->goban.y_offset - w->goban.point_size * *y) * 2 + w->goban.point_size) / 2;
  297.     
  298.     return TRUE;
  299.   }
  300.   
  301.   else 
  302.     return FALSE;
  303. }
  304.  
  305. /****************************************************************************************************************
  306.  */
  307.  
  308. /* ARGSUSED */
  309.  
  310. Boolean GbGetStoneFromPosition (w, x, y)
  311. Widget     w;
  312. Position  *x;
  313. Position  *y;
  314. {
  315.   GobanWidget gw         = (GobanWidget) w;
  316.   Dimension   point_size = gw->goban.point_size;
  317.   Position    xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  318.   Position    ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  319.   Position    xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  320.   Position    ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  321.  
  322.   if (*x > xmin && *x < xmax && *y > ymin && *y < ymax) {
  323.  
  324.     *x = (*x - gw->goban.x_offset - 1) / point_size;
  325.     *y = (gw->goban.y_offset - *y + point_size + 1) / point_size;
  326.  
  327.     return TRUE;
  328.   }
  329.  
  330.   return FALSE;
  331. }
  332.  
  333. /****************************************************************************************************************
  334.  */
  335.  
  336. void GbSetNum (w, x, y, num)
  337. Widget      w;
  338. Position    x;
  339. Position    y;
  340. int         num;
  341. {
  342.   GobanWidget  gw      = (GobanWidget) w;
  343.   Display     *display = XtDisplay (w);
  344.   GC           draw_gc;
  345.   GC           undraw_gc;
  346.   XCharStruct  extent;
  347.   XExposeEvent event;
  348.   int          ascent;
  349.   int          descent;
  350.   int          direction;
  351.   int          X;
  352.   int          Y;
  353.   char         s[3];
  354.   int          len = 0;
  355.  
  356.   if (num >= 0 && num <= 999 && x >= 1 && y >= 1  && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  357.     
  358.     gw->goban.points[x][y].num   = num;
  359.     gw->goban.points[x][y].mark1 = 0;
  360.     gw->goban.points[x][y].mark2 = 0;
  361.     
  362.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
  363.       
  364.       if (gw->goban.points[x][y].free == 0) {
  365.     
  366.     if (num == 0) {
  367.       if (gw->goban.points[x][y].black == 1)
  368.         DrawPoint (w, x, y, GbBlackStone);
  369.       else
  370.         DrawPoint (w, x, y, GbWhiteStone);
  371.     }
  372.     
  373.     else {
  374.       if (gw->goban.points[x][y].black == 1) {
  375.         draw_gc   = gw->goban.black_fg_gc;
  376.         undraw_gc = gw->goban.black_bg_gc;
  377.       } else {
  378.         draw_gc   = gw->goban.white_fg_gc;
  379.         undraw_gc = gw->goban.white_bg_gc;
  380.       }
  381.       
  382.       X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
  383.       Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
  384.       
  385.       if (num > 99)
  386.         s[len++] = '0' + (num % 1000) / 100;
  387.       if (num > 9)
  388.         s[len++] = '0' + (num % 100) / 10;
  389.       s[len++] = '0' + num % 10;
  390.       
  391.       XQueryTextExtents (display, XGContextFromGC (draw_gc),
  392.                  s, len, &direction, &ascent, &descent, &extent);
  393.       
  394.       if (extent.width + extent.descent + extent.ascent < gw->goban.point_size - 1) {
  395.         XFillArc (display, gw->goban.picture, undraw_gc, 
  396.               (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  397.               (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  398.               0, 360 * 64);
  399.         XDrawString (display, gw->goban.picture, draw_gc,
  400.              (X - extent.width) / 2 - extent.lbearing + 1, 
  401.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  402.       }
  403.     
  404.       if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  405.         event.x      = (X - gw->goban.point_size) / 2;
  406.         event.y      = (Y - gw->goban.point_size) / 2;
  407.         event.width  = gw->goban.point_size;
  408.         event.height = gw->goban.point_size;
  409.         
  410.         Redisplay (w, &event, (Region) NULL);
  411.       }
  412.     }
  413.       }
  414.     }
  415.   }
  416. }
  417.  
  418. /****************************************************************************************************************
  419.  */
  420.  
  421. void GbSetMark (w, x, y, c1, c2)
  422. Widget        w;
  423. Position      x;
  424. Position      y;
  425. unsigned char c1;
  426. unsigned char c2;
  427. {
  428.   GobanWidget  gw      = (GobanWidget) w;
  429.   Display     *display = XtDisplay (w);
  430.   int          len     = 0;
  431.   XCharStruct  extent;
  432.   XExposeEvent event;
  433.   int          ascent;
  434.   int          descent;
  435.   int          direction;
  436.   int          X;
  437.   int          Y;
  438.   int          radius;
  439.   char         s[2];
  440.   XSegment     segment[4];
  441.   GC           mark_gc;
  442.   GC           erase_gc;
  443.   
  444.   if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  445.    
  446.     if (c1 != 0 || c2 != 0)
  447.       GbSetMark (w, x, y, 0, 0);
  448.      
  449.     gw->goban.points[x][y].mark1 = c1;
  450.     gw->goban.points[x][y].mark2 = c2;
  451.     gw->goban.points[x][y].num   = 0;
  452.  
  453.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
  454.       
  455.       if (c1 == 0 && c2 == 0) {
  456.     if (gw->goban.points[x][y].free == 0)
  457.       if (gw->goban.points[x][y].black == 1)
  458.         DrawPoint (w, x, y, GbBlackStone);
  459.       else
  460.         DrawPoint (w, x, y, GbWhiteStone);
  461.     else
  462.       DrawPoint (w, x, y, GbEmptyPoint);
  463.       }
  464.       
  465.       else {
  466.     X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
  467.     Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
  468.               
  469.     if (gw->goban.points[x][y].free == 0)
  470.       if (gw->goban.points[x][y].black == 1) {
  471.         mark_gc  = gw->goban.black_fg_gc;
  472.         erase_gc = gw->goban.black_bg_gc;
  473.       }
  474.       else {
  475.         mark_gc  = gw->goban.white_fg_gc;
  476.         erase_gc = gw->goban.white_bg_gc;
  477.       }
  478.  
  479.     else {
  480.       mark_gc  = gw->goban.foreground_gc;
  481.       erase_gc = gw->goban.background_gc;
  482.     }
  483.     
  484.     if (c1 == 0) {
  485.       radius = 10 * gw->goban.point_size / 15;
  486.       
  487.       if (gw->goban.points[x][y].free == 0)
  488.           XFillArc (display, gw->goban.picture, erase_gc, 
  489.             (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  490.             (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  491.             0, 360 * 64);
  492.       else
  493.         XFillArc (display, gw->goban.picture, erase_gc,
  494.               (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  495.               (unsigned int) radius, (unsigned int) radius, 
  496.               0, 360 * 64);
  497.  
  498.       switch (c2) {
  499.         
  500.       case GbMTriangleMark :
  501.         radius -= 4;
  502.  
  503.         segment[0].x1 = (short) X / 2;
  504.         segment[0].x2 = (short) (X / 2 + (86 * radius + 100) / 200);
  505.         segment[0].y1 = (short) (Y / 2 - (radius - 1) / 2);
  506.         segment[0].y2 = (short) (Y / 2 + (radius + 4) / 4);
  507.         
  508.         segment[1].x1 = (short) segment[0].x2;
  509.         segment[1].x2 = (short) (X / 2 - (86 * radius + 100) / 200);
  510.         segment[1].y1 = (short) segment[0].y2;
  511.         segment[1].y2 = (short) (Y / 2 + (radius + 4) / 4);
  512.         
  513.         segment[2].x1 = (short) segment[1].x2;
  514.         segment[2].x2 = (short) segment[0].x1;
  515.         segment[2].y1 = (short) segment[1].y2;
  516.         segment[2].y2 = (short) segment[0].y1;
  517.  
  518.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 3);
  519.         break;
  520.  
  521.       case GbMSquareMark  :
  522.         radius = 10 * radius / 14 - 2;
  523.         
  524.         XDrawRectangle (display, gw->goban.picture, mark_gc, 
  525.                 (X - radius) / 2, (Y - radius) / 2, 
  526.                 (unsigned int) radius, (unsigned int) radius);
  527.         break;
  528.     
  529.       case GbMDCrossMark  :
  530.         radius = 10 * radius / 14 - 2;
  531.  
  532.         segment[0].x1 = (short) (X - radius) / 2;
  533.         segment[0].x2 = (short) segment[0].x1    + radius;
  534.         segment[0].y1 = (short) (Y - radius) / 2;
  535.         segment[0].y2 = (short) segment[0].y1    + radius;
  536.  
  537.         segment[1].x1 = (short) (X - radius) / 2 + radius;
  538.         segment[1].x2 = (short) segment[1].x1    - radius;
  539.         segment[1].y1 = (short) (Y - radius) / 2;
  540.         segment[1].y2 = (short) segment[1].y1    + radius;
  541.         
  542.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  543.         break;
  544.         
  545.       case GbMVCrossMark  :
  546.         radius -= 4;
  547.  
  548.         segment[0].x1 = (short) X / 2;
  549.         segment[0].x2 = (short) segment[0].x1;
  550.         segment[0].y1 = (short) (Y - radius) / 2;
  551.         segment[0].y2 = (short) segment[0].y1 + radius;
  552.  
  553.         segment[1].x1 = (short) (X - radius) / 2;
  554.         segment[1].x2 = (short) segment[1].x1 + radius;
  555.         segment[1].y1 = (short) Y / 2;
  556.         segment[1].y2 = (short) segment[1].y1;
  557.         
  558.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  559.         break;
  560.  
  561.       case GbMDiamondMark :
  562.         radius -= 4;
  563.  
  564.         segment[0].x1 = (short) X / 2;
  565.         segment[0].x2 = (short) segment[0].x1 + radius / 2;
  566.         segment[0].y1 = (short) (Y - radius) / 2;
  567.         segment[0].y2 = (short) segment[0].y1 + radius / 2;
  568.  
  569.         segment[1].x1 = (short) segment[0].x2;
  570.         segment[1].x2 = (short) segment[0].x1;
  571.         segment[1].y1 = (short) segment[0].y2;
  572.         segment[1].y2 = (short) segment[1].y1 + radius / 2;
  573.         
  574.         segment[2].x1 = (short) segment[1].x2;
  575.         segment[2].x2 = (short) segment[2].x1 - radius / 2;
  576.         segment[2].y1 = (short) segment[1].y2;
  577.         segment[2].y2 = (short) segment[1].y1;
  578.         
  579.         segment[3].x1 = (short) segment[2].x2;
  580.         segment[3].x2 = (short) segment[0].x1;
  581.         segment[3].y1 = (short) segment[2].y2;
  582.         segment[3].y2 = (short) segment[0].y1;
  583.         
  584.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 4);
  585.         break;
  586.       }
  587.     }
  588.     
  589.     else {
  590.       s[len++] = c1;
  591.       if (c2 != 0)
  592.         s[len++] = c2;
  593.       
  594.       XQueryTextExtents (display, XGContextFromGC (mark_gc), s, len, &direction, &ascent, &descent, &extent);
  595.       
  596.       radius = extent.width + extent.descent + extent.ascent;
  597.       
  598.       if (radius < gw->goban.point_size - 1) {
  599.         if (gw->goban.points[x][y].free == 0)
  600.           XFillArc (display, gw->goban.picture, erase_gc, 
  601.             (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  602.             (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  603.             0, 360 * 64);
  604.         else
  605.           XFillArc (display, gw->goban.picture, erase_gc,
  606.             (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  607.             (unsigned int) radius, (unsigned int) radius, 
  608.             0, 360 * 64);
  609.         
  610.         XDrawString (display, gw->goban.picture, mark_gc,
  611.              (X - extent.width) / 2 - extent.lbearing + 1, 
  612.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  613.       }
  614.     }
  615.       
  616.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  617.       event.x      = (X - gw->goban.point_size) / 2;
  618.       event.y      = (Y - gw->goban.point_size) / 2;
  619.       event.width  = gw->goban.point_size;
  620.       event.height = gw->goban.point_size;
  621.       
  622.       Redisplay (w, &event, (Region) NULL);
  623.     }
  624.       }
  625.     }
  626.   }
  627. }
  628.  
  629. /****************************************************************************************************************
  630.  */
  631.  
  632. /* ARGSUSED */
  633.  
  634. static void Redisplay (w, event, region)
  635. Widget        w;
  636. XExposeEvent *event;
  637. Region        region;
  638. {
  639.   GobanWidget gw     = (GobanWidget) w;
  640.   Position    x      = event->x;
  641.   Position    y      = event->y;
  642.   Dimension   width  = event->width;
  643.   Dimension   height = event->height;
  644.  
  645.   XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, x, y, width, height, x, y);
  646. }
  647.  
  648. /****************************************************************************************************************
  649.  */
  650.  
  651. /* ARGSUSED */
  652.  
  653. static void CvtStringToCursor (args, num_args, fromVal, toVal)
  654. XrmValuePtr   args;        /* unused */
  655. Cardinal     *num_args;    /* unused */
  656. XrmValuePtr   fromVal;
  657. XrmValuePtr   toVal;
  658. {
  659.   static int       cursor;
  660.   static XrmQuark  QWhiteStone;
  661.   static XrmQuark  QBlackStone;
  662.   static XrmQuark  QGrayStone;
  663.   XrmQuark         quark;
  664.   char             lowerName[256];
  665.   static Boolean   inited = FALSE;
  666.     
  667.   if (inited == FALSE) {
  668.     QWhiteStone  = XrmStringToQuark (XtEgbWhiteStone);
  669.     QBlackStone  = XrmStringToQuark (XtEgbBlackStone);
  670.     QGrayStone   = XrmStringToQuark (XtEgbGrayStone);
  671.     inited       = TRUE;
  672.   }
  673.  
  674.   XmuCopyISOLatin1Lowered  (lowerName, (String) fromVal->addr);
  675.   quark = XrmStringToQuark (lowerName);
  676.  
  677.   if (quark == QWhiteStone)
  678.     cursor = GbCWhiteStone;
  679.   else if (quark == QBlackStone)       
  680.     cursor = GbCBlackStone;
  681.   else if (quark == QGrayStone)         
  682.     cursor = GbCGrayStone;
  683.   else {
  684.     toVal->size = 0;
  685.     toVal->addr = NULL;
  686.     return;
  687.   }
  688.  
  689.   toVal->size = sizeof (cursor);
  690.   toVal->addr = (caddr_t) &cursor;
  691. }
  692.  
  693. /****************************************************************************************************************
  694.  */
  695.  
  696. static void ClassInitialize()
  697. {
  698.   XtAddConverter (XtRString, XtRInt, (XtConverter) CvtStringToCursor, NULL, 0);
  699. }
  700.  
  701. /****************************************************************************************************************
  702.  */
  703.  
  704. static void InitializePixmap (w)
  705. Widget w;
  706. {
  707.   GobanWidget  gw      = (GobanWidget) w;
  708.   Display     *display = XtDisplay (w);
  709.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  710.   Dimension    width   = w->core.width;
  711.   Dimension    height  = w->core.height;
  712.  
  713.   gw->goban.board   = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  714.   gw->goban.picture = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  715. }
  716.  
  717. /****************************************************************************************************************
  718.  */
  719.  
  720. static void InitializeGC (w)
  721. Widget w;
  722. {
  723.   GobanWidget  gw      = (GobanWidget) w;
  724.   Display     *display = XtDisplay (w);
  725.   XtGCMask     mask    = GCForeground | GCBackground | GCFont;
  726.   XGCValues    values;
  727.  
  728.   values.font             = gw->goban.font->fid;
  729.   values.background       = w->core.background_pixel;
  730.  
  731.   values.foreground       = gw->goban.white_fg;
  732.   gw->goban.white_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  733.   values.foreground       = gw->goban.white_bg;
  734.   gw->goban.white_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  735.   values.foreground       = gw->goban.white_bd;
  736.   gw->goban.white_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  737.  
  738.   values.foreground       = gw->goban.black_fg;
  739.   gw->goban.black_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  740.   values.foreground       = gw->goban.black_bg;
  741.   gw->goban.black_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  742.   values.foreground       = gw->goban.black_bd;
  743.   gw->goban.black_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  744.  
  745.   values.foreground       = gw->goban.foreground;
  746.   gw->goban.foreground_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  747.  
  748.   if (gw->core.background_pixmap != XtUnspecifiedPixmap) {
  749.     values.tile           = gw->core.background_pixmap;
  750.     values.fill_style     = FillTiled;
  751.     mask                 |= GCTile | GCFillStyle;
  752.   }
  753.  
  754.   values.foreground       = w->core.background_pixel;
  755.   values.background       = gw->goban.foreground;
  756.   gw->goban.background_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  757.  
  758.   gw->goban.copy_gc       = XCreateGC  (display, gw->goban.picture, (XtGCMask) 0, (XGCValues *) NULL);
  759. }
  760.  
  761. /****************************************************************************************************************
  762.  */ 
  763. static void InitializeCursor (w)
  764. Widget w;
  765. {
  766.   GobanWidget  gw      = (GobanWidget) w;
  767.   Display     *display = XtDisplay (w);
  768.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  769.   Pixel        black   = BlackPixel (display, DefaultScreen (display));
  770.   Pixel        white   = WhitePixel (display, DefaultScreen (display));
  771.  
  772.   static XColor black_color = { 0,    0,     0,     0  };  /* black */
  773.   static XColor white_color = { 0, 65535, 65535, 65535 };  /* white */
  774.  
  775.   /* Some teminals invert the mask with BlackPixel and WhitePixel     */
  776.   /* should use black and white instead of 1 and 0 but depth is 1 ... */
  777.   /* will probably have trouble with some special colormaps           */
  778.  
  779.   gw->goban.white_stone = XCreatePixmapFromBitmapData
  780.     (display, window, whitestone_bits, whitestone_width, whitestone_height, 1, 0, 1);
  781.   gw->goban.black_stone = XCreatePixmapFromBitmapData
  782.     (display, window, blackstone_bits, blackstone_width, blackstone_height, 1, 0, 1);
  783.   gw->goban.gray_stone  = XCreatePixmapFromBitmapData
  784.     (display, window, graystone_bits , graystone_width , graystone_height , 1, 0, 1);
  785.   gw->goban.mouse_mask  = XCreatePixmapFromBitmapData
  786.     (display, window, stonemask_bits , stonemask_width , stonemask_height , 1, 0, 1);
  787.  
  788.   gw->goban.white_cursor = 
  789.     XCreatePixmapCursor (display, gw->goban.white_stone, gw->goban.mouse_mask, 
  790.              &black_color, &white_color, whitestone_x_hot, whitestone_y_hot);
  791.   gw->goban.black_cursor = 
  792.     XCreatePixmapCursor (display, gw->goban.black_stone, gw->goban.mouse_mask, 
  793.              &black_color, &white_color, blackstone_x_hot, blackstone_y_hot);
  794.   gw->goban.gray_cursor  = 
  795.     XCreatePixmapCursor (display, gw->goban.gray_stone, gw->goban.mouse_mask,  
  796.              &black_color, &white_color, graystone_x_hot , graystone_y_hot );
  797.  
  798.   gw->goban.font_cursor  = XCreateFontCursor (display, XC_question_arrow);
  799. }
  800.   
  801. /****************************************************************************************************************
  802.  */
  803.  
  804. static void DestroyPixmap (w)
  805. Widget w;
  806. {
  807.   GobanWidget  gw      = (GobanWidget) w;
  808.   Display     *display = XtDisplay (w);
  809.  
  810.   XFreePixmap (display, gw->goban.picture);
  811.   XFreePixmap (display, gw->goban.board  );
  812. }
  813.  
  814. /****************************************************************************************************************
  815.  */
  816.  
  817. static void DestroyGC (w)
  818. Widget w;
  819. {
  820.   GobanWidget  gw      = (GobanWidget) w;
  821.   Display     *display = XtDisplay (w);
  822.  
  823.   XFreeGC (display, gw->goban.black_fg_gc  );
  824.   XFreeGC (display, gw->goban.black_bg_gc  );
  825.   XFreeGC (display, gw->goban.black_bd_gc  );
  826.   XFreeGC (display, gw->goban.white_fg_gc  );
  827.   XFreeGC (display, gw->goban.white_bg_gc  );
  828.   XFreeGC (display, gw->goban.white_bd_gc  );
  829.   XFreeGC (display, gw->goban.foreground_gc);
  830.   XFreeGC (display, gw->goban.background_gc);
  831.   XFreeGC (display, gw->goban.copy_gc      );
  832. }
  833.  
  834. /****************************************************************************************************************
  835.  */
  836.  
  837. static void Destroy (w)
  838. Widget w;
  839. {
  840.   GobanWidget  gw      = (GobanWidget) w;
  841.   Display     *display = XtDisplay (w);
  842.  
  843.   DestroyPixmap (w);
  844.   DestroyGC     (w);
  845.  
  846.   XFreePixmap (display, gw->goban.white_stone  );
  847.   XFreePixmap (display, gw->goban.black_stone  );
  848.   XFreePixmap (display, gw->goban.gray_stone   );
  849.   XFreePixmap (display, gw->goban.mouse_mask   );
  850.  
  851.   XFreeCursor (display, gw->goban.white_cursor );
  852.   XFreeCursor (display, gw->goban.black_cursor );
  853.   XFreeCursor (display, gw->goban.gray_cursor  );
  854.   XFreeCursor (display, gw->goban.font_cursor  );
  855. }
  856.  
  857. /****************************************************************************************************************
  858.  */
  859.  
  860. static void Realize (w, valuemaskp, attr)
  861. Widget                w;
  862. XtValueMask          *valuemaskp;
  863. XSetWindowAttributes *attr;
  864. {
  865.   GobanWidget  gw      = (GobanWidget) w;
  866.   
  867.   *valuemaskp |= CWCursor;
  868.  
  869.   switch (gw->goban.cursor) {
  870.   case GbCGrayStone  : attr->cursor = gw->goban.gray_cursor ; break;
  871.   case GbCBlackStone : attr->cursor = gw->goban.black_cursor; break;
  872.   case GbCWhiteStone : attr->cursor = gw->goban.white_cursor; break;
  873.   default            : attr->cursor = gw->goban.font_cursor ; break;
  874.   }
  875.   
  876.   XtCreateWindow (w, InputOutput, (Visual *) CopyFromParent, *valuemaskp, attr);
  877. }
  878.  
  879. /****************************************************************************************************************
  880.  */
  881.  
  882. static char *stars[18] = {
  883.   "",                /*  2  */  
  884.   "",                /*  3  */  
  885.   "",                /*  4  */  
  886.   "",                /*  5  */  
  887.   "",                /*  6  */  
  888.   "",                /*  7  */  
  889.   "cccffcff",            /*  8  */    
  890.   "cccgeegcgg",            /*  9  */  
  891.   "ccchhchh",            /* 10  */  
  892.   "cccfcifcfffiicifii",        /* 11  */  
  893.   "dddiidii",            /* 12  */  
  894.   "dddjggjdjj",            /* 13  */  
  895.   "dddkkdkk",            /* 14  */  
  896.   "dddhdlhdhhhlldlhll",        /* 15  */  
  897.   "dddmmdmm",            /* 16  */  
  898.   "dddidnidiiinndninn",        /* 17  */  
  899.   "dddoodoo",            /* 18  */  
  900.   "dddjdpjdjjjppdpjpp",        /* 19  */  
  901. };
  902.  
  903. static void DrawBoard (w)
  904. Widget w;
  905. {
  906.   GobanWidget  gw         = (GobanWidget) w;
  907.   Display     *display    = XtDisplay (w);
  908.   XSegment     segment[44];
  909.   int          segc;
  910.   Position     game_size  = (Position) gw->goban.game_size;
  911.   Position     point_size = (Position) gw->goban.point_size;
  912.   Position     star_size  = 4;
  913.   Position     xbase      = gw->goban.x_offset + point_size / 2;
  914.   Position     ybase      = gw->goban.y_offset - point_size / 2;
  915.   Position     xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  916.   Position     ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  917.   Position     xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  918.   Position     ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  919.   char        *star;
  920.   int          x;
  921.   int          y;
  922.  
  923.   XFillRectangle (display, gw->goban.board, gw->goban.background_gc, 0, 0, w->core.width, w->core.height);
  924.  
  925.   if (point_size > 0) {
  926.     segc = 0;
  927.     for (y = gw->goban.bottom - 1; y < gw->goban.top; y++, segc++) {
  928.       segment[segc].x1 = (short) Max ((int) xbase + point_size , xmin);
  929.       segment[segc].x2 = (short) Min ((int) xbase + point_size * game_size, xmax);
  930.       segment[segc].y1 = (short) (ybase - point_size * y);
  931.       segment[segc].y2 = (short) (ybase - point_size * y);
  932.     }
  933.     
  934.     for (x = gw->goban.left; x <= gw->goban.right; x++, segc++) {
  935.       segment[segc].x1 = (short) (xbase + point_size * x);
  936.       segment[segc].x2 = (short) (xbase + point_size * x);
  937.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1), ymin);
  938.       segment[segc].y2 = (short) Min (ybase, ymax);
  939.     }
  940.     
  941.     if (gw->goban.top == gw->goban.game_size) {
  942.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  943.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  944.       segment[segc].y1 = (short) (ybase - point_size * (game_size - 1) - 1);
  945.       segment[segc].y2 = (short) (ybase - point_size * (game_size - 1) - 1);
  946.       segc++;
  947.     }
  948.     
  949.     if (gw->goban.bottom == 1) {
  950.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  951.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  952.       segment[segc].y1 = (short) (ybase + 1);
  953.       segment[segc].y2 = (short) (ybase + 1);
  954.       segc++;
  955.     }
  956.     
  957.     if (gw->goban.left == 1) {
  958.       segment[segc].x1 = (short) (xbase + point_size - 1);
  959.       segment[segc].x2 = (short) (xbase + point_size - 1);
  960.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin); 
  961.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  962.       segc++;
  963.     }
  964.     
  965.     if (gw->goban.right == gw->goban.game_size) {
  966.       segment[segc].x1 = (short) (xbase + point_size * game_size + 1);
  967.       segment[segc].x2 = (short) (xbase + point_size * game_size + 1);
  968.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin);
  969.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  970.       segc++;
  971.     }
  972.     
  973.     XDrawSegments (display, gw->goban.board, gw->goban.foreground_gc, segment, segc);
  974.     
  975.     if (point_size > 8) {
  976.       star_size = (point_size > 10) ? 4 : 2;
  977.       star      = stars[game_size - 2];
  978.       
  979.       while (*star != '\0') {
  980.     x = *star++ - 'a' + 1;
  981.     y = *star++ - 'a' + 1;
  982.     
  983.     if (x >= gw->goban.left && x <= gw->goban.right && y >= gw->goban.bottom && y <= gw->goban.top) {
  984.       x = gw->goban.x_offset + (point_size * (2 * x + 1)) / 2;
  985.       y = gw->goban.y_offset - (point_size * (2 * y - 1)) / 2;
  986.       
  987.       XDrawArc (display, gw->goban.board, gw->goban.foreground_gc, 
  988.             (int) x - star_size / 2, (int) y - star_size / 2, 
  989.             (unsigned int) star_size, (unsigned int) star_size, 
  990.             0, 64 * 360);
  991.       XFillArc (display, gw->goban.board, gw->goban.foreground_gc, 
  992.             (int) x - star_size / 2, (int) y - star_size / 2, 
  993.             (unsigned int) star_size, (unsigned int) star_size, 
  994.             0, 64 * 360);
  995.     }
  996.       }
  997.     }
  998.   }
  999.  
  1000.   XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, 0, 0, 
  1001.          w->core.width, w->core.height, 0, 0);
  1002. }
  1003.  
  1004. /****************************************************************************************************************
  1005.  */
  1006.  
  1007. static void DrawCoordinates (w)
  1008. Widget w;
  1009. {
  1010.   GobanWidget  gw         = (GobanWidget) w;
  1011.   Display     *display    = XtDisplay (w);
  1012.   XCharStruct  extent;
  1013.   int          point_size = gw->goban.point_size;
  1014.   char         s[2];
  1015.   int          len;
  1016.   int          ascent;
  1017.   int          descent;
  1018.   int          direction;
  1019.   int          xbase;
  1020.   int          ybase;
  1021.   int          x;
  1022.   int          y;
  1023.   unsigned int width;
  1024.   unsigned int height;
  1025.  
  1026.   s[0] = s[1] = '8';
  1027.   XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1028.              s, 2, &direction, &ascent, &descent, &extent);
  1029.  
  1030.   if ((point_size > extent.width + 2) && (point_size > extent.ascent + extent.descent + 2)) {
  1031.     xbase = 2 * gw->goban.x_offset + point_size;
  1032.     ybase = 2 * gw->goban.y_offset - point_size;
  1033.  
  1034.     if (gw->goban.display_coordinates == TRUE) {
  1035.     
  1036.       for (x = gw->goban.left; x <= gw->goban.right; x++) {
  1037.     s[0] = 'A' - 1 + ((x > 8) ? (x + 1) : x);
  1038.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1039.                s, 1, &direction, &ascent, &descent, &extent);
  1040.  
  1041.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1042.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1043.              (ybase + extent.ascent - extent.descent) / 2 - point_size * gw->goban.top + 1, s, 1);
  1044.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1045.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1046.              (ybase + extent.ascent - extent.descent) / 2 - point_size * (gw->goban.bottom - 2) + 1, s, 1);
  1047.       }
  1048.     }
  1049.  
  1050.     x      = gw->goban.x_offset + point_size * gw->goban.left;
  1051.     y      = gw->goban.y_offset - point_size * (gw->goban.top + 1);
  1052.     width  = point_size * (gw->goban.right - gw->goban.left + 1);
  1053.     height = point_size;
  1054.     
  1055.     if (gw->goban.display_coordinates == FALSE)
  1056.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1057.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1058.  
  1059.     y      = gw->goban.y_offset - point_size * (gw->goban.bottom - 1);
  1060.  
  1061.     if (gw->goban.display_coordinates == FALSE)
  1062.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1063.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1064.     
  1065.     ybase += 2 * point_size;
  1066.  
  1067.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1068.       if (gw->goban.display_coordinates == TRUE) {
  1069.     len = 0;
  1070.     if (y > 9)
  1071.       s[len++] = '1';
  1072.     s[len++] = '0' + y % 10;
  1073.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1074.                s, len, &direction, &ascent, &descent, &extent);
  1075.  
  1076.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1077.              (xbase - extent.width) / 2 + point_size * (gw->goban.left  - 1) - extent.lbearing + 1, 
  1078.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1079.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1080.              (xbase - extent.width) / 2 + point_size * (gw->goban.right + 1) - extent.lbearing + 1, 
  1081.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1082.       }
  1083.     }
  1084.  
  1085.     x      = gw->goban.x_offset + point_size * (gw->goban.left  - 1);
  1086.     y      = gw->goban.y_offset - point_size * gw->goban.top;
  1087.     width  = point_size;
  1088.     height = point_size * (gw->goban.top - gw->goban.bottom + 1);;
  1089.     
  1090.     if (gw->goban.display_coordinates == FALSE)
  1091.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1092.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1093.  
  1094.     x      = gw->goban.x_offset + point_size * (gw->goban.right + 1);
  1095.     
  1096.     if (gw->goban.display_coordinates == FALSE)
  1097.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1098.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1099.   }
  1100.  
  1101. }
  1102.  
  1103. /****************************************************************************************************************
  1104.  */
  1105.  
  1106. static void InitializeSize (w)
  1107. Widget w;
  1108. {  
  1109.   GobanWidget  gw        = (GobanWidget) w;
  1110.   Position     bottom    = Min (gw->goban.bottom, gw->goban.top  );
  1111.   Position     left      = Min (gw->goban.left  , gw->goban.right);
  1112.   Position     top       = Max (gw->goban.bottom, gw->goban.top  );
  1113.   Position     right     = Max (gw->goban.left  , gw->goban.right);
  1114.   Dimension    game_size = gw->goban.game_size;
  1115.   Dimension    width;
  1116.   Dimension    height;
  1117.  
  1118.   game_size = (game_size > 1      && game_size <  20       ) ? game_size : 19;
  1119.   bottom    = (bottom    > 0      && bottom    <  game_size) ? bottom    : 1;
  1120.   left      = (left      > 0      && left      <  game_size) ? left      : 1;
  1121.   top       = (top       > bottom && top       <= game_size) ? top       : game_size;
  1122.   right     = (right     > left   && right     <= game_size) ? right     : game_size;
  1123.  
  1124.   width     = right - left   + 3;
  1125.   height    = top   - bottom + 3;
  1126.  
  1127.   if ((w->core.height == 0) && (w->core.width == 0)) {
  1128.     w->core.width  = gw->goban.point_size * width ;
  1129.     w->core.height = gw->goban.point_size * height;
  1130.   } 
  1131.  
  1132.   else 
  1133.     gw->goban.point_size = Min (w->core.width / width, w->core.height / height);
  1134.  
  1135.   gw->goban.game_size = game_size;
  1136.   gw->goban.bottom    = bottom;
  1137.   gw->goban.left      = left;
  1138.   gw->goban.top       = top;
  1139.   gw->goban.right     = right;
  1140.   gw->goban.x_offset  = (int) (w->core.width  - gw->goban.point_size * (width  + 2 * left - 2)) / 2;
  1141.   gw->goban.y_offset  = (int) (w->core.height - gw->goban.point_size * (height - 2 * top  - 2)) / 2;
  1142. }
  1143.  
  1144. /****************************************************************************************************************
  1145.  */
  1146.  
  1147. /* ARGSUSED */
  1148.  
  1149. static void Initialize (request, new)
  1150. Widget request;
  1151. Widget new;
  1152. {
  1153.   InitializeSize   (new);
  1154.   InitializePixmap (new);
  1155.   InitializeGC     (new);
  1156.   InitializeCursor (new);
  1157.   DrawBoard        (new);
  1158.   DrawCoordinates  (new);
  1159.   GbClearBoard     (new);
  1160. }
  1161.  
  1162. /****************************************************************************************************************
  1163.  */
  1164.  
  1165. static void DrawPoint (w, x, y, color)
  1166. Widget      w;
  1167. int         x;
  1168. int         y;
  1169. GbPointState color;
  1170. {
  1171.   GobanWidget   gw      = (GobanWidget) w;
  1172.   Display      *display = XtDisplay (w);
  1173.   unsigned int  size    = (unsigned int) gw->goban.point_size - 2;
  1174.   XExposeEvent  event;
  1175.   int           X;
  1176.   int           Y;
  1177.  
  1178.   if (size > 1) {
  1179.     X = gw->goban.x_offset + gw->goban.point_size * x + 1;
  1180.     Y = gw->goban.y_offset - gw->goban.point_size * y + 1;
  1181.     
  1182.     switch (color)
  1183.       {
  1184.       case GbBlackStone :
  1185.     XFillArc (display, gw->goban.picture, gw->goban.black_bg_gc, X, Y, size, size, 0, 360 * 64);
  1186.     XDrawArc (display, gw->goban.picture, gw->goban.black_bd_gc, X, Y, size, size, 0, 360 * 64);
  1187.     XDrawArc (display, gw->goban.picture, gw->goban.black_fg_gc, X + (int) size / 6, Y + (int) size / 6, 
  1188.           (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1189.     break;
  1190.       case GbWhiteStone :
  1191.     XFillArc (display, gw->goban.picture, gw->goban.white_bg_gc, X, Y, size, size, 0, 360 * 64);
  1192.     XDrawArc (display, gw->goban.picture, gw->goban.white_bd_gc, X, Y, size, size, 0, 360 * 64);
  1193.     XDrawArc (display, gw->goban.picture, gw->goban.white_fg_gc, X + (int) size / 6, Y + (int) size / 6, 
  1194.           (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1195.     break;
  1196.       case GbEmptyPoint :
  1197.     XCopyArea (XtDisplay (w), gw->goban.board, gw->goban.picture, gw->goban.copy_gc,
  1198.            X, Y, gw->goban.point_size, gw->goban.point_size, X, Y); 
  1199.     break;
  1200.       }
  1201.     
  1202.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  1203.       event.x      = X - 1;
  1204.       event.y      = Y - 1;
  1205.       event.width  = gw->goban.point_size;
  1206.       event.height = gw->goban.point_size;
  1207.  
  1208.       Redisplay (w, &event, (Region) NULL);
  1209.     }
  1210.   }
  1211. }
  1212.  
  1213. /****************************************************************************************************************
  1214.  */
  1215.  
  1216. static void RedrawStones (w)
  1217. Widget w;
  1218. {
  1219.   GobanWidget  gw         = (GobanWidget) w;
  1220.   Boolean      redisplay  = gw->goban.auto_redisplay;
  1221.   Position     x;
  1222.   Position     y;
  1223.  
  1224.   gw->goban.auto_redisplay = FALSE;
  1225.  
  1226.   for (x = gw->goban.left; x <= gw->goban.right; x++)
  1227.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1228.       if (gw->goban.points[x][y].free == 0) {
  1229.     if (gw->goban.points[x][y].black == 1)
  1230.       DrawPoint (w, x, y, GbBlackStone);
  1231.     else
  1232.       DrawPoint (w, x, y, GbWhiteStone);
  1233.     if (gw->goban.points[x][y].num > 0)
  1234.       GbSetNum (w, x, y, (int) gw->goban.points[x][y].num);
  1235.       }
  1236.  
  1237.       if (gw->goban.points[x][y].mark1 != 0 || gw->goban.points[x][y].mark2 != 0)
  1238.     GbSetMark (w, x, y, gw->goban.points[x][y].mark1, gw->goban.points[x][y].mark2);
  1239.     }
  1240.  
  1241.   gw->goban.auto_redisplay = redisplay;
  1242.  
  1243.   if (redisplay == TRUE)
  1244.     GbRedisplayBoard (w);
  1245. }
  1246.  
  1247. /****************************************************************************************************************
  1248.  */
  1249.  
  1250. static void Resize (w)
  1251. Widget w;
  1252. {
  1253.   DestroyPixmap    (w);
  1254.   DestroyGC        (w);
  1255.   InitializeSize   (w);
  1256.   InitializePixmap (w);
  1257.   InitializeGC     (w);
  1258.   DrawBoard        (w);
  1259.   DrawCoordinates  (w);
  1260.   RedrawStones     (w);
  1261. }
  1262.  
  1263. /****************************************************************************************************************
  1264.  */
  1265.  
  1266. /* ARGSUSED */
  1267.  
  1268. static Boolean SetValues (current, request, new)
  1269. Widget current;
  1270. Widget request;
  1271. Widget new;
  1272. {
  1273.   GobanWidget gnew      = (GobanWidget) new;
  1274.   GobanWidget gcurrent  = (GobanWidget) current;
  1275.   Boolean     redisplay = FALSE;
  1276.  
  1277.   if (gnew->goban.point_size != gcurrent->goban.point_size)
  1278.     gnew->goban.point_size = gcurrent->goban.point_size;
  1279.  
  1280.   if (XtIsRealized (new)) {
  1281.     if (gnew->goban.cursor != gcurrent->goban.cursor) {
  1282.  
  1283.       switch (gnew->goban.cursor) {
  1284.  
  1285.       case GbCGrayStone  : 
  1286.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.gray_cursor);
  1287.     break;
  1288.       case GbCBlackStone : 
  1289.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.black_cursor);
  1290.     break;
  1291.       case GbCWhiteStone : 
  1292.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.white_cursor);
  1293.     break;
  1294.       default :
  1295.     XFreeCursor (XtDisplay (new), gnew->goban.font_cursor );
  1296.     gnew->goban.font_cursor = XCreateFontCursor (XtDisplay (new), (unsigned int) gnew->goban.cursor);
  1297.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.font_cursor);
  1298.       }
  1299.     }
  1300.   }
  1301.  
  1302.   if (gnew->goban.game_size != gcurrent->goban.game_size) 
  1303.     if (gnew->goban.game_size > 1 && gnew->goban.game_size < 20) {
  1304.  
  1305.       gnew->goban.bottom = 1;
  1306.       gnew->goban.left   = 1;
  1307.       gnew->goban.top    = gnew->goban.game_size;
  1308.       gnew->goban.right  = gnew->goban.game_size;
  1309.       
  1310.       InitializeSize   (new);
  1311.       DrawBoard        (new);
  1312.       DrawCoordinates  (new);
  1313.       GbClearBoard     (new);
  1314.       
  1315.       redisplay = TRUE;
  1316.     }
  1317.     else
  1318.       gnew->goban.game_size = gcurrent->goban.game_size;
  1319.  
  1320.   else if (gnew->goban.top    != gcurrent->goban.top   ||
  1321.        gnew->goban.left   != gcurrent->goban.left  ||
  1322.        gnew->goban.right  != gcurrent->goban.right ||
  1323.        gnew->goban.bottom != gcurrent->goban.bottom) {
  1324.  
  1325.     InitializeSize  (new);
  1326.     DrawBoard       (new);
  1327.     DrawCoordinates (new);
  1328.     RedrawStones    (new);
  1329.  
  1330.     redisplay = TRUE;
  1331.   }
  1332.  
  1333.   else if (new->core.background_pixel != current->core.background_pixel || 
  1334.            gnew->goban.foreground     != gcurrent->goban.foreground     ||
  1335.            gnew->goban.white_fg       != gcurrent->goban.white_fg       ||
  1336.            gnew->goban.white_bg       != gcurrent->goban.white_bg       ||
  1337.            gnew->goban.white_bd       != gcurrent->goban.white_bd       ||
  1338.            gnew->goban.black_fg       != gcurrent->goban.black_fg       ||
  1339.            gnew->goban.black_bg       != gcurrent->goban.black_bg       ||
  1340.            gnew->goban.black_bd       != gcurrent->goban.black_bd       ) {
  1341.  
  1342.     DestroyGC        (new);
  1343.     InitializeGC     (new);
  1344.     DrawBoard        (new);
  1345.     DrawCoordinates  (new);
  1346.     RedrawStones     (new);
  1347.  
  1348.     redisplay = TRUE;
  1349.   }
  1350.  
  1351.   if (gnew->goban.display_coordinates != gcurrent->goban.display_coordinates) {
  1352.     DrawCoordinates (new);
  1353.  
  1354.     redisplay = TRUE;
  1355.   }
  1356.  
  1357.   return (gnew->goban.auto_redisplay == True) ? redisplay : False;
  1358. }
  1359.  
  1360. /****************************************************************************************************************
  1361.  */
  1362. SHAR_EOF
  1363. fi # end of overwriting check
  1364. if test -f 'node.c'
  1365. then
  1366.     echo shar: will not over-write existing file "'node.c'"
  1367. else
  1368. cat << \SHAR_EOF > 'node.c'
  1369. /****************************************************************************************************************
  1370.  *
  1371.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1372.  *
  1373.  *  This program is distributed in the hope that it will be useful.
  1374.  *  Use and copying of this software and preparation of derivative works
  1375.  *  based upon this software are permitted, so long as the following
  1376.  *  conditions are met:
  1377.  *       o credit to the authors is acknowledged following current
  1378.  *         academic behaviour
  1379.  *       o no fees or compensation are charged for use, copies, or
  1380.  *         access to this software
  1381.  *       o this copyright notice is included intact.
  1382.  *  This software is made available AS IS, and no warranty is made about 
  1383.  *  the software or its performance. 
  1384.  * 
  1385.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1386.  *  Send them to    dumesnil@etca.fr   or to:
  1387.  *       
  1388.  *       Antoine de Maricourt
  1389.  *       ETCA CREA-SP
  1390.  *       16 bis, avenue Prieur de la Cote d'Or
  1391.  *       94114 Arcueil Cedex
  1392.  *       France
  1393.  */
  1394.  
  1395. #include "sg.h"
  1396.  
  1397. static void bcopy (b1, b2, length)
  1398. char *b1;
  1399. char *b2;
  1400. int   length;
  1401. {
  1402.   if (length > 0)
  1403.     if ((long) (b2 - b1) < 0)
  1404.       while (length-- > 0)
  1405.     *b2++ = *b1++;
  1406.  
  1407.     else {
  1408.       b2 += length;
  1409.       b1 += length;
  1410.  
  1411.       while (length-- > 0) 
  1412.     *--b2 = *--b1;
  1413.     }
  1414. }
  1415.  
  1416. static void bzero (b, length)
  1417. char *b;
  1418. int   length;
  1419. {
  1420.   if (length > 0)
  1421.     while (length-- > 0)
  1422.       *b++ = '\0';
  1423. }
  1424.  
  1425. /*******************************************************************************************************
  1426.  *
  1427.  *    Recopie la chaine <src> a la suite de la chaine <*dst>. La memoire est allouee par malloc et les
  1428.  *    deux chaines sont supposees etre terminees par le caractere <end>.
  1429.  */
  1430.  
  1431. void SG_strcat (dst, src, end)
  1432. char   **dst;
  1433. char    *src;
  1434. char     end;
  1435. {
  1436.   char *ptr;
  1437.   int   src_size = 0;
  1438.   int   dst_size = 0;
  1439.  
  1440.   if ( src != NULL) { ptr =  src; while (*ptr++ != end) src_size++; }
  1441.   if (*dst != NULL) { ptr = *dst; while (*ptr++ != end) dst_size++; }
  1442.  
  1443.   if (src_size > 0) {
  1444.     ptr = (char*) malloc ((unsigned) src_size + dst_size + 1);
  1445.  
  1446.     (void) bcopy (*dst, ptr           , dst_size    );
  1447.     (void) bcopy ( src, ptr + dst_size, src_size + 1);
  1448.  
  1449.     (void) free (*dst);
  1450.     *dst = ptr;
  1451.   }
  1452. }
  1453.  
  1454. /*******************************************************************************************************
  1455.  *
  1456.  *    Recopie la chaine <src> a la place de la chaine *<dst>. Les deux chaines sont terminees par
  1457.  *    le caractere <end>.
  1458.  */
  1459.  
  1460. void SG_strcpy (dst, src, end)
  1461. char   **dst;
  1462. char    *src;
  1463. char     end;
  1464. {
  1465.   char *ptr;
  1466.   int   src_size = 0;
  1467.   int   dst_size = 0;
  1468.  
  1469.   if ( src != NULL) { ptr =  src; while (*ptr++ != end) src_size++; }
  1470.   if (*dst != NULL) { ptr = *dst; while (*ptr++ != end) dst_size++; }
  1471.  
  1472.   if (src_size == dst_size)
  1473.     (void) bcopy (src, *dst, src_size);
  1474.  
  1475.   else {
  1476.     (void) free (*dst);
  1477.     *dst = (char*) malloc ((unsigned) src_size + 1);
  1478.     (void) bcopy (src, *dst, src_size + 1);
  1479.   }
  1480. }
  1481.  
  1482. /*******************************************************************************************************
  1483.  *
  1484.  *   Supprime le noeud <node> de l'arbre. Tous les pointeurs (up, down, right et left) sont remis
  1485.  *   a NULL pour ce noeud. La valeur retournee est le noeud lui-meme : il est necessaire d'appeler
  1486.  *   SG_FreeNode pour recuperer la place memoire associee et liberer les proprietes.
  1487.  */
  1488.  
  1489. SG_NodePtr SG_RemoveNode (node)
  1490. SG_NodePtr node;
  1491. {
  1492.   if (node->up != NULL) {
  1493.     node->up->down  = node->right;
  1494.     if (node->right != NULL)
  1495.       node->right->up = node->up;
  1496.     node->up        = NULL;
  1497.   }
  1498.  
  1499.   if (node->left != NULL && node->right != NULL) {
  1500.     node->left->right = node->right;
  1501.     node->right->left = node->left;
  1502.   }
  1503.  
  1504.   else if (node->right != NULL)
  1505.     node->right->left = NULL;
  1506.  
  1507.   else if (node->left != NULL)
  1508.     node->left->right = NULL;
  1509.  
  1510.   node->left        = NULL;
  1511.   node->right       = NULL;
  1512.  
  1513.   return node;
  1514. }
  1515.  
  1516. /*******************************************************************************************************
  1517.  *
  1518.  *   Libere le noeud <node>. Cette fonction est appelee recursivement sur les fils et les freres
  1519.  *   de ce noeud. La liste des proprietes est liberee par la meme occasion
  1520.  */
  1521.  
  1522. void SG_FreeNode (node)
  1523. SG_NodePtr node;
  1524. {
  1525.   SG_PropertyPtr property;
  1526.   SG_PropertyPtr next_property;
  1527.   SG_NodePtr     next_node;
  1528.  
  1529.  free_node :
  1530.  
  1531.   if (node != NULL) {
  1532.     if (node->right != NULL)
  1533.       SG_FreeNode (node->right);
  1534.  
  1535.     next_property = node->property;
  1536.     
  1537.     while (next_property != NULL) {
  1538.       property      = next_property;
  1539.       next_property = property->next;
  1540.       
  1541.       switch (property->id) {
  1542.       case SG_Letters     :
  1543.       case SG_Comment     :
  1544.       case SG_GameComment :
  1545.       case SG_GameName    :
  1546.       case SG_nodeName    :
  1547.       case SG_EVent       :
  1548.       case SG_ROund       :
  1549.       case SG_DaTe        :
  1550.       case SG_PlaCe       :
  1551.       case SG_REsult      :
  1552.       case SG_USer        :
  1553.       case SG_TiMe        :
  1554.       case SG_SOurce      :
  1555.       case SG_BlackRank   :
  1556.       case SG_WhiteRank   :
  1557.       case SG_BlackSpec   :
  1558.       case SG_WhiteSpec   :
  1559.       case SG_HAndicap    :
  1560.       case SG_KoMi        :
  1561.       case SG_PlayerBlack :
  1562.       case SG_PlayerWhite :
  1563.       case SG_BlackLeft   :
  1564.       case SG_WhiteLeft   :
  1565.     free ((char *) property->data.pvalue);
  1566.     break;
  1567.       }
  1568.       
  1569.       (void) free ((char *) property);
  1570.     }
  1571.  
  1572.     (void) free ((char *) node->setup);
  1573.  
  1574.     next_node = node->down;
  1575.     (void) free ((char *) node);
  1576.  
  1577.     node = next_node;
  1578.     goto free_node;
  1579.   }
  1580. }
  1581.  
  1582. /*******************************************************************************************************
  1583.  *
  1584.  *   Retourne un nouveau noeud alloue par malloc. Tous les champs sont remis a zero.
  1585.  */
  1586.  
  1587. static SG_NodePtr make_node ()
  1588. {
  1589.   SG_NodePtr node;
  1590.  
  1591.   node = (SG_NodePtr) malloc ((unsigned) sizeof (SG_Node));
  1592.  
  1593.   node->num      = -1;
  1594.   node->color    = SG_EmptyPoint;
  1595.   node->x        = 0;
  1596.   node->y        = 0;
  1597.   node->player   = SG_EmptyPoint;
  1598.   node->setup    = NULL;
  1599.   node->property = NULL;
  1600.   node->up       = NULL;
  1601.   node->down     = NULL;
  1602.   node->left     = NULL;
  1603.   node->right    = NULL;
  1604.  
  1605.   return node;
  1606. }
  1607.  
  1608. /*******************************************************************************************************
  1609.  *
  1610.  */
  1611.  
  1612. SG_NodePtr SG_MakeNode (node, type)
  1613. SG_NodePtr node;
  1614. int        type;
  1615. {
  1616.   SG_NodePtr new = NULL;
  1617.  
  1618.   switch (type) {
  1619.  
  1620.   case SG_Event :
  1621.     new = make_node ();
  1622.  
  1623.     if (node != NULL) {
  1624.       do {
  1625.     while (node->up != NULL)
  1626.       node = node->up;
  1627.     while (node->left != NULL)
  1628.       node = node->left;
  1629.       } while (node->up != NULL);
  1630.       
  1631.       while (node->right != NULL)
  1632.     node = node->right;
  1633.       
  1634.       node->right = new;
  1635.       new->left   = node;
  1636.     }
  1637.       
  1638.     new->type   = SG_EventType;
  1639.     break;
  1640.  
  1641.   case SG_Move    :
  1642.   case SG_Diagram :
  1643.     new = make_node ();
  1644.  
  1645.     node->down  = new;
  1646.     new->up     = node;
  1647.  
  1648.     if (type == SG_Move)
  1649.       new->type   = SG_MoveType;
  1650.     else
  1651.       new->type   = SG_DiagramType;
  1652.     break;
  1653.  
  1654.   case SG_VariationMove    :
  1655.   case SG_VariationDiagram :
  1656.  
  1657.     new = make_node ();
  1658.  
  1659.     while (node->right != NULL)
  1660.       node = node->right;
  1661.  
  1662.     node->right = new;
  1663.     new->left   = node;
  1664.  
  1665.     if (type == SG_VariationMove)
  1666.       new->type   = SG_MoveType;
  1667.     else
  1668.       new->type   = SG_DiagramType;
  1669.  
  1670.     break;
  1671.   }
  1672.   
  1673.   return new;
  1674. }
  1675.  
  1676. /*******************************************************************************************************
  1677.  *
  1678.  */
  1679.  
  1680. SG_PropertyPtr SG_GetProperty (node, id)
  1681. SG_NodePtr node;
  1682. int        id;
  1683. {
  1684.   SG_PropertyPtr property = node->property;
  1685.   
  1686.   while (property != NULL) {
  1687.     if (property->id == id)
  1688.       break;
  1689.     property = property->next;
  1690.   }
  1691.   
  1692.   return property;
  1693. }
  1694.  
  1695. /*******************************************************************************************************
  1696.  *
  1697.  */
  1698.  
  1699. void SG_MakeProperty (node, id, value)
  1700. SG_NodePtr node;
  1701. int        id;
  1702. long       value;
  1703. {
  1704.   SG_PropertyPtr property;
  1705.  
  1706.   property = SG_GetProperty (node, id);
  1707.  
  1708.   if (property == NULL) {
  1709.     if (node->property != NULL) {
  1710.       property = node->property;
  1711.   
  1712.       while (property->next != NULL)
  1713.     property = property->next;
  1714.  
  1715.       property->next = (SG_PropertyPtr) malloc ((unsigned) sizeof (SG_Property));
  1716.       property       = property->next;
  1717.     }
  1718.  
  1719.     else 
  1720.       property = node->property = (SG_PropertyPtr) malloc ((unsigned) sizeof (SG_Property));
  1721.  
  1722.     (void) bzero ((char *) property, sizeof (SG_Property));
  1723.   }
  1724.  
  1725.   property->id = id;
  1726.   
  1727.   switch (id) {
  1728.     
  1729.   case SG_unVieW :
  1730.   case SG_ko     :
  1731.  
  1732.   case SG_KO     :
  1733.     property->data.ivalue = value;
  1734.     break;
  1735.     
  1736.   case SG_SiZe :
  1737.   case SG_VieW :
  1738.     property->data.pvalue = (unsigned char *) value;
  1739.     break;
  1740.     
  1741.   case SG_AddBlack :
  1742.   case SG_AddWhite :
  1743.   case SG_AddEmpty :
  1744.   case SG_Letters  :
  1745.   case SG_Marked   :
  1746.     SG_strcat ((char **) &property->data.pvalue, (char *) value, SG_EOS);
  1747.     break;
  1748.     
  1749.   case SG_Comment :
  1750.   case SG_GameComment :
  1751.     SG_strcat ((char **) &property->data.pvalue, (char *) value, '\0');
  1752.     break;
  1753.     
  1754.   case SG_GameName    :
  1755.   case SG_nodeName    :
  1756.   case SG_EVent       :
  1757.   case SG_ROund       :
  1758.   case SG_DaTe        :
  1759.   case SG_PlaCe       :
  1760.   case SG_REsult      :
  1761.   case SG_USer        :
  1762.   case SG_TiMe        :
  1763.   case SG_SOurce      :
  1764.   case SG_BlackRank   :
  1765.   case SG_WhiteRank   :
  1766.   case SG_BlackSpec   :
  1767.   case SG_WhiteSpec   :
  1768.   case SG_HAndicap    :
  1769.   case SG_KoMi        :
  1770.   case SG_PlayerBlack :
  1771.   case SG_PlayerWhite :
  1772.   case SG_BlackLeft   :
  1773.   case SG_WhiteLeft   :
  1774.     SG_strcpy ((char **) &property->data.pvalue, (char *) value, '\0');
  1775.     break;
  1776.   }
  1777. }
  1778.  
  1779. /*******************************************************************************************************
  1780.  *
  1781.  */
  1782.   
  1783. SHAR_EOF
  1784. fi # end of overwriting check
  1785. if test -f 'sg.c'
  1786. then
  1787.     echo shar: will not over-write existing file "'sg.c'"
  1788. else
  1789. cat << \SHAR_EOF > 'sg.c'
  1790. /****************************************************************************************************************
  1791.  *
  1792.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1793.  *
  1794.  *  This program is distributed in the hope that it will be useful.
  1795.  *  Use and copying of this software and preparation of derivative works
  1796.  *  based upon this software are permitted, so long as the following
  1797.  *  conditions are met:
  1798.  *       o credit to the authors is acknowledged following current
  1799.  *         academic behaviour
  1800.  *       o no fees or compensation are charged for use, copies, or
  1801.  *         access to this software
  1802.  *       o this copyright notice is included intact.
  1803.  *  This software is made available AS IS, and no warranty is made about 
  1804.  *  the software or its performance. 
  1805.  * 
  1806.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1807.  *  Send them to    dumesnil@etca.fr   or to:
  1808.  *       
  1809.  *       Antoine de Maricourt
  1810.  *       ETCA CREA-SP
  1811.  *       16 bis, avenue Prieur de la Cote d'Or
  1812.  *       94114 Arcueil Cedex
  1813.  *       France
  1814.  */
  1815.  
  1816. #include "sg.h"
  1817.  
  1818. SG_KWData sg_keywords[] = {
  1819.   { ""        , ""                , SG_Illegal         , 0                                           , },
  1820.   { "B"       , "Black"           , SG_Black           ,                SG_MoveType                  , },
  1821.   { "W"       , "White"           , SG_White           ,                SG_MoveType                  , },
  1822.   { "C"       , "Comment"         , SG_Comment         , SG_EventType | SG_MoveType | SG_DiagramType , },
  1823.   { "N"       , "nodeName"        , SG_nodeName        , SG_EventType | SG_MoveType | SG_DiagramType , },
  1824.   { "V"       , "nodeValue"       , SG_nodeValue       , SG_EventType | SG_MoveType | SG_DiagramType , },
  1825.   { "CH"      , "CHeck"           , SG_CHeck           ,                SG_MoveType                  , },
  1826.   { "GB"      , "GoodBlack"       , SG_GoodBlack       ,                SG_MoveType                  , },
  1827.   { "GW"      , "GoodWhite"       , SG_GoodWhite       ,                SG_MoveType                  , },
  1828.   { "TE"      , "TEsuji"          , SG_TEsuji          ,                SG_MoveType                  , },
  1829.   { "BM"      , "BadMove"         , SG_BadMove         ,                SG_MoveType                  , },
  1830.   { "BL"      , "BlackLeft"       , SG_BlackLeft       , SG_EventType | SG_MoveType | SG_DiagramType , },
  1831.   { "WL"      , "WhiteLeft"       , SG_WhiteLeft       , SG_EventType | SG_MoveType | SG_DiagramType , },
  1832.   { "FG"      , "FiGure"          , SG_FiGure          , SG_EventType | SG_MoveType | SG_DiagramType , },
  1833.   { "AB"      , "AddBlack"        , SG_AddBlack        , SG_EventType |               SG_DiagramType , },
  1834.   { "AW"      , "AddWhite"        , SG_AddWhite        , SG_EventType |               SG_DiagramType , },
  1835.   { "AE"      , "AddEmpty"        , SG_AddEmpty        , SG_EventType |               SG_DiagramType , },
  1836.   { "PL"      , "PLayer"          , SG_PLayer          , SG_EventType |               SG_DiagramType , },
  1837.   { "GN"      , "GameName"        , SG_GameName        , SG_EventType                                , },
  1838.   { "GC"      , "GameComment"     , SG_GameComment     , SG_EventType                                , },
  1839.   { "EV"      , "EVent"           , SG_EVent           , SG_EventType                                , },
  1840.   { "RO"      , "ROund"           , SG_ROund           , SG_EventType                                , },
  1841.   { "DT"      , "DaTe"            , SG_DaTe            , SG_EventType                                , },
  1842.   { "PC"      , "PlaCe"           , SG_PlaCe           , SG_EventType                                , },
  1843.   { "PB"      , "PlayerBlack"     , SG_PlayerBlack     , SG_EventType                                , },
  1844.   { "PW"      , "PlayerWhite"     , SG_PlayerWhite     , SG_EventType                                , },
  1845.   { "RE"      , "REsult"          , SG_REsult          , SG_EventType                                , },
  1846.   { "US"      , "USer"            , SG_USer            , SG_EventType                                , },
  1847.   { "TM"      , "TiMe"            , SG_TiMe            , SG_EventType                                , },
  1848.   { "SO"      , "SOurce"          , SG_SOurce          , SG_EventType                                , },
  1849.   { "GM"      , "GaMe"            , SG_GaMe            , SG_EventType                                , },
  1850.   { "SZ"      , "SiZe"            , SG_SiZe            , SG_EventType                                , },
  1851.   { "VW"      , "VieW"            , SG_VieW            , SG_EventType | SG_MoveType | SG_DiagramType , },
  1852.   { "BS"      , "BlackSpec"       , SG_BlackSpec       , SG_EventType                                , },
  1853.   { "WS"      , "WhiteSpec"       , SG_WhiteSpec       , SG_EventType                                , },
  1854.   { "EL"      , "EvaLuation"      , SG_EvaLuation      , SG_EventType | SG_MoveType | SG_DiagramType , },
  1855.   { "EX"      , "EXpected"        , SG_EXpected        , SG_EventType | SG_MoveType | SG_DiagramType , },
  1856.   { "SL"      , "SeLected"        , SG_SeLected        , SG_EventType | SG_MoveType | SG_DiagramType , },
  1857.   { "M"       , "Marked"          , SG_Marked          , SG_EventType | SG_MoveType | SG_DiagramType , },
  1858.   { "L"       , "Letters"         , SG_Letters         , SG_EventType | SG_MoveType | SG_DiagramType , },
  1859.   { "BR"      , "BlackRank"       , SG_BlackRank       , SG_EventType                                , },
  1860.   { "WR"      , "WhiteRank"       , SG_WhiteRank       , SG_EventType                                , },
  1861.   { "HA"      , "HAndicap"        , SG_HAndicap        , SG_EventType                                , },
  1862.   { "KM"      , "KoMi"            , SG_KoMi            , SG_EventType                                , },
  1863.   { "TB"      , "TerritoryBlack"  , SG_TerritoryBlack  , SG_EventType | SG_MoveType | SG_DiagramType , },
  1864.   { "TW"      , "TerritoryWhite"  , SG_TerritoryWhite  , SG_EventType | SG_MoveType | SG_DiagramType , },
  1865.   { "SC"      , "SeCure"          , SG_SeCure          , SG_EventType | SG_MoveType | SG_DiagramType , },
  1866.   { "RG"      , "ReGion"          , SG_ReGion          , SG_EventType | SG_MoveType | SG_DiagramType , },
  1867.   { "KO"      , "KO"              , SG_KO              ,                SG_MoveType                  , },
  1868.   { ""        , ""                , SG_Illegal         , 0                                           , },
  1869. };
  1870. SHAR_EOF
  1871. fi # end of overwriting check
  1872. if test -f 'read.c'
  1873. then
  1874.     echo shar: will not over-write existing file "'read.c'"
  1875. else
  1876. cat << \SHAR_EOF > 'read.c'
  1877. /****************************************************************************************************************
  1878.  *
  1879.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1880.  *
  1881.  *  This program is distributed in the hope that it will be useful.
  1882.  *  Use and copying of this software and preparation of derivative works
  1883.  *  based upon this software are permitted, so long as the following
  1884.  *  conditions are met:
  1885.  *       o credit to the authors is acknowledged following current
  1886.  *         academic behaviour
  1887.  *       o no fees or compensation are charged for use, copies, or
  1888.  *         access to this software
  1889.  *       o this copyright notice is included intact.
  1890.  *  This software is made available AS IS, and no warranty is made about 
  1891.  *  the software or its performance. 
  1892.  * 
  1893.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1894.  *  Send them to    dumesnil@etca.fr   or to:
  1895.  *       
  1896.  *       Antoine de Maricourt
  1897.  *       ETCA CREA-SP
  1898.  *       16 bis, avenue Prieur de la Cote d'Or
  1899.  *       94114 Arcueil Cedex
  1900.  *       France
  1901.  */
  1902.  
  1903. #include "sg.h"
  1904.  
  1905. static int size        = 19;
  1906.  
  1907. /*******************************************************************************************************
  1908.  */
  1909.  
  1910. static int read_int (i, file)
  1911. int   *i;
  1912. FILE  *file;
  1913. {
  1914.   int result = SG_OK;
  1915.   int ch     = ' ';
  1916.   int j      = 0;
  1917.  
  1918.   while (ch != '[' && ch != EOF) ch = getc (file);
  1919.   if (ch == EOF) return SG_EOFERR;
  1920.  
  1921.   ch = getc (file);
  1922.   if (! isdigit (ch)) goto error;
  1923.  
  1924.   while (isdigit (ch)) {
  1925.     j = 10 * j + ch - '0';
  1926.     ch = getc (file);
  1927.   }
  1928.   *i = j;
  1929.   goto ok;
  1930.  
  1931.  error :
  1932.   result = SG_NDGERR;
  1933.  
  1934.  ok :
  1935.   while (ch != ']' && ch != EOF) ch = getc (file);
  1936.   return result;
  1937. }
  1938.  
  1939. /*******************************************************************************************************
  1940.  *
  1941.  */
  1942.  
  1943. static int read_color (color, file)
  1944. unsigned char  *color;
  1945. FILE           *file;
  1946. {
  1947.   int result = SG_OK;
  1948.   int ch     = ' ';
  1949.  
  1950.   while (ch != '[' && ch != EOF) ch = getc (file);
  1951.   if (ch == EOF) return SG_EOFERR;
  1952.  
  1953.   ch = getc (file);
  1954.   switch (ch) {
  1955.   case 'B' : case 'b' : *color = SG_BlackStone; goto ok;
  1956.   case 'W' : case 'w' : *color = SG_WhiteStone; goto ok;
  1957.   }
  1958.  
  1959.   result = SG_NCLERR;
  1960.  
  1961.  ok :
  1962.   while (ch != ']' && ch != EOF) ch = getc (file);
  1963.   return result;
  1964. }
  1965.  
  1966. /*******************************************************************************************************
  1967.  */
  1968.  
  1969. static int read_stone (x, y, file)
  1970. unsigned char  *x;
  1971. unsigned char  *y;
  1972. FILE           *file;
  1973. {
  1974.   int result = SG_OK;
  1975.   int ch     = ' ';
  1976.  
  1977.   while (ch != '[' && ch != EOF) ch = getc (file);
  1978.   if (ch == EOF) return SG_EOFERR;
  1979.  
  1980.   ch = getc (file);
  1981.   if (! islower (ch)) goto error;
  1982.   *x = ch - 'a' + 1;
  1983.  
  1984.   ch = getc (file);
  1985.   if (! islower (ch)) goto error;
  1986.   *y = size + 1 - (ch - 'a' + 1);
  1987.  
  1988.   if (*y == 20 || *x == 20)
  1989.     *x = *y = 0;
  1990.  
  1991.   goto ok;
  1992.  
  1993.  error :
  1994.   result = SG_NSTERR;
  1995.  
  1996.  ok :
  1997.   while (ch != ']' && ch != EOF) ch = getc (file);
  1998.   return result;
  1999. }
  2000.  
  2001. /*******************************************************************************************************
  2002.  */
  2003.  
  2004. static int read_stones (color, dst, file)
  2005. unsigned char   color;     
  2006. unsigned char **dst;
  2007. FILE           *file;
  2008. {
  2009.   unsigned char  stones[361 * 2];
  2010.   unsigned char *pos = stones;
  2011.   int            ch  = ' ';
  2012.  
  2013.   do {
  2014.     if (read_stone (pos, pos + 1, file) == SG_OK) {
  2015.       *pos++ |= color;
  2016.       *pos++ |= color;
  2017.     }
  2018.  
  2019.     do ch = getc (file);
  2020.     while (isspace (ch) && ch != EOF);
  2021.  
  2022.     if (ch != EOF)
  2023.       (void) ungetc (ch, file);
  2024.  
  2025.   } while (ch == '[');
  2026.  
  2027.   if (pos != stones) {
  2028.     *pos++ = SG_EOS;
  2029.     SG_strcat ((char **) dst, (char *) stones, SG_EOS);
  2030.     return SG_OK;
  2031.   }
  2032.  
  2033.   else 
  2034.     return SG_NSTERR;
  2035. }
  2036.  
  2037. /*******************************************************************************************************
  2038.  */
  2039.  
  2040. static int read_text (dst, file, add)
  2041. unsigned char **dst;
  2042. FILE           *file;
  2043. int             add;
  2044. {
  2045.   char  text[5010];
  2046.   char *ptr = text;
  2047.   int   ch  = ' ';
  2048.  
  2049.   while (ch != '[' && ch != EOF) ch = getc (file);
  2050.   if (ch == EOF) return SG_NCTERR;
  2051.  
  2052.   while (ch != ']' && ch != EOF) {
  2053.     ch = getc (file);
  2054.  
  2055.     if ((unsigned) (ptr - text) < 5000) {
  2056.       if (ch == '\\') {
  2057.     *ptr = getc (file);
  2058.     
  2059.     switch (*ptr) {
  2060.     case 'n' : *ptr = '\n'; break;
  2061.     case 't' : *ptr = '\t'; break;
  2062.     }
  2063.     
  2064.     ptr++;
  2065.       }
  2066.       
  2067.       else
  2068.     *ptr++ = ch;
  2069.     }
  2070.  
  2071.     else {
  2072.       *ptr++ = '.';
  2073.       *ptr++ = '.';
  2074.       *ptr++ = '.';
  2075.     }
  2076.   }
  2077.   
  2078.   ptr--;
  2079.  
  2080.   if (ptr != text) {
  2081.     *ptr++ = '\0';
  2082.  
  2083.     if (add != 0)
  2084.       SG_strcat ((char **) dst, (char *) text, '\0');
  2085.     else 
  2086.       SG_strcpy ((char **) dst, (char *) text, '\0');
  2087.   }
  2088.  
  2089.   return SG_OK;
  2090. }
  2091.  
  2092. /*******************************************************************************************************
  2093.  */
  2094.    
  2095. static void read_property (node, cmd, file)
  2096. SG_NodePtr  node;
  2097. char       *cmd;
  2098. FILE       *file;
  2099. {
  2100.   int            id;
  2101.   SG_PropertyPtr property;
  2102.   char           top;
  2103.   char           left;
  2104.   char           bottom;
  2105.   char           right;
  2106.   unsigned char  x;
  2107.   unsigned char  y;
  2108.   int            i;
  2109.   long           value;
  2110.  
  2111.   for (id = 0; id < SG_MaxID; id++)
  2112.     if (strcmp (cmd, sg_keywords[id].keyword) == 0)
  2113.       break;
  2114.  
  2115.   id = sg_keywords[id].id;
  2116.  
  2117.   if ((id == SG_Black || id == SG_White) && node->type == SG_DiagramType) {
  2118.     if (node->setup == NULL)
  2119.       node->type = SG_MoveType;
  2120.  
  2121.     else
  2122.       id = (id == SG_Black) ? SG_AddBlack : SG_AddWhite;
  2123.   }
  2124.  
  2125.   if (node->type == SG_DiagramType || node->type == SG_EventType) {
  2126.     if (id == SG_Black) {
  2127.       id = SG_AddBlack;
  2128.       if (node->player == SG_EmptyPoint) node->player = SG_WhiteStone;
  2129.     }
  2130.  
  2131.     if (id == SG_White) {
  2132.       id = SG_AddWhite;
  2133.       if (node->player == SG_EmptyPoint) node->player = SG_BlackStone;
  2134.     }
  2135.   }
  2136.  
  2137.   if ((node->type & sg_keywords[id].node_id) != 0) 
  2138.     switch (id) {
  2139.       
  2140.     case SG_SiZe :
  2141.       if (read_int (&i, file) == SG_OK) {
  2142.     size = i;
  2143.     SG_MakeProperty (node, id, size);
  2144.       }
  2145.       break;
  2146.   
  2147.     case SG_Black :
  2148.       if (read_stone (&x, &y, file) == SG_OK) {
  2149.     node->x     = x;
  2150.     node->y     = y;
  2151.     node->color = SG_BlackStone;
  2152.       }
  2153.       break;
  2154.       
  2155.     case SG_White :
  2156.       if (read_stone (&x, &y, file) == SG_OK) {
  2157.     node->x     = x;
  2158.     node->y     = y;
  2159.     node->color = SG_WhiteStone;
  2160.       }
  2161.       break;
  2162.       
  2163.     case SG_AddBlack :
  2164.       (void) read_stones (SG_SETB, &node->setup, file);
  2165.       break;
  2166.       
  2167.     case SG_AddWhite :
  2168.       (void) read_stones (SG_SETW, &node->setup, file);
  2169.       break;
  2170.       
  2171.     case SG_AddEmpty :
  2172.       (void) read_stones (SG_SETE, &node->setup, file);
  2173.       break;
  2174.  
  2175.     case SG_VieW :
  2176.       if (read_stone (&x, &y, file) == SG_OK) {
  2177.     left = x; 
  2178.     top  = y;
  2179.  
  2180.     if (read_stone (&x, &y, file) == SG_OK) {
  2181.       right  = x; 
  2182.       bottom = y;
  2183.       value  = ((long) top << 24) + ((long) left << 16) + ((long) bottom << 8) + (long) right;
  2184.  
  2185.       SG_MakeProperty (node, id, value);
  2186.     }
  2187.       }
  2188.       break;
  2189.  
  2190.     case SG_Letters :
  2191.     case SG_Marked  :
  2192.       SG_MakeProperty (node, id, NULL);
  2193.       property = SG_GetProperty (node, id);
  2194.       (void) read_stones (SG_SETE, &property->data.pvalue, file);
  2195.       break;
  2196.  
  2197.     case SG_Comment :
  2198.     case SG_GameComment :
  2199.       SG_MakeProperty (node, id, NULL);
  2200.       property = SG_GetProperty (node, id);
  2201.       (void) read_text (&property->data.pvalue, file, 1);
  2202.       break;
  2203.  
  2204.     case SG_PLayer :
  2205.       (void) read_color (&x, file);
  2206.       node->player = x;
  2207.       break;
  2208.       
  2209.     case SG_GameName    :
  2210.     case SG_nodeName    :
  2211.     case SG_EVent       :
  2212.     case SG_ROund       :
  2213.     case SG_DaTe        :
  2214.     case SG_PlaCe       :
  2215.     case SG_REsult      :
  2216.     case SG_USer        :
  2217.     case SG_TiMe        :
  2218.     case SG_SOurce      :
  2219.     case SG_BlackRank   :
  2220.     case SG_WhiteRank   :
  2221.     case SG_BlackSpec   :
  2222.     case SG_WhiteSpec   :
  2223.     case SG_HAndicap    :
  2224.     case SG_KoMi        :
  2225.     case SG_PlayerBlack :
  2226.     case SG_PlayerWhite :
  2227.     case SG_BlackLeft   :
  2228.     case SG_WhiteLeft   :
  2229.       SG_MakeProperty (node, id, NULL);
  2230.       property = SG_GetProperty (node, id);
  2231.       (void) read_text (&property->data.pvalue, file, 0);
  2232.       break;
  2233.     }
  2234. }
  2235.  
  2236. /*******************************************************************************************************
  2237.  */
  2238.  
  2239. static SG_NodePtr root;
  2240.  
  2241. static SG_NodePtr read_node (node, var, file, level)
  2242. SG_NodePtr  node;
  2243. int         var;
  2244. FILE       *file;
  2245. int level;
  2246. {
  2247.   char cmd[3];
  2248.   int  ch;
  2249.   int  len     = 0;
  2250.   int  no_node = 1;
  2251.   int  nb_var  = 0;
  2252.  
  2253.   do {
  2254.     ch = getc (file);
  2255.  
  2256.     switch (ch) {
  2257.  
  2258.     case ';' :
  2259.       if (level != 0) {
  2260.     if (node == NULL) {
  2261.       node = SG_MakeNode (root, SG_Event);
  2262.       if (root == NULL)
  2263.         root = node;
  2264.     }
  2265.  
  2266.     else if (var-- == 1)
  2267.       node = SG_MakeNode (node, SG_VariationDiagram);
  2268.  
  2269.     else
  2270.       node = SG_MakeNode (node, SG_Diagram);
  2271.     
  2272.     no_node = 0;
  2273.     len     = 0;
  2274.       }
  2275.       break;
  2276.  
  2277.     case '(' :    
  2278.       if (level == 0)
  2279.     node = read_node ((SG_NodePtr) NULL, 0, file, level + 1);
  2280.       else if (nb_var++ == 0 || node->down == NULL)
  2281.     (void) read_node (node, 0, file, level + 1);
  2282.       else 
  2283.     (void) read_node (node->down, 1, file, level + 1);
  2284.  
  2285.       len = 0;
  2286.       break;
  2287.  
  2288.     case EOF :
  2289.     case ')' :
  2290.       return node;
  2291.  
  2292.     case '[' :
  2293.       if (len > 0 && no_node == 0) {
  2294.     (void) ungetc (ch, file);
  2295.     cmd[len++] = '\0';
  2296.  
  2297.     read_property (node, cmd, file);
  2298.       }
  2299.  
  2300.       else
  2301.     while (ch != ']' && ch != EOF) ch = getc (file);
  2302.  
  2303.       len = 0;
  2304.       break;
  2305.  
  2306.     default :
  2307.       if (isupper (ch) && len < 2)
  2308.     cmd[len++] = ch;
  2309.     }
  2310.  
  2311.   } while (ch != EOF);
  2312.  
  2313.   return node;
  2314. }
  2315.  
  2316. /*******************************************************************************************************
  2317.  */
  2318.  
  2319. SG_NodePtr SG_ReadTree (file)
  2320. FILE       *file;
  2321. {
  2322.   size = 19;
  2323.   root = NULL;
  2324.  
  2325.   (void) read_node ((SG_NodePtr) NULL, 0, file, 0);
  2326.   
  2327.   return root;
  2328. }
  2329.  
  2330. /*******************************************************************************************************
  2331.  */
  2332. SHAR_EOF
  2333. fi # end of overwriting check
  2334. if test -f 'write.c'
  2335. then
  2336.     echo shar: will not over-write existing file "'write.c'"
  2337. else
  2338. cat << \SHAR_EOF > 'write.c'
  2339. /****************************************************************************************************************
  2340.  *
  2341.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  2342.  *
  2343.  *  This program is distributed in the hope that it will be useful.
  2344.  *  Use and copying of this software and preparation of derivative works
  2345.  *  based upon this software are permitted, so long as the following
  2346.  *  conditions are met:
  2347.  *       o credit to the authors is acknowledged following current
  2348.  *         academic behaviour
  2349.  *       o no fees or compensation are charged for use, copies, or
  2350.  *         access to this software
  2351.  *       o this copyright notice is included intact.
  2352.  *  This software is made available AS IS, and no warranty is made about 
  2353.  *  the software or its performance. 
  2354.  * 
  2355.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  2356.  *  Send them to    dumesnil@etca.fr   or to:
  2357.  *       
  2358.  *       Antoine de Maricourt
  2359.  *       ETCA CREA-SP
  2360.  *       16 bis, avenue Prieur de la Cote d'Or
  2361.  *       94114 Arcueil Cedex
  2362.  *       France
  2363.  */
  2364.  
  2365. #include "sg.h"
  2366.  
  2367. #define PrintKeyword(id) (short_print == 0 ? sg_keywords[id].print : sg_keywords[id].keyword)
  2368. #define Newline(file)    { if (short_print == 0) if (fprintf (file, "\n") == EOF) return EOF; }
  2369.  
  2370. static int size        = 19;
  2371. static int short_print = 0;
  2372.  
  2373. /*******************************************************************************************************
  2374.  */
  2375.  
  2376. static int write_node (node, var, file, level)
  2377. SG_NodePtr  node;
  2378. int         var;
  2379. FILE       *file;
  2380. int         level;
  2381. {
  2382.   SG_PropertyPtr  property;
  2383.   unsigned char  *ptr;
  2384.   unsigned char   color;
  2385.   int             x;
  2386.   int             y;
  2387.  
  2388.   if (node != NULL) {
  2389.  
  2390.     if (node->right != NULL && var == 1)
  2391.       do {
  2392.     if (write_node (node, 0, file, level) == EOF) 
  2393.       return EOF;
  2394.  
  2395.     node = node->right;
  2396.       } while (node != NULL);
  2397.  
  2398.     else {
  2399.       if (fprintf (file, "(") == EOF)
  2400.     return EOF;
  2401.       Newline (file);
  2402.  
  2403.       if (fprintf (file, ";") == EOF)
  2404.     return EOF;
  2405.       Newline (file);
  2406.  
  2407.       if (level == 0) {
  2408.     if (fprintf (file, "%s[1]", PrintKeyword (SG_GaMe)) == EOF)
  2409.       return EOF;
  2410.     Newline (file);
  2411.       }
  2412.  
  2413.       goto sequence1;
  2414.  
  2415.     sequence  :
  2416.  
  2417.       if (fprintf (file, ";") == EOF)
  2418.     return EOF;
  2419.       Newline (file);
  2420.             
  2421.     sequence1 :
  2422.  
  2423.       switch (node->type) {
  2424.  
  2425.       case SG_EventType   :
  2426.       case SG_DiagramType :
  2427.  
  2428.     if ((ptr = node->setup) != NULL) {
  2429.  
  2430.       color = ~(*ptr & 0xc0);
  2431.         
  2432.       while (*ptr != SG_EOS) {
  2433.         if ((*ptr & 0xc0) != color && 
  2434.         ! ((*ptr & 0xc0) == SG_SETEB && color == SG_SETEW) &&
  2435.         ! ((*ptr & 0xc0) == SG_SETEW && color == SG_SETEB)) {
  2436.           color = *ptr & 0xc0;
  2437.         
  2438.           if (ptr != node->setup) {
  2439.         Newline (file);
  2440.           }
  2441.         
  2442.           switch (color) {
  2443.           case SG_SETB  : 
  2444.         if (fprintf (file, "%s", PrintKeyword (SG_AddBlack))  == EOF)
  2445.           return EOF;
  2446.         break;
  2447.           case SG_SETW  : 
  2448.         if (fprintf (file, "%s", PrintKeyword (SG_AddWhite)) == EOF)
  2449.           return EOF;
  2450.         break;
  2451.           case SG_SETEB :
  2452.           case SG_SETEW : 
  2453.         if (fprintf (file, "%s", PrintKeyword (SG_AddEmpty)) == EOF)
  2454.           return EOF; 
  2455.         break;
  2456.           }
  2457.         }
  2458.           
  2459.         x = *ptr++ & 0x3f;
  2460.         y = *ptr++ & 0x3f;
  2461.  
  2462.         if (fprintf (file, "[%c%c]", 'a' - 1 + x , 'a' + size - y) == EOF)
  2463.           return EOF;
  2464.              
  2465.       }
  2466.         
  2467.       Newline (file);
  2468.     }
  2469.  
  2470.     if (fprintf (file, "%s[%c]", 
  2471.              PrintKeyword (SG_PLayer),
  2472.              (node->player == SG_WhiteStone) ? 'W' : 'B') 
  2473.         == EOF)
  2474.       return EOF;
  2475.     Newline (file);
  2476.  
  2477.     break;
  2478.  
  2479.       case SG_MoveType :
  2480.     if (node->x == 0 && node->y == 0) {
  2481.       if (fprintf (file, "%s[tt]", 
  2482.                PrintKeyword ((node->color ==  SG_BlackStone) ? SG_Black : SG_White))
  2483.           == EOF)
  2484.         return EOF;
  2485.       Newline (file);
  2486.     }
  2487.  
  2488.     else {
  2489.       if (fprintf (file, "%s[%c%c]", 
  2490.                PrintKeyword ((node->color ==  SG_BlackStone) ? SG_Black : SG_White),
  2491.                'a' - 1 + node->x, 
  2492.                'a' + size - node->y)
  2493.           == EOF)
  2494.         return EOF;
  2495.       Newline (file);
  2496.     }
  2497.  
  2498.     break;
  2499.       }
  2500.  
  2501.       property = node->property;
  2502.  
  2503.       while (property != NULL) {
  2504.     switch (property->id) {
  2505.     
  2506.     case SG_VieW :
  2507.       if (fprintf (file, "%s[%c%c][%c%c]",
  2508.                PrintKeyword (SG_VieW),
  2509.                'a' - 1 +    ((property->data.ivalue >> 16) & 0xff),
  2510.                'a' + size - ((property->data.ivalue >> 24) & 0xff),
  2511.                'a' - 1 +    ((property->data.ivalue      ) & 0xff),
  2512.                'a' + size - ((property->data.ivalue >>  8) & 0xff))
  2513.           == EOF)
  2514.         return EOF;
  2515.       Newline (file);
  2516.       break;
  2517.       
  2518.     case SG_SiZe :
  2519.       size = property->data.ivalue;
  2520.       if (fprintf (file, "%s[%d]", 
  2521.                PrintKeyword (SG_SiZe),
  2522.                property->data.ivalue)
  2523.           == EOF)
  2524.         return EOF;
  2525.       Newline (file);
  2526.       break;
  2527.       
  2528.     case SG_KO :
  2529.       if (fprintf (file, "%s[%c%c]",
  2530.                PrintKeyword (SG_KO),
  2531.                'a' - 1    + ((property->data.ivalue >> 8) & 0x3f),
  2532.                'a' + size - (property->data.ivalue & 0x3f))
  2533.           == EOF)
  2534.         return EOF;
  2535.       Newline (file);
  2536.       break;
  2537.        
  2538.     case SG_Comment     :
  2539.     case SG_GameName    :
  2540.     case SG_GameComment :
  2541.     case SG_nodeName    :
  2542.     case SG_EVent       :
  2543.     case SG_ROund       :
  2544.     case SG_DaTe        :
  2545.     case SG_PlaCe       :
  2546.     case SG_REsult      :
  2547.     case SG_USer        :
  2548.     case SG_TiMe        :
  2549.     case SG_SOurce      :
  2550.     case SG_BlackRank   :
  2551.     case SG_WhiteRank   :
  2552.     case SG_BlackSpec   :
  2553.     case SG_WhiteSpec   :
  2554.     case SG_HAndicap    :
  2555.     case SG_KoMi        :
  2556.     case SG_PlayerBlack :
  2557.     case SG_PlayerWhite :
  2558.     case SG_BlackLeft   :
  2559.     case SG_WhiteLeft   :
  2560.  
  2561.       if ((ptr = property ->data.pvalue) != NULL && strcmp ((char *) ptr, "") != 0) {
  2562.         if (fprintf (file, "%s[", PrintKeyword (property->id)) == EOF)
  2563.           return EOF;
  2564.  
  2565.         while (*ptr != '\0') {
  2566.           if (*ptr == ']')
  2567.         if (putc ('\\', file) == EOF) return EOF;
  2568.           if (putc ((char) *ptr, file) == EOF) return EOF;
  2569.           ptr++;
  2570.         }
  2571.  
  2572.         if (fprintf (file, "]") == EOF) return EOF; Newline (file);
  2573.       }
  2574.       break;
  2575.  
  2576.     case SG_Letters :
  2577.     case SG_Marked  :
  2578.       if ((ptr = property->data.pvalue) != NULL) {
  2579.         if (fprintf (file, "%s", 
  2580.              PrintKeyword (property->id))
  2581.         == EOF)
  2582.           return EOF;
  2583.     
  2584.         while (*ptr != SG_EOS) {
  2585.           x = *ptr++ & 0x3f;
  2586.           y = *ptr++ & 0x3f;
  2587.           
  2588.           if (x != 0 || y != 0)
  2589.         if (fprintf (file, "[%c%c]", 'a' - 1 + x , 'a' + size - y) == EOF)
  2590.           return EOF;
  2591.         }
  2592.  
  2593.         Newline (file);
  2594.       }
  2595.       break;
  2596.     }
  2597.  
  2598.     property = property->next;
  2599.       }
  2600.  
  2601.       if (node->down != NULL) {
  2602.     node = node->down;
  2603.  
  2604.     if (node->right != NULL) {
  2605.       if (write_node (node, 1, file, level + 1) == EOF) 
  2606.         return EOF;
  2607.     }
  2608.     else
  2609.       goto sequence;
  2610.       }
  2611.  
  2612.       if (fprintf (file, ")") == EOF)
  2613.     return EOF;
  2614.       Newline (file);
  2615.     }
  2616.   }
  2617.  
  2618.   return 0;
  2619. }
  2620.  
  2621. /*******************************************************************************************************
  2622.  */
  2623.  
  2624. int SG_WriteTree (node, file, shrt)
  2625. SG_NodePtr  node;
  2626. FILE       *file;
  2627. int         shrt;
  2628. {
  2629.   short_print = shrt;
  2630.   size        = 19;
  2631.  
  2632.   return write_node (node, 1, file, 0);
  2633. }
  2634.  
  2635. /*******************************************************************************************************
  2636.  */
  2637. SHAR_EOF
  2638. fi # end of overwriting check
  2639. if test -f 'play.c'
  2640. then
  2641.     echo shar: will not over-write existing file "'play.c'"
  2642. else
  2643. cat << \SHAR_EOF > 'play.c'
  2644. /****************************************************************************************************************
  2645.  *
  2646.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  2647.  *
  2648.  *  This program is distributed in the hope that it will be useful.
  2649.  *  Use and copying of this software and preparation of derivative works
  2650.  *  based upon this software are permitted, so long as the following
  2651.  *  conditions are met:
  2652.  *       o credit to the authors is acknowledged following current
  2653.  *         academic behaviour
  2654.  *       o no fees or compensation are charged for use, copies, or
  2655.  *         access to this software
  2656.  *       o this copyright notice is included intact.
  2657.  *  This software is made available AS IS, and no warranty is made about 
  2658.  *  the software or its performance. 
  2659.  * 
  2660.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  2661.  *  Send them to    dumesnil@etca.fr   or to:
  2662.  *       
  2663.  *       Antoine de Maricourt
  2664.  *       ETCA CREA-SP
  2665.  *       16 bis, avenue Prieur de la Cote d'Or
  2666.  *       94114 Arcueil Cedex
  2667.  *       France
  2668.  */
  2669.  
  2670. #include "xgoban.h"
  2671.  
  2672. static int  size = 19;
  2673. static int  board[21][21];
  2674. static int  tmp_board[21][21];
  2675.  
  2676. static int  x_ko = 0;
  2677. static int  y_ko = 0;
  2678. static int  last_player;
  2679.  
  2680. static long mark = 0;
  2681. static long marks[21][21];
  2682.  
  2683. /*******************************************************************************************************
  2684.  *
  2685.  *   Recopie le goban <src> dans <dst>. Utile pour faire la difference de deux positions et
  2686.  *   etablir les proprietes AddBlack, AddWhite et AddEmtpy.
  2687.  */
  2688.     
  2689. static void copyBoard (src, dst)
  2690. int src[21][21];
  2691. int dst[21][21];
  2692. {
  2693.   int x;
  2694.   int y;
  2695.   
  2696.   for (x = 0; x < size + 2; x++)
  2697.     for (y = 0; y < size + 2; y++)
  2698.       dst[x][y] = src[x][y];
  2699. }
  2700.  
  2701. /*******************************************************************************************************
  2702.  *
  2703.  *   Compte les libertes d'une chaine.
  2704.  */
  2705.  
  2706. static int countLiberty (board, x, y, color)
  2707. int  board[21][21];
  2708. int  x;
  2709. int  y;
  2710. int  color;
  2711. {
  2712.   if (marks[x][y] != mark) {
  2713.     marks[x][y] = mark;
  2714.  
  2715.     if (board[x][y] == SG_EmptyPoint) return 1;
  2716.     if (board[x][y] == SG_Border    ) return 0;
  2717.     if (board[x][y] != color        ) return 0;
  2718.  
  2719.     return (countLiberty (board, x - 1, y, color) +
  2720.         countLiberty (board, x + 1, y, color) +
  2721.         countLiberty (board, x, y - 1, color) +
  2722.         countLiberty (board, x, y + 1, color));
  2723.   }
  2724.   
  2725.   return 0;
  2726. }
  2727.  
  2728. /*******************************************************************************************************
  2729.  *
  2730.  *   Supprime une chaine du goban.
  2731.  */
  2732.  
  2733. static void removeString (board, x, y, color)
  2734. int  board[21][21];
  2735. int  x;
  2736. int  y;
  2737. int  color;
  2738. {
  2739.   if (board[x][y] == color) {
  2740.     board[x][y] = SG_EmptyPoint;
  2741.  
  2742.     removeString (board, x + 1, y, color);
  2743.     removeString (board, x - 1, y, color);
  2744.     removeString (board, x, y + 1, color);
  2745.     removeString (board, x, y - 1, color);
  2746.   }
  2747. }
  2748.  
  2749. /*******************************************************************************************************
  2750.  *
  2751.  *   Fait la difference entre deux positions et construit la liste des pierres a poser ou enlever.
  2752.  *   On distingue EB et EW pour que cette propriete soit reversible.
  2753.  */
  2754.  
  2755. static void getSetup (dst, old, new)
  2756. unsigned char **dst;
  2757. int             old[21][21];
  2758. int             new[21][21];
  2759. {
  2760.   int            x;
  2761.   int            y;
  2762.   unsigned char  setup[361 * 2];
  2763.   unsigned char *ptr = setup;
  2764.  
  2765.   for (x = 1; x < size + 1; x++)
  2766.     for (y = 1; y < size + 1; y++)
  2767.       if (new[x][y] != old[x][y])
  2768.     if (old[x][y] == SG_BlackStone) {
  2769.       *ptr++ = SG_SETEB | ((unsigned char) x & 0x3f);
  2770.       *ptr++ = SG_SETEB | ((unsigned char) y & 0x3f);
  2771.     }
  2772.   
  2773.     else if (old[x][y] == SG_WhiteStone) {
  2774.       *ptr++ = SG_SETEW | ((unsigned char) x & 0x3f);
  2775.       *ptr++ = SG_SETEW | ((unsigned char) y & 0x3f);
  2776.     }
  2777.   
  2778.   for (x = 1; x < size + 1; x++)
  2779.     for (y = 1; y < size + 1; y++)
  2780.       if (new[x][y] != old[x][y])
  2781.     if (new[x][y] == SG_BlackStone) {
  2782.       *ptr++ = SG_SETB | ((unsigned char) x & 0x3f);
  2783.       *ptr++ = SG_SETB | ((unsigned char) y & 0x3f);
  2784.     }
  2785.   
  2786.   for (x = 1; x < size + 1; x++)
  2787.     for (y = 1; y < size + 1; y++)
  2788.       if (new[x][y] != old[x][y])
  2789.     if (new[x][y] == SG_WhiteStone) {
  2790.       *ptr++ = SG_SETW | ((unsigned char) x & 0x3f);
  2791.       *ptr++ = SG_SETW | ((unsigned char) y & 0x3f);
  2792.     }
  2793.   
  2794.   if (ptr != setup) {
  2795.     *ptr++ = SG_EOS;
  2796.     SG_strcpy (dst, setup, SG_EOS);
  2797.   }
  2798. }
  2799.  
  2800. /*******************************************************************************************************
  2801.  *
  2802.  *   Quelques fonctions pour editer des diagrames.
  2803.  */
  2804.  
  2805. void StartDiagram () 
  2806. {
  2807.   copyBoard (board, tmp_board);
  2808. }
  2809.  
  2810. void AddStone (x, y, color)
  2811. int x;
  2812. int y;
  2813. int color;
  2814. {
  2815.   board[x][y] = color;
  2816. }
  2817.  
  2818. unsigned char *EndDiagram ()
  2819. {
  2820.   unsigned char *ptr = NULL;
  2821.  
  2822.   getSetup (&ptr, tmp_board, board);
  2823.   copyBoard (tmp_board, board);
  2824.  
  2825.   return ptr;
  2826. }
  2827.  
  2828. /*******************************************************************************************************
  2829.  */
  2830.  
  2831. int Play (node)
  2832. SG_NodePtr    node;
  2833. {
  2834.   SG_PropertyPtr  property;
  2835.   SG_NodePtr      tmp;
  2836.   unsigned char  *ptr;
  2837.   int             x;
  2838.   int             y;
  2839.   int             color;
  2840.   int             prisoner;
  2841.   int             lib;
  2842.  
  2843.   if (node != NULL)
  2844.     switch (node->type) {
  2845.  
  2846.     case SG_EventType   :
  2847.       size     = 19;
  2848.       property = node->property;
  2849.       
  2850.       while (property != NULL) {
  2851.     if (property->id == SG_SiZe)
  2852.       if (property->data.ivalue > 1 && property->data.ivalue < 20)
  2853.         size = property->data.ivalue;
  2854.  
  2855.     property = property->next;
  2856.       }
  2857.       
  2858.       for (x = 0; x < size + 2; x++)
  2859.     for (y = 0; y < size + 2; y++)
  2860.       board[x][y] = (x == 0 || y == 0 || x == size + 1 || y == size + 1) ? 
  2861.         SG_Border : SG_EmptyPoint;
  2862.     
  2863.     case SG_DiagramType :
  2864.       
  2865.       node->num = 0;
  2866.  
  2867.       if (node->setup != NULL) {
  2868.     copyBoard (board, tmp_board);
  2869.  
  2870.     ptr = node->setup;
  2871.     
  2872.     while (*ptr != SG_EOS) {
  2873.       color = (int) (*ptr   & 0xc0);
  2874.       x     = (int) (*ptr++ & 0x3f);
  2875.       y     = (int) (*ptr++ & 0x3f);
  2876.  
  2877.       switch (color) {
  2878.       case SG_SETB  : board[x][y] = SG_BlackStone; break;
  2879.       case SG_SETW  : board[x][y] = SG_WhiteStone; break;
  2880.       case SG_SETEB :
  2881.       case SG_SETEW : board[x][y] = SG_EmptyPoint; break;
  2882.       }
  2883.  
  2884.     }
  2885.  
  2886.     getSetup (&node->setup, tmp_board, board);
  2887.       }
  2888.  
  2889.       x_ko = y_ko = 0;
  2890.       break;
  2891.       
  2892.     case SG_MoveType :
  2893.  
  2894.       if (node->num == -1) {
  2895.     tmp = node;
  2896.     while (tmp->left != NULL) tmp = tmp->left;
  2897.     tmp = tmp->up;
  2898.     
  2899.     if (tmp != NULL)
  2900.       node->num = tmp->num + 1;
  2901.       }
  2902.  
  2903.       x            = node->x;
  2904.       y            = node->y;
  2905.       color        = node->color;
  2906.       node->player = (node->color == SG_BlackStone) ? SG_WhiteStone : SG_BlackStone;
  2907.  
  2908.       if ((x_ko != 0 || y_ko != 0) && color != last_player)
  2909.     SG_MakeProperty (node, SG_ko, (last_player << 16) + (x_ko << 8) + y_ko);
  2910.       
  2911.       if (x == 0 && y == 0) {
  2912.     x_ko = y_ko = 0;
  2913.     return SG_OK;
  2914.       }
  2915.  
  2916.       if (board[x][y] != SG_EmptyPoint)
  2917.     return SG_PlayIllegal;
  2918.       
  2919.       if (x == x_ko && y == y_ko && color != last_player)
  2920.     return SG_PlayKo;
  2921.  
  2922.       board[x][y] = color;
  2923.  
  2924.       prisoner = 0;
  2925.       color    = (color == SG_BlackStone) ? SG_WhiteStone : SG_BlackStone;
  2926.       
  2927.       mark++; if (board[x + 1][y] == color && countLiberty (board, x + 1, y, color) == 0) prisoner |= 1;
  2928.       mark++; if (board[x - 1][y] == color && countLiberty (board, x - 1, y, color) == 0) prisoner |= 2;
  2929.       mark++; if (board[x][y + 1] == color && countLiberty (board, x, y + 1, color) == 0) prisoner |= 4;
  2930.       mark++; if (board[x][y - 1] == color && countLiberty (board, x, y - 1, color) == 0) prisoner |= 8;
  2931.  
  2932.       mark++; 
  2933.       if ((lib = countLiberty (board, x, y, board[x][y])) == 0 && prisoner == 0) {
  2934.     board[x][y] = SG_EmptyPoint;
  2935.     return SG_PlaySuicide;
  2936.       }
  2937.  
  2938.       x_ko = y_ko = 0;
  2939.  
  2940.       if (prisoner != 0) {
  2941.     copyBoard (board, tmp_board);
  2942.  
  2943.     if (prisoner & 1) removeString (board, x + 1, y, color);
  2944.     if (prisoner & 2) removeString (board, x - 1, y, color);
  2945.     if (prisoner & 4) removeString (board, x, y + 1, color);
  2946.     if (prisoner & 8) removeString (board, x, y - 1, color);
  2947.  
  2948.     getSetup (&node->setup, tmp_board, board);
  2949.  
  2950.     ptr = node->setup;
  2951.  
  2952.     prisoner = 0;
  2953.     while (*ptr != SG_EOS) {
  2954.       prisoner++;
  2955.       ptr += 2;
  2956.     }
  2957.  
  2958.     if (prisoner == 1 && lib == 0 &&
  2959.         board[x + 1][y] != board[x][y] &&
  2960.         board[x - 1][y] != board[x][y] &&
  2961.         board[x][y + 1] != board[x][y] &&
  2962.         board[x][y - 1] != board[x][y]) {
  2963.  
  2964.       x_ko = (int) (*node->setup       & 0x3f);
  2965.       y_ko = (int) (*(node->setup + 1) & 0x3f);
  2966.  
  2967.       SG_MakeProperty (node, SG_KO, (x_ko << 8) + y_ko);
  2968.     }
  2969.       }
  2970.       
  2971.       last_player = (int) node->color;
  2972.       break;
  2973.     }
  2974.  
  2975.   return SG_OK;
  2976. }
  2977.  
  2978. /*******************************************************************************************************
  2979.  */
  2980.     
  2981. void Unplay (node)
  2982. SG_NodePtr    node;
  2983. {
  2984.   SG_PropertyPtr  property;
  2985.   unsigned char  *ptr;
  2986.   int             x;
  2987.   int             y;
  2988.   int             color;
  2989.  
  2990.   if (node != NULL)
  2991.     switch (node->type) {
  2992.       
  2993.     case SG_EventType   :
  2994.       size     = 19;
  2995.       
  2996.       for (x = 0; x < size + 2; x++)
  2997.     for (y = 0; y < size + 2; y++)
  2998.       board[x][y] = (x == 0 || y == 0 || x == size + 1 || y == size + 1) ? 
  2999.         SG_Border : SG_EmptyPoint;
  3000.  
  3001.     case SG_DiagramType :
  3002.       
  3003.       if (node->setup != NULL) {
  3004.     
  3005.     ptr = node->setup;
  3006.     
  3007.     while (*ptr != SG_EOS) {
  3008.       color = (int) (*ptr   & 0xc0);
  3009.       x     = (int) (*ptr++ & 0x3f);
  3010.       y     = (int) (*ptr++ & 0x3f);
  3011.       
  3012.       switch (color) {
  3013.       case SG_SETEB : board[x][y] = SG_BlackStone; break;
  3014.       case SG_SETEW : board[x][y] = SG_WhiteStone; break;
  3015.       case SG_SETB  :
  3016.       case SG_SETW  : board[x][y] = SG_EmptyPoint; break;
  3017.       }
  3018.     }
  3019.       }
  3020.       break;
  3021.       
  3022.     case SG_MoveType :
  3023.       x_ko = y_ko = 0;
  3024.       last_player = SG_EmptyPoint;
  3025.  
  3026.       property = node->property;
  3027.  
  3028.       while (property != NULL) {
  3029.     if (property->id == SG_ko) {
  3030.       last_player = (int) ( property->data.ivalue >> 16);
  3031.       x_ko        = (int) ((property->data.ivalue >> 8) & 0x3f);
  3032.       y_ko        = (int) ( property->data.ivalue       & 0x3f);
  3033.       break;
  3034.     }
  3035.  
  3036.     property = property->next;
  3037.       }
  3038.  
  3039.       x = (int) node->x;
  3040.       y = (int) node->y;
  3041.       
  3042.       if (x == 0 && y == 0)
  3043.     break;
  3044.  
  3045.       board[x][y] = SG_EmptyPoint;
  3046.       
  3047.       if (node->setup != NULL) {
  3048.     ptr   = node->setup;
  3049.     color = (node->color == SG_BlackStone) ? SG_WhiteStone : SG_BlackStone;
  3050.     
  3051.     while (*ptr != SG_EOS) {
  3052.       x = (int) (*ptr++ & 0x3f);
  3053.       y = (int) (*ptr++ & 0x3f);
  3054.       
  3055.       board[x][y] = color;
  3056.     }
  3057.       }
  3058.       break;
  3059.     }
  3060. }
  3061.  
  3062. /*******************************************************************************************************
  3063.  */
  3064. SHAR_EOF
  3065. fi # end of overwriting check
  3066. if test -f 'event.c'
  3067. then
  3068.     echo shar: will not over-write existing file "'event.c'"
  3069. else
  3070. cat << \SHAR_EOF > 'event.c'
  3071. /****************************************************************************************************************
  3072.  *
  3073.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  3074.  *
  3075.  *  This program is distributed in the hope that it will be useful.
  3076.  *  Use and copying of this software and preparation of derivative works
  3077.  *  based upon this software are permitted, so long as the following
  3078.  *  conditions are met:
  3079.  *       o credit to the authors is acknowledged following current
  3080.  *         academic behaviour
  3081.  *       o no fees or compensation are charged for use, copies, or
  3082.  *         access to this software
  3083.  *       o this copyright notice is included intact.
  3084.  *  This software is made available AS IS, and no warranty is made about 
  3085.  *  the software or its performance. 
  3086.  * 
  3087.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  3088.  *  Send them to    dumesnil@etca.fr   or to:
  3089.  *       
  3090.  *       Antoine de Maricourt
  3091.  *       ETCA CREA-SP
  3092.  *       16 bis, avenue Prieur de la Cote d'Or
  3093.  *       94114 Arcueil Cedex
  3094.  *       France
  3095.  */
  3096.  
  3097. #include <stdio.h>
  3098. #include <ctype.h>
  3099.  
  3100. #include <X11/Intrinsic.h>
  3101. #include <X11/Shell.h>
  3102. #include <X11/StringDefs.h>
  3103.  
  3104. #include <X11/Xaw/Command.h>
  3105. #include <X11/Xaw/Form.h>
  3106. #include <X11/Xaw/Label.h>
  3107. #include <X11/Xaw/AsciiText.h>
  3108.  
  3109. #include "Goban.h"
  3110. #include "xgoban.h"
  3111.  
  3112. static Widget   i_top;
  3113. static Widget   form;
  3114.  
  3115. static Widget   w_GN;
  3116. static Widget   w_PW;
  3117. static Widget   w_PB;
  3118. static Widget   w_WR;
  3119. static Widget   w_BR;
  3120. static Widget   w_WS;
  3121. static Widget   w_BS;
  3122. static Widget   w_EV;
  3123. static Widget   w_PC;
  3124. static Widget   w_DT;
  3125. static Widget   w_RO;
  3126. static Widget   w_HA;
  3127. static Widget   w_KM;
  3128. static Widget   w_TM;
  3129. static Widget   w_RE;
  3130. static Widget   w_US;
  3131. static Widget   w_SO;
  3132. static Widget   w_GC;
  3133.  
  3134. /*******************************************************************************************************
  3135.  */
  3136.  
  3137. static void SetEventProperty (w, id, node)
  3138. Widget      w;
  3139. int         id;
  3140. SG_NodePtr  node;
  3141. {
  3142.   Arg             arg;
  3143.   String          text;
  3144.   SG_PropertyPtr  property;
  3145.  
  3146.   XtSetArg (arg, XtNstring, &text); XtGetValues (w, &arg, 1);
  3147.  
  3148.   if (node != NULL) {
  3149.     property = SG_GetProperty (node, id);
  3150.  
  3151.     if (property != NULL && strcmp (property->data.pvalue, text) != 0) {
  3152.       SG_strcpy (&property->data.pvalue, text, '\0');
  3153.       modified = True;
  3154.     }
  3155.  
  3156.     else if (strcmp (text, "") != 0 && property == NULL) {
  3157.       SG_MakeProperty (node, id, text);
  3158.       modified = True;
  3159.     }
  3160.   }
  3161. }
  3162.  
  3163. /*******************************************************************************************************
  3164.  */
  3165.  
  3166. static void infoCancel   (w, event) 
  3167. Widget    w;
  3168. XEvent   *event;
  3169.   XtPopdown (i_top);
  3170. }
  3171.  
  3172. /*******************************************************************************************************
  3173.  */
  3174.  
  3175. static void highlightText  (w, event) 
  3176. Widget    w;
  3177. XEvent   *event;
  3178.   Arg args[1];
  3179.  
  3180.   if (edit == True) {
  3181.     XtSetArg (args[0], XtNdisplayCaret,  True);
  3182.     XtSetValues (w, args, 1);
  3183.   }
  3184. }
  3185.  
  3186. /*******************************************************************************************************
  3187.  */
  3188.  
  3189. static void unhighlightText  (w, event) 
  3190. Widget    w;
  3191. XEvent   *event;
  3192.   Arg args[1];
  3193.  
  3194.   if (edit == True) {
  3195.     XtSetArg (args[0], XtNdisplayCaret,  False);
  3196.     XtSetValues (w, args, 1);
  3197.   }
  3198. }
  3199.  
  3200. /*******************************************************************************************************
  3201.  */
  3202.  
  3203. static void infoConfirm  (w, event) 
  3204. Widget    w;
  3205. XEvent   *event;
  3206.   SG_NodePtr node = current_node;
  3207.  
  3208.   if (edit == True) {
  3209.     while (node->type != SG_EventType) {
  3210.       while (node->left != NULL)
  3211.         node = node->left;
  3212.       while (node->up != NULL)
  3213.         node = node->up;
  3214.     }
  3215.     
  3216.     SetEventProperty (w_PB, SG_PlayerBlack, node);
  3217.     SetEventProperty (w_PW, SG_PlayerWhite, node);
  3218.     SetEventProperty (w_BS, SG_BlackSpec  , node);
  3219.     SetEventProperty (w_WS, SG_WhiteSpec  , node);
  3220.     SetEventProperty (w_BR, SG_BlackRank  , node);
  3221.     SetEventProperty (w_WR, SG_WhiteRank  , node);
  3222.     SetEventProperty (w_EV, SG_EVent      , node);
  3223.     SetEventProperty (w_RO, SG_ROund      , node);
  3224.     SetEventProperty (w_PC, SG_PlaCe      , node);
  3225.     SetEventProperty (w_DT, SG_DaTe       , node);
  3226.     SetEventProperty (w_HA, SG_HAndicap   , node);
  3227.     SetEventProperty (w_KM, SG_KoMi       , node);
  3228.     SetEventProperty (w_TM, SG_TiMe       , node);
  3229.     SetEventProperty (w_RE, SG_REsult     , node);
  3230.     SetEventProperty (w_US, SG_USer       , node);
  3231.     SetEventProperty (w_SO, SG_SOurce     , node);
  3232.     SetEventProperty (w_GN, SG_GameName   , node);
  3233.     SetEventProperty (w_GC, SG_GameComment, node);
  3234.   }
  3235.    
  3236.   XtPopdown (i_top);
  3237. }
  3238.  
  3239. void EventInfo (w, event)
  3240. Widget    w;
  3241. XEvent   *event;
  3242. {
  3243.   SG_NodePtr     node = current_node;
  3244.   SG_PropertyPtr property;
  3245.   Arg            args[4];
  3246.   int            xtargc;
  3247.   Widget         text;
  3248.  
  3249.   while (node->type != SG_EventType) {
  3250.     while (node->left != NULL)
  3251.       node = node->left;
  3252.     while (node->up != NULL)
  3253.       node = node->up;
  3254.   }
  3255.  
  3256.   if (node->type == SG_EventType) {
  3257.     CenterWindow (i_top, NULL);
  3258.  
  3259.     xtargc = 0;
  3260.     XtSetArg (args[xtargc], XtNstring, (XtArgVal) ""); xtargc++;
  3261.     XtSetArg (args[xtargc], XtNeditType, 
  3262.               (XtArgVal) (edit == True) ? XawtextEdit : XawtextRead); xtargc++;
  3263.  
  3264.     
  3265.     XtSetValues (w_PB, args, xtargc);
  3266.     XtSetValues (w_PW, args, xtargc);
  3267.     XtSetValues (w_BS, args, xtargc);
  3268.     XtSetValues (w_WS, args, xtargc);
  3269.     XtSetValues (w_BR, args, xtargc);
  3270.     XtSetValues (w_WR, args, xtargc);
  3271.     XtSetValues (w_EV, args, xtargc);
  3272.     XtSetValues (w_RO, args, xtargc);
  3273.     XtSetValues (w_PC, args, xtargc);
  3274.     XtSetValues (w_DT, args, xtargc);
  3275.     XtSetValues (w_HA, args, xtargc);
  3276.     XtSetValues (w_KM, args, xtargc);
  3277.     XtSetValues (w_TM, args, xtargc);
  3278.     XtSetValues (w_RE, args, xtargc);
  3279.     XtSetValues (w_US, args, xtargc);
  3280.     XtSetValues (w_SO, args, xtargc);
  3281.     XtSetValues (w_GC, args, xtargc);
  3282.     XtSetValues (w_GN, args, xtargc);
  3283.  
  3284.     property = node->property;
  3285.     
  3286.     while (property != NULL) {
  3287.       switch (property->id) {
  3288.       case SG_PlayerBlack : text = w_PB; break;
  3289.       case SG_PlayerWhite : text = w_PW; break;
  3290.       case SG_BlackSpec   : text = w_BS; break;
  3291.       case SG_WhiteSpec   : text = w_WS; break;
  3292.       case SG_BlackRank   : text = w_BR; break;
  3293.       case SG_WhiteRank   : text = w_WR; break;
  3294.       case SG_EVent       : text = w_EV; break;
  3295.       case SG_ROund       : text = w_RO; break;
  3296.       case SG_PlaCe       : text = w_PC; break;
  3297.       case SG_DaTe        : text = w_DT; break;
  3298.       case SG_HAndicap    : text = w_HA; break;
  3299.       case SG_KoMi        : text = w_KM; break;
  3300.       case SG_TiMe        : text = w_TM; break;
  3301.       case SG_REsult      : text = w_RE; break;
  3302.       case SG_USer        : text = w_US; break;
  3303.       case SG_SOurce      : text = w_SO; break;
  3304.       case SG_GameName    : text = w_GN; break;
  3305.       case SG_GameComment : text = w_GC; break;
  3306.       default             : text = NULL;
  3307.       }
  3308.  
  3309.       if (text != NULL && property->data.pvalue != NULL)
  3310.     { XtSetArg (args[0], XtNstring, property->data.pvalue);    XtSetValues (text, args, 1); }
  3311.  
  3312.       property = property->next;
  3313.     }
  3314.  
  3315.     XtPopup (i_top, XtGrabNonexclusive);
  3316.   }
  3317. }
  3318.  
  3319. /*******************************************************************************************************
  3320.  */
  3321.  
  3322. static Widget make_label (form, name, label, horiz, vert, width, justify)
  3323. Widget    form;
  3324. String    name;
  3325. String    label;
  3326. Widget    horiz;
  3327. Widget    vert;
  3328. Dimension width;
  3329. XtArgVal  justify;
  3330. {
  3331.   Arg args[8];
  3332.   int xtargc;
  3333.  
  3334.   xtargc = 0;
  3335.   if (horiz != NULL) { XtSetArg (args[xtargc], XtNfromHoriz, horiz); xtargc++; } 
  3336.   if (vert  != NULL) { XtSetArg (args[xtargc], XtNfromVert , vert ); xtargc++; }
  3337.  
  3338.   XtSetArg (args[xtargc], XtNjustify       , justify  ); xtargc++;
  3339.   XtSetArg (args[xtargc], XtNlabel         , label    ); xtargc++;
  3340.   XtSetArg (args[xtargc], XtNwidth         , width + 2); xtargc++;
  3341.   XtSetArg (args[xtargc], XtNborderWidth   , 0        ); xtargc++;
  3342.   XtSetArg (args[xtargc], XtNinternalHeight, 3        ); xtargc++;
  3343.  
  3344.   return XtCreateManagedWidget (name, labelWidgetClass, form, args, xtargc);
  3345. }
  3346.  
  3347. /*******************************************************************************************************
  3348.  */
  3349.  
  3350. static XtTranslations translations;
  3351.  
  3352. static Widget make_text (form, name, horiz, vert, width)
  3353. Widget    form;
  3354. String    name;
  3355. Widget    horiz;
  3356. Widget    vert;
  3357. Dimension width;
  3358. {
  3359.   Arg args[8];
  3360.   int xtargc;
  3361.  
  3362.   xtargc = 0;
  3363.   if (horiz != NULL) { XtSetArg (args[xtargc], XtNfromHoriz, (XtArgVal) horiz); xtargc++; } 
  3364.   if (vert  != NULL) { XtSetArg (args[xtargc], XtNfromVert , (XtArgVal) vert ); xtargc++; }
  3365.  
  3366.   XtSetArg (args[xtargc], XtNwidth       , (XtArgVal) width       ); xtargc++;
  3367.   XtSetArg (args[xtargc], XtNeditType    , (XtArgVal) XawtextEdit ); xtargc++;
  3368.   XtSetArg (args[xtargc], XtNtranslations, (XtArgVal) translations); xtargc++;
  3369.   XtSetArg (args[xtargc], XtNdisplayCaret, (XtArgVal) False       ); xtargc++;
  3370.  
  3371.   return XtCreateManagedWidget (name, asciiTextWidgetClass, form, args, xtargc);
  3372. }
  3373.  
  3374. /*******************************************************************************************************
  3375.  */
  3376.  
  3377. void makeEventWindow (toplevel, app_context)
  3378. Widget        toplevel;
  3379. XtAppContext  app_context;
  3380.  
  3381. {
  3382.   static XtActionsRec   actions[] = {
  3383.     { "infoConfirm"      , infoConfirm     , },
  3384.     { "infoCancel"       , infoCancel      , },
  3385.     { "highlightText"    , highlightText   , },
  3386.     { "unhighlightText"  , unhighlightText , },
  3387.   }; 
  3388.  
  3389.   Arg    args[10];
  3390.   int    xtargc;
  3391.  
  3392.   Widget game;
  3393.   Widget name, rank, species, white, black;
  3394.   Widget event, place, date, round;
  3395.   Widget handicap, komi, time, result;
  3396.   Widget user, source;
  3397.   Widget cancel, confirm;
  3398.    
  3399.   XtAppAddActions (app_context, actions, XtNumber(actions));
  3400.  
  3401.   translations = XtParseTranslationTable 
  3402.     ("#override                            \
  3403.       <EnterWindow>  : highlightText()   \n\
  3404.       <LeaveWindow>  : unhighlightText() \n\
  3405.       <Key> Escape   : infoCancel()      \n\
  3406.       <Key> Linefeed : infoConfirm()     \n\
  3407.       <Key> Return   : infoConfirm()     \n\
  3408.       Ctrl <Key> J   : infoConfirm()     \n\
  3409.       Ctrl <Key> M   : infoConfirm()");
  3410.  
  3411.   i_top    = XtCreatePopupShell    ("event"        , transientShellWidgetClass, toplevel , NULL, 0);
  3412.  
  3413.   xtargc = 0;
  3414.   XtSetArg (args[xtargc], XtNtranslations, (XtArgVal) translations); xtargc++;
  3415.  
  3416.   form     = XtCreateManagedWidget ("eventForm"    , formWidgetClass          , i_top      , args, xtargc);
  3417.  
  3418.   
  3419.   game     = make_label (form, "game"    , "Game"    , NULL   , NULL    , (Dimension) 66 , XtJustifyLeft);
  3420.  
  3421.   w_GN     = make_text  (form, "GN"      , game      , NULL   , (Dimension) 200);
  3422.  
  3423.   name     = make_label (form, "name"    , "Name"    , game   , game    , (Dimension) 200, XtJustifyCenter);
  3424.   rank     = make_label (form, "rank"    , "Rank"    , name   , game    , (Dimension) 80 , XtJustifyCenter);
  3425.   species  = make_label (form, "species" , "Species" , rank   , game    , (Dimension) 80 , XtJustifyCenter);
  3426.  
  3427.   white    = make_label (form, "white"   , "White"   , NULL   , name    , (Dimension) 66 , XtJustifyLeft);
  3428.   black    = make_label (form, "black"   , "Black"   , NULL   , white   , (Dimension) 66 , XtJustifyLeft);
  3429.  
  3430.   w_PW     = make_text  (form, "PW"      , white     , name   , 200);
  3431.   w_PB     = make_text  (form, "PB"      , black     , w_PW   , 200);
  3432.   w_WR     = make_text  (form, "WR"      , w_PW      , rank   , 80 );
  3433.   w_BR     = make_text  (form, "BR"      , w_PB      , w_WR   , 80 );
  3434.   w_WS     = make_text  (form, "WS"      , w_WR      , species, 80 );
  3435.   w_BS     = make_text  (form, "BS"      , w_BR      , w_WS   , 80 );
  3436.  
  3437.   event    = make_label (form, "event"   , "Event"   , NULL   , black   , (Dimension) 66 , XtJustifyLeft);
  3438.   place    = make_label (form, "place"   , "Place"   , NULL   , event   , (Dimension) 66 , XtJustifyLeft);
  3439.   date     = make_label (form, "date"    , "Date"    , NULL   , place   , (Dimension) 66 , XtJustifyLeft);
  3440.   round    = make_label (form, "round"   , "Round"   , NULL   , date    , (Dimension) 66 , XtJustifyLeft);
  3441.  
  3442.   w_EV     = make_text  (form, "EV"      , event     , black  , (Dimension) 200);
  3443.   w_PC     = make_text  (form, "PC"      , place     , w_EV   , (Dimension) 200);
  3444.   w_DT     = make_text  (form, "DT"      , date      , w_PC   , (Dimension) 200);
  3445.   w_RO     = make_text  (form, "RO"      , round     , w_DT   , (Dimension) 200);
  3446.  
  3447.   handicap = make_label (form, "handicap", "Handicap", w_EV   , black   , (Dimension) 66 , XtJustifyLeft);
  3448.   komi     = make_label (form, "komi"    , "Komi"    , w_PC   , handicap, (Dimension) 66 , XtJustifyLeft);
  3449.   time     = make_label (form, "time"    , "Time"    , w_DT   , komi    , (Dimension) 66 , XtJustifyLeft);
  3450.   result   = make_label (form, "result"  , "Result"  , w_RO   , time    , (Dimension) 66 , XtJustifyLeft);
  3451.  
  3452.   w_HA     = make_text  (form, "HA"      , handicap  , black  , (Dimension) 80);
  3453.   w_KM     = make_text  (form, "KM"      , komi      , w_HA   , (Dimension) 80);
  3454.   w_TM     = make_text  (form, "TM"      , time      , w_KM   , (Dimension) 80);
  3455.   w_RE     = make_text  (form, "RE"      , result    , w_TM   , (Dimension) 80);
  3456.  
  3457.   user     = make_label (form, "user"    , "User"    , NULL   , round   , (Dimension) 66 , XtJustifyLeft);
  3458.   source   = make_label (form, "komi"    , "Source"  , NULL   , user    , (Dimension) 66 , XtJustifyLeft);
  3459.  
  3460.   w_US     = make_text  (form, "US"      , user      , round  , (Dimension) 200);
  3461.   w_SO     = make_text  (form, "SO"      , source    , w_US   , (Dimension) 200);
  3462.   
  3463.   xtargc = 0;
  3464.   XtSetArg (args[xtargc], XtNlabel          , (XtArgVal) CancelLabel ); xtargc++;  
  3465.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) round       ); xtargc++;  
  3466.   XtSetArg (args[xtargc], XtNfromHoriz      , (XtArgVal) w_US        ); xtargc++;  
  3467.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 100         ); xtargc++;  
  3468.  
  3469. #ifndef NO_EXTENSION
  3470.   XtSetArg (args[xtargc], XtNshapeStyle     , (XtArgVal) XmuShapeOval); xtargc++;  
  3471. #endif
  3472.  
  3473.   cancel   = XtCreateManagedWidget ("cancel"   , commandWidgetClass  , form   , args, xtargc);
  3474.   
  3475.   xtargc = 0;
  3476.   XtSetArg (args[xtargc], XtNlabel          , (XtArgVal) ConfirmLabel); xtargc++;  
  3477.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) cancel      ); xtargc++;  
  3478.   XtSetArg (args[xtargc], XtNfromHoriz      , (XtArgVal) w_US        ); xtargc++;  
  3479.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 100         ); xtargc++;  
  3480.  
  3481. #ifndef NO_EXTENSION
  3482.   XtSetArg (args[xtargc], XtNshapeStyle     , (XtArgVal) XmuShapeOval); xtargc++;  
  3483. #endif
  3484.   
  3485.   confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass  , form   , args, xtargc);
  3486.   
  3487.   xtargc = 0;
  3488.   XtSetArg (args[xtargc], XtNtranslations   , (XtArgVal) translations); xtargc++;
  3489.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) source      ); xtargc++;  
  3490.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 444         ); xtargc++;  
  3491.   XtSetArg (args[xtargc], XtNheight         , (XtArgVal) 150         ); xtargc++;  
  3492.   XtSetArg (args[xtargc], XtNscrollVertical , (XtArgVal) XawtextScrollAlways); xtargc++;  
  3493.   XtSetArg (args[xtargc], XtNeditType       , (XtArgVal) XawtextEdit ); xtargc++;  
  3494.   XtSetArg (args[xtargc], XtNdisplayCaret   , (XtArgVal) False       ); xtargc++;
  3495.  
  3496.   w_GC = XtCreateManagedWidget ("GC" , asciiTextWidgetClass     , form     , args, xtargc);
  3497.  
  3498.   xtargc = 0;
  3499.   XtSetArg (args[xtargc], XtNvertDistance , (XtArgVal) 16); xtargc++;
  3500.  
  3501.   XtSetValues (event     , args, xtargc);
  3502.   XtSetValues (w_EV      , args, xtargc);
  3503.   XtSetValues (w_HA      , args, xtargc);
  3504.   XtSetValues (user      , args, xtargc);
  3505.   XtSetValues (w_US      , args, xtargc);
  3506.   XtSetValues (cancel    , args, xtargc);
  3507.   XtSetValues (w_GC      , args, xtargc);
  3508.   XtSetValues (handicap  , args, xtargc);
  3509.  
  3510.   xtargc = 0;
  3511.   XtSetArg (args[xtargc], XtNvertDistance , (XtArgVal) 8 ); xtargc++;
  3512.  
  3513.   XtSetValues (w_GN      , args, xtargc);
  3514.   XtSetValues (game      , args, xtargc);
  3515.  
  3516.   xtargc = 0;
  3517.   XtSetArg (args[xtargc], XtNhorizDistance, (XtArgVal) 18); xtargc++;
  3518.  
  3519.   XtSetValues (handicap  , args, xtargc);
  3520.   XtSetValues (komi      , args, xtargc);
  3521.   XtSetValues (time      , args, xtargc);
  3522.   XtSetValues (result    , args, xtargc);
  3523.  
  3524.   xtargc = 0;
  3525.   XtSetArg (args[xtargc], XtNhorizDistance, (XtArgVal) 37); xtargc++;
  3526.  
  3527.   XtSetValues (confirm   , args, xtargc);
  3528.   XtSetValues (cancel    , args, xtargc);
  3529.  
  3530.   XtAddCallback (confirm, XtNcallback, infoConfirm, NULL);
  3531.   XtAddCallback (cancel , XtNcallback, infoCancel , NULL);
  3532. }
  3533. SHAR_EOF
  3534. fi # end of overwriting check
  3535. if test -f 'dialog.c'
  3536. then
  3537.     echo shar: will not over-write existing file "'dialog.c'"
  3538. else
  3539. cat << \SHAR_EOF > 'dialog.c'
  3540. /****************************************************************************************************************
  3541.  *
  3542.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  3543.  *
  3544.  *  This program is distributed in the hope that it will be useful.
  3545.  *  Use and copying of this software and preparation of derivative works
  3546.  *  based upon this software are permitted, so long as the following
  3547.  *  conditions are met:
  3548.  *       o credit to the authors is acknowledged following current
  3549.  *         academic behaviour
  3550.  *       o no fees or compensation are charged for use, copies, or
  3551.  *         access to this software
  3552.  *       o this copyright notice is included intact.
  3553.  *  This software is made available AS IS, and no warranty is made about 
  3554.  *  the software or its performance. 
  3555.  * 
  3556.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  3557.  *  Send them to    dumesnil@etca.fr   or to:
  3558.  *       
  3559.  *       Antoine de Maricourt
  3560.  *       ETCA CREA-SP
  3561.  *       16 bis, avenue Prieur de la Cote d'Or
  3562.  *       94114 Arcueil Cedex
  3563.  *       France
  3564.  */
  3565.  
  3566. #include <stdio.h>
  3567. #include <ctype.h>
  3568.  
  3569. #include <X11/Intrinsic.h>
  3570. #include <X11/Shell.h>
  3571. #include <X11/StringDefs.h>
  3572.  
  3573. #include <X11/Xaw/Command.h>
  3574. #include <X11/Xaw/Form.h>
  3575. #include <X11/Xaw/Label.h>
  3576. #include <X11/Xaw/AsciiText.h>
  3577.  
  3578. #include "xgoban.h"
  3579.  
  3580. /*******************************************************************************************************
  3581.  */
  3582.  
  3583. static Widget   d_top;
  3584. static Widget   d_form;
  3585. static Widget   d_msg;
  3586. static Widget   d_text;
  3587. static Widget   d_confirm;
  3588. static Widget   d_cancel;
  3589.  
  3590. static Widget   a_top;
  3591. static Widget   a_form;
  3592. static Widget   a_msg;
  3593. static Widget   a_confirm;
  3594. static Widget   a_cancel;
  3595.  
  3596. static Widget   w_top;
  3597. static Widget   w_form;
  3598. static Widget   w_msg;
  3599. static Widget   w_confirm;
  3600.  
  3601. static Widget   h_top;
  3602. static Widget   h_text;
  3603.  
  3604. static int      dialog_mode  = -1;
  3605. static Widget   dialog_widget;
  3606.  
  3607. static XEvent   delay_event;
  3608.  
  3609. /*******************************************************************************************************
  3610.  */
  3611.  
  3612. /* ARGSUSED */
  3613.  
  3614. void PopupDialog (w, event, mode)
  3615. Widget   w;
  3616. XEvent  *event;
  3617. int      mode;
  3618. {
  3619.   SG_PropertyPtr property;
  3620.   Widget         top;
  3621.   Widget         focus;
  3622.   Arg            arg;
  3623.  
  3624.   switch (mode) {
  3625.  
  3626.   case HelpDialog : 
  3627.     top   = h_top; 
  3628.     focus = NULL; 
  3629.     break;
  3630.  
  3631.   case ReallyQuitDialog :
  3632.     XtSetArg (arg, XtNlabel, (XtArgVal) ReallyQuitMsg); XtSetValues (a_msg     , &arg, 1);
  3633.     XtSetArg (arg, XtNlabel, (XtArgVal) QuitLabel    ); XtSetValues (a_confirm , &arg, 1);
  3634.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel  ); XtSetValues (a_cancel  , &arg, 1);
  3635.  
  3636.     top   = a_top;
  3637.     focus = a_confirm;
  3638.     break;
  3639.   
  3640.   case ReallyDeleteDialog :
  3641.  
  3642.     delay_event = *event;
  3643.     
  3644.     XtSetArg (arg, XtNlabel, (XtArgVal) ReallyDeleteMsg); XtSetValues (a_msg     , &arg, 1);
  3645.     XtSetArg (arg, XtNlabel, (XtArgVal) DeleteLabel    ); XtSetValues (a_confirm , &arg, 1);
  3646.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel    ); XtSetValues (a_cancel  , &arg, 1);
  3647.  
  3648.     top   = a_top;
  3649.     focus = a_confirm;
  3650.     break;
  3651.    
  3652.   case SaveBeforeQuitDialog :
  3653.   case SaveBeforeLoadDialog :
  3654.     XtSetArg (arg, XtNlabel, (XtArgVal) SaveFileBeforeMsg); XtSetValues (a_msg     , &arg, 1);
  3655.     XtSetArg (arg, XtNlabel, (XtArgVal) YesLabel         ); XtSetValues (a_confirm , &arg, 1);
  3656.     XtSetArg (arg, XtNlabel, (XtArgVal) NoLabel          ); XtSetValues (a_cancel  , &arg, 1);
  3657.  
  3658.     top   = a_top;
  3659.     focus = a_confirm;
  3660.     break;
  3661.    
  3662.   case SaveAsAndLoadDialog :
  3663.   case SaveAsAndQuitDialog :
  3664.   case SaveAsDialog        :
  3665.     XtSetArg (arg, XtNstring , (XtArgVal) file_name   ); XtSetValues (d_text    , &arg, 1);
  3666.     XtSetArg (arg, XtNlabel  , (XtArgVal) SaveFileMsg ); XtSetValues (d_msg     , &arg, 1);
  3667.     XtSetArg (arg, XtNlabel  , (XtArgVal) SaveLabel   ); XtSetValues (d_confirm , &arg, 1);
  3668.     XtSetArg (arg, XtNlabel  , (XtArgVal) CancelLabel ); XtSetValues (d_cancel  , &arg, 1);
  3669.  
  3670.     top   = d_top;
  3671.     focus = d_text;
  3672.     break;
  3673.  
  3674.   case NodeNameDialog      :
  3675.     property = SG_GetProperty (current_node, SG_nodeName);
  3676.     
  3677.     if (property != NULL && property->data.pvalue != NULL)
  3678.       { XtSetArg (arg, XtNstring , (XtArgVal) property->data.pvalue); XtSetValues (d_text    , &arg, 1); }
  3679.     else
  3680.       { XtSetArg (arg, XtNstring , (XtArgVal) ""                   ); XtSetValues (d_text    , &arg, 1); }
  3681.  
  3682.     XtSetArg (arg, XtNlabel  , (XtArgVal) NodeNameMsg ); XtSetValues (d_msg     , &arg, 1);
  3683.     XtSetArg (arg, XtNlabel  , (XtArgVal) OkLabel     ); XtSetValues (d_confirm , &arg, 1);
  3684.     XtSetArg (arg, XtNlabel  , (XtArgVal) CancelLabel ); XtSetValues (d_cancel  , &arg, 1);
  3685.  
  3686.     top   = d_top;
  3687.     focus = d_text;
  3688.     break;
  3689.  
  3690.   case LoadDialog :
  3691.     XtSetArg (arg, XtNstring , (XtArgVal) ""          ); XtSetValues (d_text    , &arg, 1);
  3692.     XtSetArg (arg, XtNlabel  , (XtArgVal) LoadFileMsg ); XtSetValues (d_msg     , &arg, 1);
  3693.     XtSetArg (arg, XtNlabel  , (XtArgVal) LoadLabel   ); XtSetValues (d_confirm , &arg, 1);
  3694.     XtSetArg (arg, XtNlabel  , (XtArgVal) CancelLabel ); XtSetValues (d_cancel  , &arg, 1);
  3695.  
  3696.     top   = d_top;
  3697.     focus = d_text;
  3698.     break;
  3699.  
  3700.   case EditDialog :
  3701.     if (edit == True) return;
  3702.  
  3703.     delay_event = *event;
  3704.     
  3705.     XtSetArg (arg, XtNlabel, (XtArgVal) EditFileMsg); XtSetValues (a_msg     , &arg, 1);
  3706.     XtSetArg (arg, XtNlabel, (XtArgVal) EditLabel  ); XtSetValues (a_confirm , &arg, 1);
  3707.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel); XtSetValues (a_cancel  , &arg, 1);
  3708.  
  3709.     top   = a_top;
  3710.     focus = a_confirm;
  3711.     break;
  3712.  
  3713.   case StopGameDialog :
  3714.     delay_event = *event;
  3715.  
  3716.   case StopGameBeforeQuitDialog :
  3717.     
  3718.     XtSetArg (arg, XtNlabel, (XtArgVal) StopGameMsg); XtSetValues (a_msg     , &arg, 1);
  3719.     XtSetArg (arg, XtNlabel, (XtArgVal) StopLabel  ); XtSetValues (a_confirm , &arg, 1);
  3720.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel); XtSetValues (a_cancel  , &arg, 1);
  3721.  
  3722.     top   = a_top;
  3723.     focus = a_confirm;
  3724.     break;
  3725.  
  3726.   case ReplaceNodeDialog :
  3727.     delay_event = *event;
  3728.  
  3729.     XtSetArg (arg, XtNlabel, (XtArgVal) ReplaceNodeMsg); XtSetValues (a_msg     , &arg, 1);
  3730.     XtSetArg (arg, XtNlabel, (XtArgVal) ReplaceLabel  ); XtSetValues (a_confirm , &arg, 1);
  3731.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel   ); XtSetValues (a_cancel  , &arg, 1);
  3732.  
  3733.     top   = a_top;
  3734.     focus = a_confirm;
  3735.     break;
  3736.  
  3737.   case MailConfirmMoveDialog :
  3738.     delay_event = *event;
  3739.  
  3740.     XtSetArg (arg, XtNlabel, (XtArgVal) MailConfirmMoveMsg); XtSetValues (a_msg     , &arg, 1);
  3741.     XtSetArg (arg, XtNlabel, (XtArgVal) ConfirmLabel      ); XtSetValues (a_confirm , &arg, 1);
  3742.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel       ); XtSetValues (a_cancel  , &arg, 1);
  3743.  
  3744.     top   = a_top;
  3745.     focus = a_confirm;
  3746.     break;
  3747.  
  3748.   case MailNoMoveDialog :
  3749.     delay_event = *event;
  3750.  
  3751.     XtSetArg (arg, XtNlabel, (XtArgVal) MailNoMoveMsg); XtSetValues (a_msg     , &arg, 1);
  3752.     XtSetArg (arg, XtNlabel, (XtArgVal) QuitLabel    ); XtSetValues (a_confirm , &arg, 1);
  3753.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel  ); XtSetValues (a_cancel  , &arg, 1);
  3754.  
  3755.     top   = a_top;
  3756.     focus = a_confirm;
  3757.     break;
  3758.  
  3759.   case RemoveStonesDialog :
  3760.     delay_event = *event;
  3761.  
  3762.     XtSetArg (arg, XtNlabel, (XtArgVal) RemoveStonesMsg); XtSetValues (a_msg     , &arg, 1);
  3763.     XtSetArg (arg, XtNlabel, (XtArgVal) RemoveLabel    ); XtSetValues (a_confirm , &arg, 1);
  3764.     XtSetArg (arg, XtNlabel, (XtArgVal) CancelLabel    ); XtSetValues (a_cancel  , &arg, 1);
  3765.  
  3766.     top   = a_top;
  3767.     focus = a_confirm;
  3768.     break;
  3769.  
  3770.   default :
  3771.     switch (mode) {
  3772.     case PlayerNodeErrorWarning  : XtSetArg (arg, XtNlabel, PlayerNodeErrorMsg ); XtSetValues (w_msg, &arg, 1); break;
  3773.     case PlayerMoveErrorWarning  : XtSetArg (arg, XtNlabel, PlayerMoveErrorMsg ); XtSetValues (w_msg, &arg, 1); break;
  3774.     case MemoryErrorDialog       : XtSetArg (arg, XtNlabel, MemoryErrorMsg     ); XtSetValues (w_msg, &arg, 1); break;
  3775.     case CantOpenFileDialog      : XtSetArg (arg, XtNlabel, CantOpenFileMsg    ); XtSetValues (w_msg, &arg, 1); break;
  3776.     case IllegalMoveDialog       : XtSetArg (arg, XtNlabel, IllegalMoveMsg     ); XtSetValues (w_msg, &arg, 1); break;
  3777.     case SuicideMoveDialog       : XtSetArg (arg, XtNlabel, SuicideMoveMsg     ); XtSetValues (w_msg, &arg, 1); break;
  3778.     case KoMoveDialog            : XtSetArg (arg, XtNlabel, KoMoveMsg          ); XtSetValues (w_msg, &arg, 1); break;
  3779.     case BadHandicapWarning      : XtSetArg (arg, XtNlabel, BadHandicapMsg     ); XtSetValues (w_msg, &arg, 1); break;
  3780.     case RemainingStonesWarning  : XtSetArg (arg, XtNlabel, RemainingStonesMsg ); XtSetValues (w_msg, &arg, 1); break;
  3781.     case DiagramBadNodeWarning   : XtSetArg (arg, XtNlabel, DiagramBadNodeMsg  ); XtSetValues (w_msg, &arg, 1); break;
  3782.     case SizeBadNodeWarning      : XtSetArg (arg, XtNlabel, SizeBadNodeMsg     ); XtSetValues (w_msg, &arg, 1); break;
  3783.     case WallyWhitePlayWarning   : XtSetArg (arg, XtNlabel, WallyWhitePlayMsg  ); XtSetValues (w_msg, &arg, 1); break;
  3784.     case WallyBadSizeWarning     : XtSetArg (arg, XtNlabel, WallyBadSizeMsg    ); XtSetValues (w_msg, &arg, 1); break;
  3785.     case WallyBadHandicapWarning : XtSetArg (arg, XtNlabel, WallyBadHandicapMsg); XtSetValues (w_msg, &arg, 1); break;
  3786.     case BlackPassDialog         : XtSetArg (arg, XtNlabel, BlackPassMsg       ); XtSetValues (w_msg, &arg, 1); break;
  3787.     case WhitePassDialog         : XtSetArg (arg, XtNlabel, WhitePassMsg       ); XtSetValues (w_msg, &arg, 1); break;
  3788.     }
  3789.  
  3790.     top   = w_top;
  3791.     focus = w_confirm;
  3792.     break;
  3793.   }
  3794.  
  3795.   dialog_mode   = mode;
  3796.   dialog_widget = top;
  3797.  
  3798.   CenterWindow  (top, focus);
  3799.   XtPopup       (top, XtGrabNonexclusive);
  3800. }
  3801.  
  3802. /*******************************************************************************************************
  3803.  */
  3804.  
  3805. static void dialogConfirm  (w, event)
  3806. Widget    w;
  3807. XEvent   *event;
  3808. {
  3809.   SG_NodePtr     node;
  3810.   String         name;
  3811.   Arg            arg;
  3812.  
  3813.   XtPopdown (dialog_widget);
  3814.  
  3815.   switch (dialog_mode) {
  3816.  
  3817.   case ReallyDeleteDialog :
  3818.     delete_confirm = True;
  3819.     XPutBackEvent (XtDisplay (w), &delay_event);
  3820.     break;
  3821.  
  3822.   case ReallyQuitDialog :
  3823.     exit (1);
  3824.     break;
  3825.  
  3826.   case SaveBeforeQuitDialog :
  3827.     if (file_name[0] != '\0') {
  3828.       if (SaveFile (w, event, file_name) == True)
  3829.     (void) exit (1);
  3830.     }
  3831.  
  3832.     else 
  3833.       PopupDialog (w, event, SaveAsAndQuitDialog);
  3834.     break;
  3835.  
  3836.   case SaveBeforeLoadDialog :
  3837.     if (file_name[0] != '\0') {
  3838.       if (SaveFile (w, event, file_name) == True)
  3839.     PopupDialog (w, event, LoadDialog);
  3840.     }
  3841.  
  3842.     else 
  3843.       PopupDialog (w, event, SaveAsAndLoadDialog);
  3844.     break;
  3845.  
  3846.   case NodeNameDialog      :
  3847.     XtSetArg (arg, XtNstring, (XtArgVal) &name); 
  3848.     XtGetValues (d_text, &arg, 1);
  3849.  
  3850.     SG_MakeProperty (current_node, SG_nodeName, name);
  3851.     ShowTmpProperty (current_node);
  3852.  
  3853.     modified = True;
  3854.     break;
  3855.  
  3856.   case SaveAsAndQuitDialog :
  3857.   case SaveAsAndLoadDialog :
  3858.   case SaveAsDialog        :
  3859.     
  3860.     XtSetArg (arg, XtNstring, (XtArgVal) &name); XtGetValues (d_text, &arg, 1);
  3861.     
  3862.     if (SaveFile (w, event, name) == True)
  3863.       switch (dialog_mode) {
  3864.       case SaveAsAndQuitDialog : exit (1);
  3865.       case SaveAsAndLoadDialog : PopupDialog (w, event, LoadDialog);
  3866.       }
  3867.     break;
  3868.     
  3869.   case LoadDialog :
  3870.     XtSetArg (arg, XtNstring , (XtArgVal) &name); XtGetValues (d_text, &arg, 1);
  3871.  
  3872.     if (LoadFile (w, event, name) == True) {
  3873.       XtSetArg (arg, XtNtitle , (XtArgVal) ApplicationName); XtSetValues (w_toplevel, &arg, 1);
  3874.       XtSetArg (arg, XtNstring, (XtArgVal) ""             ); XtSetValues (c_comment , &arg, 1);
  3875.       XtSetArg (arg, XtNstring, (XtArgVal) ""             ); XtSetValues (d_text    , &arg, 1); 
  3876.  
  3877.       GbClearBoard  (w_goban);
  3878.  
  3879.       Play           (current_node);
  3880.       ShowProperty   (current_node);
  3881.       RedisplayBoard ();
  3882.  
  3883.       Edit (False);
  3884.     }
  3885.     break;
  3886.     
  3887.   case EditDialog :
  3888.     Edit (True);
  3889.  
  3890.     XPutBackEvent (XtDisplay (w), &delay_event);
  3891.     break;
  3892.     
  3893.   case StopGameDialog :
  3894.     stopGame ();
  3895.  
  3896.     XPutBackEvent (XtDisplay (w), &delay_event);
  3897.     break;
  3898.  
  3899.   case StopGameBeforeQuitDialog :
  3900.     stopGame ();
  3901.     (void) exit (1);
  3902.  
  3903.     /* NOTREACHED */
  3904.  
  3905.   case RemoveStonesDialog :
  3906.   case ReplaceNodeDialog :
  3907.     node = current_node->down;
  3908.     
  3909.     SG_RemoveNode (node);
  3910.     SG_FreeNode   (node);
  3911.     
  3912.     modified = True;
  3913.     
  3914.     XPutBackEvent (XtDisplay (w), &delay_event);
  3915.     break;
  3916.     
  3917.   case MailNoMoveDialog :
  3918.     (void) exit (1); 
  3919.  
  3920.     /* NOTREACHED */
  3921.  
  3922.   case MailConfirmMoveDialog :
  3923.     if (SaveFile (w, event, mail_file_name) == True)
  3924.       (void) exit (0);
  3925.     else
  3926.       (void) exit (1);
  3927.     
  3928.     /* NOTREACHED */
  3929.   }
  3930. }
  3931.  
  3932. /*******************************************************************************************************
  3933.  */
  3934.  
  3935. static void dialogCancel  (w, event) 
  3936. Widget    w;
  3937. XEvent   *event;
  3938.   XtPopdown (dialog_widget);
  3939.  
  3940.   switch (dialog_mode) {
  3941.   case SaveBeforeQuitDialog : PopupDialog (w, event, ReallyQuitDialog); break;
  3942.   case SaveBeforeLoadDialog : PopupDialog (w, event, LoadDialog      ); break;
  3943.   }
  3944. }
  3945.  
  3946. /*******************************************************************************************************
  3947.  */
  3948.  
  3949. void makeDialogWindow (toplevel, app_context)
  3950. Widget        toplevel;
  3951. XtAppContext  app_context;
  3952. {
  3953.   static XtActionsRec   actions[] = {
  3954.     { "dialogConfirm"   , dialogConfirm  , },
  3955.     { "dialogCancel"    , dialogCancel   , },
  3956.   }; 
  3957.   
  3958.   Arg            args[10];
  3959.   int            xtargc;
  3960.   XtTranslations translations;
  3961.   
  3962.   XtAppAddActions (app_context, actions, XtNumber(actions));
  3963.   
  3964.   /*
  3965.    *    Dialog Window.
  3966.    */
  3967.   
  3968.   translations = XtParseTranslationTable 
  3969.     ("#override                        \
  3970.       <Key> Escape   : dialogCancel()  \n\
  3971.       <Key> Linefeed : dialogConfirm() \n\
  3972.       <Key> Return   : dialogConfirm() \n\
  3973.       Ctrl <Key> J   : dialogConfirm() \n\
  3974.       Ctrl <Key> M   : dialogConfirm()");
  3975.   
  3976.   d_top      = XtCreatePopupShell ("dialog"     , transientShellWidgetClass, toplevel , NULL, 0);
  3977.   
  3978.   xtargc = 0;
  3979.   XtSetArg (args[xtargc], XtNdefaultDistance  , (XtArgVal) 12          ); xtargc++;
  3980.   XtSetArg (args[xtargc], XtNtranslations     , (XtArgVal) translations); xtargc++;
  3981.  
  3982.   d_form     = XtCreateManagedWidget ("form"     , formWidgetClass     , d_top   , args, xtargc);
  3983.  
  3984.   xtargc = 0;
  3985.   XtSetArg (args[xtargc], XtNwidth            , (XtArgVal) 294         ); xtargc++;  
  3986.   XtSetArg (args[xtargc], XtNborderWidth      , (XtArgVal) 0           ); xtargc++;  
  3987.  
  3988.   d_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass    , d_form   , args, xtargc);
  3989.   
  3990.   xtargc = 0;
  3991.   XtSetArg (args[xtargc], XtNfromVert         , (XtArgVal) d_msg       ); xtargc++;  
  3992.   XtSetArg (args[xtargc], XtNwidth            , (XtArgVal) 294         ); xtargc++;  
  3993.   XtSetArg (args[xtargc], XtNvertDistance     , (XtArgVal) 8           ); xtargc++;  
  3994.   XtSetArg (args[xtargc], XtNeditType         , (XtArgVal) XawtextEdit ); xtargc++;  
  3995.   XtSetArg (args[xtargc], XtNtranslations     , (XtArgVal) translations); xtargc++;  
  3996.  
  3997.   d_text     = XtCreateManagedWidget ("text"     , asciiTextWidgetClass, d_form   , args, xtargc);
  3998.   
  3999.   xtargc = 0;
  4000.   XtSetArg (args[xtargc], XtNfromVert         , (XtArgVal) d_text      ); xtargc++;  
  4001.   XtSetArg (args[xtargc], XtNwidth            , (XtArgVal) 140         ); xtargc++;  
  4002.  
  4003. #ifndef NO_EXTENSION
  4004.   XtSetArg (args[xtargc], XtNshapeStyle       , (XtArgVal) XmuShapeOval); xtargc++;  
  4005. #endif
  4006.  
  4007.   d_cancel   = XtCreateManagedWidget ("cancel"   , commandWidgetClass  , d_form   , args, xtargc);
  4008.   
  4009.   xtargc = 0;
  4010.   XtSetArg (args[xtargc], XtNfromVert         , (XtArgVal) d_text      ); xtargc++;  
  4011.   XtSetArg (args[xtargc], XtNfromHoriz        , (XtArgVal) d_cancel    ); xtargc++;  
  4012.   XtSetArg (args[xtargc], XtNwidth            , (XtArgVal) 140         ); xtargc++;  
  4013.  
  4014. #ifndef NO_EXTENSION
  4015.   XtSetArg (args[xtargc], XtNshapeStyle       , (XtArgVal) XmuShapeOval); xtargc++;  
  4016. #endif
  4017.   
  4018.   d_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass  , d_form   , args, xtargc);
  4019.   
  4020.   XtAddCallback (d_cancel , XtNcallback, dialogCancel , NULL);
  4021.   XtAddCallback (d_confirm, XtNcallback, dialogConfirm, NULL);
  4022.  
  4023.   XtRealizeWidget (d_top);
  4024.  
  4025.   /*
  4026.    *    Ask Window.
  4027.    */
  4028.    
  4029.   a_top      = XtCreatePopupShell ("ask", transientShellWidgetClass, toplevel, NULL, 0);
  4030.   
  4031.   xtargc = 0;
  4032.   XtSetArg (args[xtargc], XtNdefaultDistance, (XtArgVal) 12          ); xtargc++;  
  4033.   XtSetArg (args[xtargc], XtNtranslations   , (XtArgVal) translations); xtargc++;  
  4034.   
  4035.   a_form     = XtCreateManagedWidget ("form"     , formWidgetClass     , a_top    , args, xtargc);
  4036.   
  4037.   xtargc = 0;
  4038.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 214         ); xtargc++;  
  4039.   XtSetArg (args[xtargc], XtNheight         , (XtArgVal) 30          ); xtargc++;  
  4040.   XtSetArg (args[xtargc], XtNborderWidth    , (XtArgVal) 0           ); xtargc++;  
  4041.   
  4042.   a_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass    , a_form   , args, xtargc);
  4043.   
  4044.   xtargc = 0;
  4045.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) a_msg       ); xtargc++;  
  4046.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 100         ); xtargc++;  
  4047.  
  4048. #ifndef NO_EXTENSION
  4049.   XtSetArg (args[xtargc], XtNshapeStyle     , (XtArgVal) XmuShapeOval); xtargc++;  
  4050. #endif
  4051.  
  4052.   a_cancel   = XtCreateManagedWidget ("cancel"   , commandWidgetClass  , a_form   , args, xtargc);
  4053.   
  4054.   xtargc = 0;
  4055.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) a_msg       ); xtargc++;  
  4056.   XtSetArg (args[xtargc], XtNfromHoriz      , (XtArgVal) a_cancel    ); xtargc++;  
  4057.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 100         ); xtargc++;  
  4058.  
  4059. #ifndef NO_EXTENSION
  4060.   XtSetArg (args[xtargc], XtNshapeStyle     , (XtArgVal) XmuShapeOval); xtargc++;  
  4061. #endif
  4062.   
  4063.   a_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass  , a_form   , args, xtargc);
  4064.   
  4065.   XtAddCallback (a_cancel , XtNcallback, dialogCancel , NULL);
  4066.   XtAddCallback (a_confirm, XtNcallback, dialogConfirm, NULL);
  4067.   
  4068.   XtRealizeWidget (a_top);
  4069.  
  4070.   /*
  4071.    *    Warning Window.
  4072.    */
  4073.   
  4074.   translations = XtParseTranslationTable 
  4075.     ("#override                    \
  4076.       <BtnDown>  : dialogCancel()  \n\
  4077.       <Key>      : dialogCancel()");
  4078.   
  4079.   w_top     = XtCreatePopupShell ("warning", transientShellWidgetClass, toplevel, NULL, 0);
  4080.    
  4081.   xtargc = 0;
  4082.   XtSetArg (args[xtargc], XtNdefaultDistance, (XtArgVal) 12          ); xtargc++;  
  4083.   XtSetArg (args[xtargc], XtNtranslations   , (XtArgVal) translations); xtargc++;  
  4084.  
  4085.   w_form     = XtCreateManagedWidget ("form"     , formWidgetClass     , w_top    , args, xtargc);
  4086.   
  4087.   xtargc = 0;
  4088.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 206         ); xtargc++;  
  4089.   XtSetArg (args[xtargc], XtNheight         , (XtArgVal) 48          ); xtargc++;  
  4090.   XtSetArg (args[xtargc], XtNborderWidth    , (XtArgVal) 0           ); xtargc++;  
  4091.   
  4092.   w_msg      = XtCreateManagedWidget ("msg"      , labelWidgetClass    , w_form   , args, xtargc);
  4093.   
  4094.   xtargc = 0;
  4095.   XtSetArg (args[xtargc], XtNfromVert       , (XtArgVal) w_msg       ); xtargc++;  
  4096.   XtSetArg (args[xtargc], XtNwidth          , (XtArgVal) 100         ); xtargc++;  
  4097.   XtSetArg (args[xtargc], XtNhorizDistance  , (XtArgVal) 65          ); xtargc++;  
  4098.   XtSetArg (args[xtargc], XtNlabel          , (XtArgVal) OkLabel     ); xtargc++;  
  4099.  
  4100. #ifndef NO_EXTENSION
  4101.   XtSetArg (args[xtargc], XtNshapeStyle     , (XtArgVal) XmuShapeOval); xtargc++;  
  4102. #endif
  4103.  
  4104.   w_confirm  = XtCreateManagedWidget ("confirm"  , commandWidgetClass  , w_form   , args, xtargc);
  4105.   
  4106.   XtAddCallback (w_confirm, XtNcallback, dialogCancel, NULL);
  4107.  
  4108.   XtRealizeWidget (w_top);
  4109.   
  4110.   /*
  4111.    *  Help window
  4112.    */
  4113.  
  4114.   h_top  = XtCreatePopupShell ("help", transientShellWidgetClass, w_toplevel, NULL, 0); 
  4115.   
  4116.   xtargc = 0;
  4117.   XtSetArg (args[xtargc], XtNlabel        , (XtArgVal) HelpString  ); xtargc++;  
  4118.   XtSetArg (args[xtargc], XtNtranslations , (XtArgVal) translations); xtargc++;  
  4119.  
  4120.   h_text     = XtCreateManagedWidget ("text"     , labelWidgetClass    ,  h_top   , args, xtargc);
  4121.  
  4122.   XtRealizeWidget (h_top);
  4123. }
  4124. SHAR_EOF
  4125. fi # end of overwriting check
  4126. if test -f 'xgoban.c'
  4127. then
  4128.     echo shar: will not over-write existing file "'xgoban.c'"
  4129. else
  4130. cat << \SHAR_EOF > 'xgoban.c'
  4131. /****************************************************************************************************************
  4132.  *
  4133.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  4134.  *
  4135.  *  This program is distributed in the hope that it will be useful.
  4136.  *  Use and copying of this software and preparation of derivative works
  4137.  *  based upon this software are permitted, so long as the following
  4138.  *  conditions are met:
  4139.  *       o credit to the authors is acknowledged following current
  4140.  *         academic behaviour
  4141.  *       o no fees or compensation are charged for use, copies, or
  4142.  *         access to this software
  4143.  *       o this copyright notice is included intact.
  4144.  *  This software is made available AS IS, and no warranty is made about 
  4145.  *  the software or its performance. 
  4146.  * 
  4147.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4148.  *  Send them to    dumesnil@etca.fr   or to:
  4149.  *       
  4150.  *       Antoine de Maricourt
  4151.  *       ETCA CREA-SP
  4152.  *       16 bis, avenue Prieur de la Cote d'Or
  4153.  *       94114 Arcueil Cedex
  4154.  *       France
  4155.  */
  4156.  
  4157. #include <stdio.h>
  4158. #include <malloc.h>
  4159. #include <ctype.h>
  4160.  
  4161. #include <X11/Intrinsic.h>
  4162. #include <X11/Shell.h>
  4163. #include <X11/StringDefs.h>
  4164.  
  4165. #include <X11/Xaw/Form.h>
  4166. #include <X11/Xaw/AsciiText.h>
  4167. #include <X11/Xaw/SimpleMenu.h>
  4168. #include <X11/Xaw/SmeBSB.h>
  4169.  
  4170. #include "xgoban.h"
  4171. #include "icon.bm"
  4172.  
  4173. Widget      w_toplevel;
  4174. Widget      w_form;
  4175. Widget      w_goban;
  4176. Widget      w_menu            = NULL;
  4177. Widget      c_toplevel;
  4178. Widget      c_comment;
  4179. Widget      w_second_toplevel = NULL;
  4180. Widget      w_second_goban    = NULL;
  4181.  
  4182. SG_NodePtr  tree          = NULL;
  4183. SG_NodePtr  current_node  = NULL;
  4184. SG_NodePtr  mail_node     = NULL;
  4185.  
  4186. Mode        current_mode  = EditMode;
  4187.  
  4188. Player      black_player  = Human;
  4189. Player      white_player  = Human;
  4190. int         handicap      = 0;
  4191. int         board_size    = 19;
  4192. int         second_player = 0;
  4193.  
  4194. Boolean     edit          = False;
  4195. Boolean     modified      = False;
  4196. Boolean     autonum;
  4197. Boolean     strict;
  4198. Boolean     short_print   = False;
  4199. int         beep;
  4200.  
  4201. String      file = NULL;
  4202.  
  4203. char        file_name[512];
  4204. char        mail_file_name[512];
  4205. char       *path;
  4206.  
  4207. /*******************************************************************************************************
  4208.  */
  4209.  
  4210. typedef struct {
  4211.   int        handicap;
  4212.   int        size;
  4213.   int        stipple;
  4214.   String     path;
  4215.   String     mail;
  4216.   int        beep;
  4217.   Boolean    help;
  4218.   Boolean    autonum;
  4219.   Boolean    strict;
  4220.   Boolean    short_print;
  4221.   String     black;
  4222.   String     white;
  4223.   Dimension  point_size;
  4224.   String     white_dsp;
  4225.   String     black_dsp;
  4226. } AppData, *AppDataPtr;
  4227.  
  4228. static XtResource resources[] = {
  4229.   { "blackDisplay", XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, black_dsp)  , XtRString    , (caddr_t) NULL , },
  4230.   { "whiteDisplay", XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, white_dsp)  , XtRString    , (caddr_t) NULL , },
  4231.   { "path"        , XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, path)       , XtRString    , (caddr_t) "."  , },
  4232.   { "handicap"    , "Handicap"  , XtRInt      , sizeof (int)      , XtOffset (AppDataPtr, handicap)   , XtRImmediate , (caddr_t) 0    , },
  4233.   { "size"        , "Size"      , XtRInt      , sizeof (int)      , XtOffset (AppDataPtr, size)       , XtRImmediate , (caddr_t) 19   , },
  4234.   { "stipple"     , "Stipple"   , XtRInt      , sizeof (int)      , XtOffset (AppDataPtr, stipple)    , XtRImmediate , (caddr_t) 0    , },
  4235.   { "beep"        , "Beep"      , XtRInt      , sizeof (int)      , XtOffset (AppDataPtr, beep)       , XtRImmediate , (caddr_t) 0    , },
  4236.   { "short"       , XtCBoolean  , XtRBoolean  , sizeof (Boolean)  , XtOffset (AppDataPtr, short_print), XtRImmediate , (caddr_t) False, },
  4237.   { "mail"        , XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, mail)       , XtRString    , (caddr_t) NULL , },
  4238.   { "autonum"     , XtCBoolean  , XtRBoolean  , sizeof (Boolean)  , XtOffset (AppDataPtr, autonum)    , XtRImmediate , (caddr_t) True , },
  4239.   { "versatile"   , XtCBoolean  , XtRBoolean  , sizeof (Boolean)  , XtOffset (AppDataPtr, strict)     , XtRImmediate , (caddr_t) True , },
  4240.   { "black"       , XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, black)      , XtRImmediate , (caddr_t) NULL , },
  4241.   { "white"       , XtCString   , XtRString   , sizeof (String)   , XtOffset (AppDataPtr, white)      , XtRImmediate , (caddr_t) NULL , },
  4242.   { "help"        , XtCBoolean  , XtRBoolean  , sizeof (Boolean)  , XtOffset (AppDataPtr, help)       , XtRImmediate , (caddr_t) False, },
  4243.   { "pointSize"   , "Size"      , XtRDimension, sizeof (Dimension), XtOffset (AppDataPtr, point_size) , XtRImmediate , (caddr_t) 26   , },
  4244. };
  4245.  
  4246. static XrmOptionDescRec options[] = {
  4247.   { "-help"           , ".help"           , XrmoptionNoArg  , "True"  , },
  4248.   { "-size"           , ".size"           , XrmoptionSepArg , NULL    , },
  4249.   { "-handicap"       , ".handicap"       , XrmoptionSepArg , NULL    , },
  4250.   { "-path"           , ".path"           , XrmoptionSepArg , NULL    , },
  4251.   { "-pointSize"      , ".pointSize"      , XrmoptionSepArg , NULL    , },
  4252.   { "-silent"         , ".beep"           , XrmoptionNoArg  , "-101"  , },
  4253.   { "-beep"           , ".beep"           , XrmoptionSepArg , NULL    , },
  4254.   { "-nonum"          , ".autonum"        , XrmoptionNoArg  , "False" , },
  4255.   { "-versatile"      , ".versatile"      , XrmoptionNoArg  , "False" , },
  4256.   { "-black"          , ".black"          , XrmoptionSepArg , NULL    , },
  4257.   { "-white"          , ".white"          , XrmoptionSepArg , NULL    , },
  4258.   { "-stipple1"       , ".stipple"        , XrmoptionNoArg  , "1"     , },
  4259.   { "-stipple2"       , ".stipple"        , XrmoptionNoArg  , "2"     , },
  4260.   { "-stipple3"       , ".stipple"        , XrmoptionNoArg  , "3"     , },
  4261.  
  4262.  
  4263.   { "-m"              , ".mail"           , XrmoptionSepArg , NULL    , },
  4264.   { "-s"              , ".short"          , XrmoptionNoArg  , "True"  , },
  4265.   { "-mail"           , ".mail"           , XrmoptionSepArg , NULL    , },
  4266.   { "-short"          , ".short"          , XrmoptionNoArg  , "True"  , },
  4267.   { "-blackDisplay"   , ".blackDisplay"   , XrmoptionSepArg , NULL    , },
  4268.   { "-whiteDisplay"   , ".whiteDisplay"   , XrmoptionSepArg , NULL    , },
  4269. };
  4270.  
  4271. static AppData  app_data;
  4272.  
  4273. static char *stars[18] = {
  4274.   "",                /*  2  */  
  4275.   "",                /*  3  */  
  4276.   "",                /*  4  */  
  4277.   "",                /*  5  */  
  4278.   "",                /*  6  */  
  4279.   "",                /*  7  */  
  4280.   "cffcffcc",            /*  8  */    
  4281.   "cggcggccee",            /*  9  */  
  4282.   "hchhchcc",            /* 10  */  
  4283.   "ciiciiccffcfiffcfi",        /* 11  */  
  4284.   "cjjcjjcc",            /* 12  */  
  4285.   "ckkckkccggcgkggcgk",        /* 13  */  
  4286.   "dkkdkkdd",            /* 14  */  
  4287.   "dlldllddhhdhlhhdhl",        /* 15  */  
  4288.   "dmmdmmdd",            /* 16  */  
  4289.   "dnndnnddiidiniidin",        /* 17  */  
  4290.   "doodoodd",            /* 18  */  
  4291.   "dppdppddjjdjpjjdjp",        /* 19  */  
  4292. };
  4293.  
  4294. char translations_table[] =
  4295.   "#override                                                                            \
  4296.    Ctrl Shift <Key> P        : makeVariationPass()                                    \n\
  4297.    Shift <Key> A             : selectVariation(A)                                     \n\
  4298.    Shift <Key> B             : selectVariation(B)                                     \n\
  4299.    Shift <Key> C             : selectVariation(C)                                     \n\
  4300.    Shift <Key> D             : selectVariation(D)                                     \n\
  4301.    Shift <Key> E             : selectVariation(E)                                     \n\
  4302.    Shift <Key> F             : selectVariation(F)                                     \n\
  4303.    Shift <Key> G             : selectVariation(G)                                     \n\
  4304.    Shift <Key> H             : selectVariation(H)                                     \n\
  4305.    Shift <Key> I             : selectVariation(I)                                     \n\
  4306.    Shift <Key> J             : selectVariation(J)                                     \n\
  4307.    Shift <Key> K             : selectVariation(K)                                     \n\
  4308.    Shift <Key> L             : selectVariation(L)                                     \n\
  4309.    Shift <Key> M             : selectVariation(M)                                     \n\
  4310.    Shift <Key> N             : selectVariation(N)                                     \n\
  4311.    Shift <Key> O             : selectVariation(O)                                     \n\
  4312.    Shift <Key> P             : selectVariation(P)                                     \n\
  4313.    Shift <Key> Q             : selectVariation(Q)                                     \n\
  4314.    Shift <Key> R             : selectVariation(R)                                     \n\
  4315.    Shift <Key> S             : selectVariation(S)                                     \n\
  4316.    Shift <Key> T             : selectVariation(T)                                     \n\
  4317.    Shift <Key> U             : selectVariation(U)                                     \n\
  4318.    Shift <Key> V             : selectVariation(V)                                     \n\
  4319.    Shift <Key> W             : selectVariation(W)                                     \n\
  4320.    Shift <Key> X             : selectVariation(X)                                     \n\
  4321.    Shift <Key> Y             : selectVariation(Y)                                     \n\
  4322.    Shift <Key> Z             : selectVariation(Z)                                     \n\
  4323.    Shift <Key> }             : nextComment()                                          \n\
  4324.    Shift <Key> {             : previousComment()                                      \n\
  4325.    <Key> a                   : setMode(Diagram)                                       \n\
  4326.    <Key> b                   : setPlayer(Black)                                       \n\
  4327.    <Key> e                   : dialog(Edit)                                           \n\
  4328.    <Key> p                   : pass()                                                 \n\
  4329.    <Key> i                   : eventInfo()                                            \n\
  4330.    <Key> v                   : setMode(View)                                          \n\
  4331.    <Key> w                   : setPlayer(White)                                       \n\
  4332.    <Key> z                   : setMode(Size)                                          \n\
  4333.    <Key> Escape              : setMode(Edit)                                          \n\
  4334.    <Key> l                   : dialog(Load)                                           \n\
  4335.    <Key> n                   : dialog(NodeName)                                       \n\
  4336.    <Key> q                   : exit()                                                 \n\
  4337.    <Key> s                   : dialog(Save)                                           \n\
  4338.    <Key> ]                   : nextVariationBranch()                                  \n\
  4339.    <Key> [                   : previousVariationBranch()                              \n\
  4340.    <Key> <                   : previousMove()                                         \n\
  4341.    <Key> >                   : nextMove()                                             \n\
  4342.    <Key> ?                   : dialog(Help)                                           \n\
  4343.    <Key> h                   : dialog(Help)                                           \n\
  4344.    Ctrl Shift <Btn1Down>     : makeVariation()                                        \n\
  4345.    Ctrl Shift <Btn2Down>     : makeVariationDiagram()                                 \n\
  4346.    Shift <Btn1Down>          : makeMove()                                             \n\
  4347.    Shift <Btn3Down>          : deleteMove()                                           \n\
  4348.    Ctrl <Btn1Down>           : letter()                                               \n\
  4349.    Ctrl <Btn2Down>           : mark()                                                 \n\
  4350.    Ctrl <Btn3Down>           : deleteMark()                                           \n\
  4351.    <Btn1Down>                : nextMove() add(Black) drag(Start)                      \n\
  4352.    <Btn2Down>                : add(White) selectDiagram()                             \n\
  4353.    <Btn3Down>                : previousMove() add(Empty)                              \n\
  4354.    <Btn1Motion>              : drag()                                                 \n\
  4355.    <Btn1Up>                  : drag(Stop)                                             \n\
  4356. "; 
  4357.  
  4358. /*******************************************************************************************************
  4359.  */
  4360.  
  4361. extern void SelectDiagram           ();
  4362. extern void Dialog                  ();
  4363. extern void NextMove                ();
  4364. extern void PreviousMove            ();
  4365. extern void SelectVariation         ();
  4366. extern void NextVariationBranch     ();
  4367. extern void PreviousVariationBranch ();
  4368. extern void NextComment             ();
  4369. extern void PreviousComment         ();
  4370. extern void Exit                    ();
  4371. extern void Help                    ();
  4372. extern void PopdownHelp             ();
  4373. extern void MakeVariationDiagram    ();
  4374. extern void SetPlayer               ();
  4375. extern void Add                     ();
  4376. extern void SetMode                 ();
  4377. extern void MakeMove                ();
  4378. extern void Pass                    ();
  4379. extern void DeleteMove              ();
  4380. extern void DeleteMark              ();
  4381. extern void MakeVariation           ();
  4382. extern void MakeVariationPass       ();
  4383. extern void Drag                    ();
  4384. extern void Letter                  ();
  4385. extern void Mark                    ();
  4386. extern void EventInfo               ();
  4387.  
  4388. XtActionsRec actions[] = {
  4389.   { "selectDiagram"           , SelectDiagram           , },
  4390.   { "dialog"                  , Dialog                  , },
  4391.   { "nextMove"                , NextMove                , },
  4392.   { "previousMove"            , PreviousMove            , },
  4393.   { "selectVariation"         , SelectVariation         , },
  4394.   { "nextVariationBranch"     , NextVariationBranch     , },
  4395.   { "previousVariationBranch" , PreviousVariationBranch , },
  4396.   { "nextComment"             , NextComment             , },
  4397.   { "previousComment"         , PreviousComment         , },
  4398.   { "exit"                    , Exit                    , },
  4399.   { "makeVariationDiagram"    , MakeVariationDiagram    , },
  4400.   { "setPlayer"               , SetPlayer               , },
  4401.   { "add"                     , Add                     , },
  4402.   { "selectDiagram"           , SelectDiagram           , },
  4403.   { "setMode"                 , SetMode                 , },
  4404.   { "makeMove"                , MakeMove                , },
  4405.   { "deleteMove"              , DeleteMove              , },
  4406.   { "deleteMark"              , DeleteMark              , },
  4407.   { "pass"                    , Pass                    , },
  4408.   { "makeVariation"           , MakeVariation           , },
  4409.   { "makeVariationPass"       , MakeVariationPass       , },
  4410.   { "drag"                    , Drag                    , },
  4411.   { "letter"                  , Letter                  , },
  4412.   { "mark"                    , Mark                    , },
  4413.   { "eventInfo"               , EventInfo               , },
  4414. }; 
  4415.  
  4416. extern void exit ();
  4417.  
  4418. #define stipple1_width  2
  4419. #define stipple1_height 2
  4420.  
  4421. static char stipple1_bits[] = {
  4422.    0x01, 0x02};
  4423.  
  4424. #define stipple2_width  4
  4425. #define stipple2_height 4
  4426.  
  4427. static char stipple2_bits[] = {
  4428.    0x05, 0x00, 0x0a, 0x00};
  4429.  
  4430. #define stipple3_width  4
  4431. #define stipple3_height 4
  4432.  
  4433. static char stipple3_bits[] = {
  4434.    0x01, 0x00, 0x00, 0x00};
  4435.  
  4436.  
  4437. void main (argc, argv)
  4438. int    argc;
  4439. char **argv;
  4440. {
  4441.   XtAppContext   app_context;
  4442.   Display       *display;
  4443.   Display       *second_display;
  4444.   Drawable       window;
  4445.   String         title;
  4446.   String         icon_title;
  4447.   Pixmap         icon_pixmap;
  4448.   Arg            args[16];
  4449.   int            xtargc;
  4450.  
  4451.   w_toplevel = XtAppInitialize (&app_context, ApplicationName,  options, XtNumber (options), 
  4452.                 &argc, argv, NULL, NULL, 0);
  4453.  
  4454.   XtGetApplicationResources (w_toplevel, &app_data, resources, XtNumber (resources), NULL, 0);
  4455.  
  4456.   if (argc == 2 && argv[1][0] != '-')
  4457.     file = argv[1];
  4458.  
  4459.   else if (argc > 1)
  4460.     app_data.help = True;
  4461.  
  4462.   /*
  4463.    *    help option 
  4464.    */
  4465.    
  4466.   if (app_data.help == True) {
  4467.     (void) fprintf (stderr, "%s", UsageString);
  4468.     (void) exit (1);
  4469.   }
  4470.  
  4471.   /*
  4472.    *    Various options 
  4473.    */
  4474.  
  4475.   if (app_data.beep > 100)
  4476.     app_data.beep = 0;
  4477.  
  4478.   path        = app_data.path;
  4479.   beep        = app_data.beep;
  4480.   autonum     = app_data.autonum;
  4481.   strict      = app_data.strict;
  4482.   short_print = app_data.short_print;
  4483.  
  4484.   if (strict == False) autonum = False;
  4485.  
  4486.   /*
  4487.    *    Mail option
  4488.    */
  4489.  
  4490.   if (app_data.mail != NULL) {
  4491.  
  4492.     if (file == NULL) {
  4493.       (void) fprintf (stderr, "XGoban : Mail mode : no input file specified\n");
  4494.       (void) exit (1);
  4495.     }
  4496.  
  4497.     strcpy (mail_file_name, app_data.mail);
  4498.  
  4499.     current_mode = MailMode;
  4500.     edit         = True;
  4501.   }
  4502.  
  4503.   /*
  4504.    *    Widget creation
  4505.    */
  4506.  
  4507.   display   = XtDisplay (w_toplevel);
  4508.   window    = RootWindowOfScreen (XtScreen (w_toplevel));
  4509.  
  4510.   icon_pixmap = XCreateBitmapFromData (display, window, icon_bits, icon_width, icon_height);
  4511.  
  4512.   xtargc    = 0;
  4513.   XtSetArg (args[xtargc], XtNiconPixmap       , (XtArgVal) icon_pixmap         ); xtargc++;
  4514.   XtSetArg (args[xtargc], XtNtitle            , (XtArgVal) ApplicationName     ); xtargc++;
  4515.   XtSetArg (args[xtargc], XtNiconName         , (XtArgVal) "Goban"             ); xtargc++;
  4516.    
  4517.   XtSetValues (w_toplevel, args, xtargc);
  4518.  
  4519.   xtargc    = 0;
  4520.   XtSetArg (args[xtargc], XtNtranslations     , (XtArgVal) XtParseTranslationTable (translations_table)); xtargc++;
  4521.   XtSetArg (args[xtargc], XtNpointSize        , (XtArgVal) app_data.point_size ); xtargc++;
  4522.   XtSetArg (args[xtargc], XtNautoRedisplay    , (XtArgVal) False               ); xtargc++;
  4523.  
  4524.   switch (app_data.stipple) {
  4525.   case 1 :
  4526.     XtSetArg (args[xtargc], XtNbackgroundPixmap , 
  4527.           XCreatePixmapFromBitmapData (display, window, (char *) stipple1_bits, 
  4528.                        stipple1_width, stipple1_height,
  4529.                        BlackPixel (display, DefaultScreen (display)),
  4530.                        WhitePixel (display, DefaultScreen (display)),
  4531.                        DefaultDepthOfScreen (XtScreen (w_toplevel))));
  4532.     xtargc++;
  4533.     break;
  4534.   case 2 :
  4535.     XtSetArg (args[xtargc], XtNbackgroundPixmap , 
  4536.           XCreatePixmapFromBitmapData (display, window, (char *) stipple2_bits, 
  4537.                        stipple2_width, stipple2_height,
  4538.                        BlackPixel (display, DefaultScreen (display)),
  4539.                        WhitePixel (display, DefaultScreen (display)),
  4540.                        DefaultDepthOfScreen (XtScreen (w_toplevel))));
  4541.     xtargc++;
  4542.     break;
  4543.   case 3 :
  4544.     XtSetArg (args[xtargc], XtNbackgroundPixmap , 
  4545.           XCreatePixmapFromBitmapData (display, window, (char *) stipple3_bits, 
  4546.                        stipple3_width, stipple3_height,
  4547.                        BlackPixel (display, DefaultScreen (display)),
  4548.                        WhitePixel (display, DefaultScreen (display)),
  4549.                        DefaultDepthOfScreen (XtScreen (w_toplevel))));
  4550.     xtargc++;
  4551.     break;
  4552.   }
  4553.  
  4554.   w_goban   = XtCreateManagedWidget ("goban"      , gobanWidgetClass     , w_toplevel  , args, xtargc);
  4555.  
  4556.   xtargc    = 0;
  4557.   XtSetArg (args[xtargc], XtNiconPixmap       , (XtArgVal) icon_pixmap         ); xtargc++;
  4558.   XtSetArg (args[xtargc], XtNtitle            , (XtArgVal) "XGoban : comment"  ); xtargc++;
  4559.   XtSetArg (args[xtargc], XtNiconName         , (XtArgVal) "Comment"           ); xtargc++;
  4560.  
  4561.   c_toplevel = XtCreatePopupShell ("comment", applicationShellWidgetClass, w_toplevel, args, xtargc);
  4562.  
  4563.   xtargc    = 0;
  4564.   XtSetArg (args[xtargc], XtNwidth            , (XtArgVal) 540                 ); xtargc++;
  4565.   XtSetArg (args[xtargc], XtNheight           , (XtArgVal) 200                 ); xtargc++;
  4566.   XtSetArg (args[xtargc], XtNscrollVertical   , (XtArgVal) XawtextScrollAlways ); xtargc++;
  4567.   XtSetArg (args[xtargc], XtNwrap             , (XtArgVal) XawtextWrapWord     ); xtargc++;
  4568.   XtSetArg (args[xtargc], XtNeditType         , (XtArgVal) XawtextRead         ); xtargc++;
  4569.   XtSetArg (args[xtargc], XtNdisplayCaret     , (XtArgVal) False               ); xtargc++;
  4570.  
  4571.   c_comment = XtCreateManagedWidget ("commentText", asciiTextWidgetClass , c_toplevel   , args, xtargc);
  4572.  
  4573.   makeDialogWindow  (w_toplevel, app_context);
  4574.   makeEventWindow   (w_toplevel, app_context);
  4575.  
  4576.   XtAppAddActions (app_context, actions, XtNumber(actions));
  4577.   XawSimpleMenuAddGlobalActions (app_context); 
  4578.  
  4579.   XtRegisterGrabAction (SelectDiagram, True, (ButtonPressMask | ButtonReleaseMask), GrabModeAsync, GrabModeAsync);
  4580.   XtRealizeWidget (w_toplevel);
  4581.  
  4582.   /*
  4583.    *   Second display
  4584.    */
  4585.  
  4586.   if (current_mode == EditMode) {
  4587.     if (app_data.white_dsp != NULL) {
  4588.       second_display = XtOpenDisplay (app_context, app_data.white_dsp, NULL, ApplicationName, 
  4589.                       options, XtNumber (options), &argc, argv);
  4590.       
  4591.       w_second_toplevel  = XtAppCreateShell (argv[0], ApplicationName, applicationShellWidgetClass, second_display, NULL, 0);
  4592.       second_player      = SG_WhiteStone;
  4593.     }
  4594.     
  4595.     else if (app_data.black_dsp != NULL) {
  4596.       second_display = XtOpenDisplay (app_context, app_data.black_dsp, NULL, ApplicationName,
  4597.                       options, XtNumber (options), &argc, argv);
  4598.       
  4599.       w_second_toplevel  = XtAppCreateShell (argv[0], ApplicationName, applicationShellWidgetClass, second_display, NULL, 0);
  4600.       second_player      = SG_BlackStone;
  4601.     }
  4602.     
  4603.     if (w_second_toplevel != NULL) {
  4604.       
  4605.       window     = RootWindowOfScreen (XtScreen (w_second_toplevel));
  4606.       
  4607.       title      = second_player == SG_BlackStone ? "XGoban : Black" : "XGoban : White"; 
  4608.       icon_title = second_player == SG_BlackStone ? "Black" : "White"; 
  4609.       
  4610.       xtargc    = 0;
  4611.       XtSetArg (args[xtargc], XtNiconPixmap, icon_pixmap ); xtargc++;
  4612.       XtSetArg (args[xtargc], XtNtitle     , title       ); xtargc++;
  4613.       XtSetArg (args[xtargc], XtNiconName  , icon_title  ); xtargc++;
  4614.       
  4615.       XtSetValues (w_second_toplevel, args, xtargc);
  4616.       
  4617.       title      = second_player == SG_BlackStone ? "XGoban : White" : "XGoban : Black"; 
  4618.       icon_title = second_player == SG_BlackStone ? "White" : "Black"; 
  4619.       
  4620.       xtargc    = 0;
  4621.       XtSetArg (args[xtargc], XtNtitle     , title       ); xtargc++;
  4622.       XtSetArg (args[xtargc], XtNiconName  , icon_title  ); xtargc++;
  4623.       
  4624.       XtSetValues (w_toplevel, args, xtargc);
  4625.       
  4626.       xtargc    = 0;
  4627.       XtSetArg (args[xtargc], XtNtranslations     , (XtArgVal) XtParseTranslationTable (translations_table)); xtargc++;
  4628.       XtSetArg (args[xtargc], XtNpointSize        , (XtArgVal) app_data.point_size ); xtargc++;
  4629.       XtSetArg (args[xtargc], XtNautoRedisplay    , (XtArgVal) False               ); xtargc++;
  4630.       
  4631.       w_second_goban   = XtCreateManagedWidget ("goban"      , gobanWidgetClass     , w_second_toplevel, args, xtargc);
  4632.       
  4633.       XtRealizeWidget (w_second_toplevel);
  4634.       
  4635.       current_mode = PlayMode;
  4636.     }
  4637.   }
  4638.  
  4639.   /*
  4640.    *   Black and White options : play a game
  4641.    */
  4642.     
  4643.   if (current_mode == EditMode) {
  4644.     if (app_data.black != NULL) {
  4645.       current_mode = PlayMode;
  4646.       edit         = True;
  4647.       
  4648.       if (strcmp (app_data.black, "wally") == 0)
  4649.     black_player = Wally;
  4650.       else if (strcmp (app_data.black, "gnugo") == 0)
  4651.     black_player = Gnugo;
  4652.     }
  4653.     
  4654.     if (app_data.white != NULL) {
  4655.       current_mode = PlayMode;
  4656.       edit         = True;
  4657.       
  4658.       if (strcmp (app_data.white, "wally") == 0)
  4659.     PopupDialog (w_toplevel, NULL, WallyWhitePlayWarning);
  4660.       else if (strcmp (app_data.white, "gnugo") == 0)
  4661.     white_player = Gnugo;
  4662.     }
  4663.   }
  4664.  
  4665.   /*
  4666.    *    File option 
  4667.    */
  4668.  
  4669.   file_name[0] = '\0';
  4670.  
  4671.   if (file != NULL) {
  4672.     (void) strcpy (file_name, file);
  4673.  
  4674.     if (current_mode != PlayMode)
  4675.       if (LoadFile (NULL, NULL, file) == True) {
  4676.     app_data.handicap = 0;
  4677.     app_data.size     = 19;
  4678.       }
  4679.     
  4680.       else {
  4681.     (void) fprintf (stderr, "XGoban : can't open file : %s\n", file);
  4682.     (void) exit (1);
  4683.       }
  4684.   }
  4685.  
  4686.   /*
  4687.    *   Create first node
  4688.    */
  4689.  
  4690.   if (tree == NULL) {
  4691.     tree         = SG_MakeNode (NULL, SG_Event);
  4692.     current_node = tree;
  4693.  
  4694.     if (current_mode != PlayMode) Edit (True);
  4695.   }
  4696.  
  4697.   if (current_mode == PlayMode) {
  4698.     switch (black_player) {
  4699.     case Gnugo : SG_MakeProperty (tree, SG_PlayerBlack, (long) "gnugo"); break;
  4700.     case Wally : SG_MakeProperty (tree, SG_PlayerBlack, (long) "wally"); break;
  4701.     case Human : 
  4702.       if (app_data.black != NULL) 
  4703.     SG_MakeProperty (tree, SG_PlayerBlack, (long) app_data.black); 
  4704.       break;
  4705.     }
  4706.  
  4707.     switch (white_player) {
  4708.     case Gnugo : SG_MakeProperty (tree, SG_PlayerWhite, (long) "gnugo"); break;
  4709.     case Wally : SG_MakeProperty (tree, SG_PlayerWhite, (long) "wally"); break;
  4710.     case Human : 
  4711.       if (app_data.white != NULL) 
  4712.     SG_MakeProperty (tree, SG_PlayerWhite, (long) app_data.white); 
  4713.       break;
  4714.     }
  4715.   }
  4716.  
  4717.   /*
  4718.    *    Size option 
  4719.    */
  4720.  
  4721.   if (app_data.size > 1 && app_data.size < 19) {
  4722.     if (black_player == Wally && app_data.size != 9 && app_data.size != 13 && app_data.size != 19) {
  4723.       PopupDialog (w_toplevel, NULL, WallyBadSizeWarning);
  4724.       app_data.size = 9;
  4725.     }
  4726.  
  4727.     SG_MakeProperty (current_node, SG_SiZe, (long) app_data.size);
  4728.  
  4729.     modified = True;
  4730.     if (current_mode != PlayMode) Edit (True);
  4731.   }
  4732.  
  4733.   else 
  4734.     app_data.size = 19;
  4735.  
  4736.   board_size = app_data.size;
  4737.  
  4738.   /*
  4739.    *    Handicap option 
  4740.    */
  4741.  
  4742.   current_node->player = SG_BlackStone;
  4743.  
  4744.   if (app_data.handicap > 1) {
  4745.     int            x;
  4746.     int            y;
  4747.     int            h;
  4748.     char          *ptr = stars[app_data.size - 2];
  4749.     unsigned char *setup;
  4750.  
  4751.     if (black_player == Wally && app_data.handicap != 9) {
  4752.       PopupDialog (w_toplevel, NULL, WallyBadHandicapWarning);
  4753.       app_data.handicap = 9;
  4754.     }
  4755.  
  4756.     if (*ptr == '\0') {
  4757.       PopupDialog (w_toplevel, NULL, BadHandicapWarning);
  4758.       app_data.handicap = 0;
  4759.     }
  4760.  
  4761.     else {
  4762.       setup = current_node->setup = (unsigned char *) malloc ((unsigned) 2 * app_data.handicap + 1);
  4763.  
  4764.       for (h = 0; h < app_data.handicap && *ptr != '\0'; h++) {
  4765.     x = *ptr++;
  4766.     y = *ptr++;
  4767.     
  4768.     if (h == 4 && (app_data.handicap == 6 || app_data.handicap == 8)) {
  4769.       x = *ptr++;
  4770.       y = *ptr++;
  4771.     }
  4772.  
  4773.     *setup++ = SG_SETB | (x - 'a' + 1);
  4774.     *setup++ = SG_SETB | (y - 'a' + 1);
  4775.       }
  4776.       
  4777.       if (h != app_data.handicap) {
  4778.     PopupDialog (w_toplevel, NULL, RemainingStonesWarning);
  4779.     app_data.handicap -= h;
  4780.       }
  4781.     
  4782.       *setup++ = SG_EOS;
  4783.       current_node->player = SG_WhiteStone;
  4784.       
  4785.       modified = True;
  4786.       if (current_mode != PlayMode) Edit (True);
  4787.     }
  4788.   }
  4789.  
  4790.   else 
  4791.     app_data.handicap = 0;
  4792.  
  4793.   handicap = app_data.handicap;
  4794.  
  4795.   /*
  4796.    *    Play first node and go... 
  4797.    */
  4798.  
  4799.   GbClearBoard (w_goban);
  4800.  
  4801.   switch (current_mode) {
  4802.   case PlayMode :
  4803.     startGame (app_context);
  4804.     break;
  4805.  
  4806.   case EditMode :
  4807.     XtPopup (c_toplevel, XtGrabNone);
  4808.     break;
  4809.  
  4810.   case MailMode :
  4811.     XtPopup (c_toplevel, XtGrabNone);
  4812.  
  4813.     while (current_node->down != NULL) {
  4814.       Play            (current_node);
  4815.       ShowProperty    (current_node);
  4816.       HideTmpProperty (current_node);
  4817.  
  4818.       current_node = current_node->down;
  4819.     }
  4820.  
  4821.     mail_node = current_node;
  4822.     break;
  4823.  
  4824.   default :
  4825.     break;
  4826.   }
  4827.  
  4828.   Play           (current_node);
  4829.   ShowProperty   (current_node);
  4830.   RedisplayBoard ();
  4831.  
  4832.   XtAppMainLoop    (app_context);
  4833.  
  4834.   /* NOTREACHED */
  4835. }
  4836.  
  4837. /*******************************************************************************************************
  4838.  */
  4839. SHAR_EOF
  4840. fi # end of overwriting check
  4841. if test -f 'action.c'
  4842. then
  4843.     echo shar: will not over-write existing file "'action.c'"
  4844. else
  4845. cat << \SHAR_EOF > 'action.c'
  4846. /****************************************************************************************************************
  4847.  *
  4848.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  4849.  *
  4850.  *  This program is distributed in the hope that it will be useful.
  4851.  *  Use and copying of this software and preparation of derivative works
  4852.  *  based upon this software are permitted, so long as the following
  4853.  *  conditions are met:
  4854.  *       o credit to the authors is acknowledged following current
  4855.  *         academic behaviour
  4856.  *       o no fees or compensation are charged for use, copies, or
  4857.  *         access to this software
  4858.  *       o this copyright notice is included intact.
  4859.  *  This software is made available AS IS, and no warranty is made about 
  4860.  *  the software or its performance. 
  4861.  * 
  4862.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4863.  *  Send them to    dumesnil@etca.fr   or to:
  4864.  *       
  4865.  *       Antoine de Maricourt
  4866.  *       ETCA CREA-SP
  4867.  *       16 bis, avenue Prieur de la Cote d'Or
  4868.  *       94114 Arcueil Cedex
  4869.  *       France
  4870.  */
  4871.  
  4872. #include <X11/Intrinsic.h>
  4873. #include <X11/Shell.h>
  4874. #include <X11/StringDefs.h>
  4875.  
  4876. #include <X11/Xaw/SimpleMenu.h>
  4877. #include <X11/Xaw/SmeBSB.h>
  4878. #include <X11/cursorfont.h>
  4879.  
  4880. #include "xgoban.h"
  4881.  
  4882. /*******************************************************************************************************
  4883.  */
  4884.  
  4885. /* ARGSUSED */
  4886.  
  4887. void NextComment (w, event, params, num_params)
  4888. Widget    w;
  4889. XEvent   *event;
  4890. String   *params;
  4891. Cardinal *num_params;
  4892. {
  4893.   Arg     arg;
  4894.   Boolean no_beep = False;
  4895.  
  4896.   if (current_node != NULL)
  4897.     switch (current_mode) {
  4898.     case EditMode :
  4899.     case MailMode :
  4900.       
  4901.       if (current_node->down != NULL) {
  4902.     XtSetArg (arg, XtNautoRedisplay, (XtArgVal) True ); XtSetValues (w_goban, &arg, 1);
  4903.     
  4904.     do {
  4905.       HideTmpProperty (current_node);
  4906.       
  4907.       current_node = current_node->down;
  4908.       
  4909.       Play            (current_node);
  4910.       ShowProperty    (current_node);
  4911.       
  4912.       if (SG_GetProperty (current_node, SG_Comment) != NULL) {
  4913.         no_beep = True;
  4914.         break;
  4915.       }
  4916.       
  4917.     } while (current_node->down != NULL && current_node->right == NULL);
  4918.     
  4919.     XtSetArg (arg, XtNautoRedisplay, (XtArgVal) False); XtSetValues (w_goban, &arg, 1);
  4920.       }
  4921.       
  4922.       if (beep >= -100 && no_beep == False)
  4923.     XBell (XtDisplay (w), beep);
  4924.       break;
  4925.       
  4926.     default : break;
  4927.     }
  4928. }
  4929.  
  4930. /*******************************************************************************************************
  4931.  */
  4932.  
  4933. /* ARGSUSED */
  4934.  
  4935. void PreviousComment (w, event, params, num_params)
  4936. Widget    w;
  4937. XEvent   *event;
  4938. String   *params;
  4939. Cardinal *num_params;
  4940. {
  4941.   SG_NodePtr tmp;
  4942.   Arg        arg;
  4943.   Boolean    no_beep = False;
  4944.  
  4945.   if (current_node != NULL)
  4946.     switch (current_mode) {
  4947.     case EditMode :
  4948.     case MailMode :
  4949.       
  4950.       XtSetArg (arg, XtNautoRedisplay, (XtArgVal) True ); XtSetValues (w_goban, &arg, 1);
  4951.       
  4952.       do {
  4953.     tmp = current_node;
  4954.     while (tmp->left != NULL) tmp = tmp->left;
  4955.     
  4956.     if (tmp->up != NULL) {
  4957.       Unplay          (current_node);
  4958.       HideProperty    (current_node);
  4959.       
  4960.       current_node = tmp->up;
  4961.       
  4962.       ShowTmpProperty (current_node);
  4963.     }
  4964.     
  4965.     if (SG_GetProperty (current_node, SG_Comment) != NULL) {
  4966.       no_beep = True;
  4967.       break;
  4968.     }
  4969.     
  4970.       } while (tmp->up != NULL && current_node->left == NULL && current_node->right == NULL); 
  4971.       
  4972.       XtSetArg (arg, XtNautoRedisplay, (XtArgVal) False); XtSetValues (w_goban, &arg, 1);
  4973.       
  4974.       if (beep >= -100 && no_beep == False)
  4975.     XBell (XtDisplay (w), beep);
  4976.     }
  4977. }
  4978.  
  4979. /*******************************************************************************************************
  4980.  */
  4981.  
  4982. /* ARGSUSED */
  4983.  
  4984. void NextVariationBranch (w, event, params, num_params)
  4985. Widget    w;
  4986. XEvent   *event;
  4987. String   *params;
  4988. Cardinal *num_params;
  4989. {
  4990.   Arg arg;
  4991.  
  4992.   if (current_node != NULL)
  4993.     switch (current_mode) {
  4994.     case EditMode :
  4995.     case MailMode :
  4996.       
  4997.       if (current_node->down != NULL) {
  4998.     XtSetArg (arg, XtNautoRedisplay, (XtArgVal) True ); XtSetValues (w_goban, &arg, 1);
  4999.     
  5000.     HideTmpProperty (current_node);
  5001.     
  5002.     current_node = current_node->down;
  5003.     
  5004.     Play            (current_node);
  5005.     ShowProperty    (current_node);
  5006.     
  5007.     while (current_node->down != NULL && current_node->right == NULL) {
  5008.       HideTmpProperty  (current_node);
  5009.       
  5010.       current_node = current_node->down;
  5011.       
  5012.       Play             (current_node);
  5013.       ShowProperty     (current_node);
  5014.     }
  5015.     
  5016.     XtSetArg (arg, XtNautoRedisplay, (XtArgVal) False); XtSetValues (w_goban, &arg, 1);
  5017.       }
  5018.       
  5019.       else if (beep >= -100)
  5020.     XBell (XtDisplay (w), beep);
  5021.     }
  5022. }    
  5023.  
  5024. /*******************************************************************************************************
  5025.  */
  5026.  
  5027. /* ARGSUSED */
  5028.  
  5029. void PreviousVariationBranch (w, event, params, num_params)
  5030. Widget    w;
  5031. XEvent   *event;
  5032. String   *params;
  5033. Cardinal *num_params;
  5034. {
  5035.   SG_NodePtr tmp;
  5036.   Boolean    no_beep = False;
  5037.   Arg        arg;
  5038.  
  5039.   if (current_node != NULL)
  5040.     switch (current_mode) {
  5041.     case EditMode :
  5042.     case MailMode :
  5043.       
  5044.       XtSetArg (arg, XtNautoRedisplay, (XtArgVal) True ); XtSetValues (w_goban, &arg, 1);
  5045.       
  5046.       do {
  5047.     tmp = current_node;
  5048.     while (tmp->left != NULL) tmp = tmp->left;
  5049.     
  5050.     if (tmp->up != NULL) {
  5051.       Unplay          (current_node);
  5052.       HideProperty    (current_node);
  5053.       
  5054.       current_node = tmp->up;
  5055.       no_beep      = True;
  5056.       
  5057.       ShowTmpProperty (current_node);
  5058.     }
  5059.       } while (tmp->up != NULL && current_node->left == NULL && current_node->right == NULL); 
  5060.       
  5061.       XtSetArg (arg, XtNautoRedisplay, (XtArgVal) False); XtSetValues (w_goban, &arg, 1);
  5062.       
  5063.       if (beep >= -100 && no_beep == False)
  5064.     XBell (XtDisplay (w), beep);
  5065.     }  
  5066. }
  5067.  
  5068. /*******************************************************************************************************
  5069.  */
  5070.  
  5071. /* ARGSUSED */
  5072.  
  5073. void PreviousMove (w, event, params, num_params)
  5074. Widget    w;
  5075. XEvent   *event;
  5076. String   *params;
  5077. Cardinal *num_params;
  5078. {
  5079.   SG_NodePtr tmp = current_node;
  5080.  
  5081.   if (current_node != NULL)
  5082.     switch (current_mode) {
  5083.     case EditMode :
  5084.     case MailMode :
  5085.       
  5086.       while (tmp->left != NULL)
  5087.     tmp = tmp->left;
  5088.       
  5089.       if (tmp->up != NULL) {
  5090.     Unplay           (current_node);
  5091.     HideProperty     (current_node);
  5092.     
  5093.     current_node = tmp->up;
  5094.     
  5095.     ShowTmpProperty  (current_node);
  5096.     RedisplayBoard   ();
  5097.  
  5098.     return;
  5099.       }
  5100.  
  5101.       if (beep >= -100)
  5102.     XBell (XtDisplay (w), beep);
  5103.     }
  5104. }
  5105.  
  5106. /*******************************************************************************************************
  5107.  */
  5108.  
  5109. /* ARGSUSED */
  5110.  
  5111. void Exit (w, event, params, num_params)
  5112. Widget  w;
  5113. XEvent *event;
  5114. String   *params;
  5115. Cardinal *num_params;
  5116. {
  5117.   HideTmpProperty (current_node);
  5118.   ShowTmpProperty (current_node);
  5119.  
  5120.   switch (current_mode) {
  5121.   case EditMode :
  5122.     PopupDialog (w, event, modified == True ? SaveBeforeQuitDialog : ReallyQuitDialog);
  5123.     break;
  5124.   case PlayMode :
  5125.     PopupDialog (w, event, StopGameBeforeQuitDialog);
  5126.     break;
  5127.   case MailMode :
  5128.     PopupDialog (w, event, mail_node->down == NULL ? MailNoMoveDialog : MailConfirmMoveDialog);
  5129.     break;
  5130.   }
  5131. }
  5132.  
  5133. /*******************************************************************************************************
  5134.  */
  5135.  
  5136.  
  5137. /* ARGSUSED */
  5138.  
  5139. void destroyMenu (w, client_data, call_data)
  5140. Widget    w;
  5141. XtPointer client_data;
  5142. XtPointer call_data;
  5143. {
  5144.   if (w_menu != NULL) {
  5145.     XtDestroyWidget (w_menu);
  5146.     w_menu = NULL;
  5147.   }
  5148. }
  5149.  
  5150. /* ARGSUSED */
  5151.  
  5152. void menuAction (w, client_data, call_data)
  5153. Widget    w;
  5154. XtPointer client_data;
  5155. XtPointer call_data;
  5156. {
  5157.   SG_NodePtr tmp  = current_node;
  5158.   char       mark = (int) client_data - 'A';
  5159.  
  5160.   while (tmp->left != NULL)
  5161.     tmp = tmp->left;
  5162.  
  5163.   while (mark-- != 0)
  5164.     tmp = tmp->right;
  5165.  
  5166.           
  5167.   Unplay           (current_node);
  5168.   HideProperty     (current_node);
  5169.           
  5170.   current_node = tmp;
  5171.           
  5172.   Play           (current_node);
  5173.   ShowProperty   (current_node);
  5174.   RedisplayBoard ();
  5175. }
  5176.  
  5177. /* ARGSUSED */
  5178.  
  5179. void SelectDiagram (w, event, params, num_params)
  5180. Widget    w;
  5181. XEvent   *event;
  5182. String   *params;
  5183. Cardinal *num_params;
  5184. {
  5185.   Widget         entry;
  5186.   Arg            args[4];
  5187.   int            xtargc;
  5188.   SG_NodePtr     tmp   = current_node;
  5189.   SG_PropertyPtr property;
  5190.   String         nparams[1];
  5191.   char           buffer[256];
  5192.   char           mark  = 'A';
  5193.     
  5194.   if (event->type != ButtonPress) {
  5195.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5196.           "XGoban - selectDiagram : This action routine requires a button press event.");
  5197.     return;
  5198.   }
  5199.  
  5200.   if (*num_params != 0)
  5201.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5202.           "XGoban - selectDiagram : This action routine requires no argument.");
  5203.  
  5204.   if (current_node != NULL)
  5205.     switch (current_mode) {
  5206.     case EditMode :
  5207.     case MailMode :
  5208.  
  5209.       while (tmp->left != NULL)
  5210.     tmp = tmp->left;
  5211.  
  5212.       if (tmp->right == NULL) {
  5213.     if (beep >= -100)
  5214.       XBell (XtDisplay (w), beep);
  5215.     return;
  5216.       }
  5217.  
  5218.       if (w_menu == NULL) {
  5219.  
  5220.     xtargc = 0;
  5221.     XtSetArg (args[xtargc], XtNlabel        , " Variations "); xtargc++;
  5222.     
  5223.     w_menu = XtCreatePopupShell ("variations", simpleMenuWidgetClass, w_goban, args, xtargc);
  5224.     
  5225.     entry = XtNameToWidget (w_menu, "menuLabel");
  5226.     
  5227.     xtargc = 0;
  5228.     XtSetArg (args[xtargc], XtNheight        , 32           ); xtargc++;
  5229.     XtSetValues (entry, args, xtargc);
  5230.     
  5231.     while (tmp != NULL) {
  5232.       property = SG_GetProperty (tmp, SG_nodeName);
  5233.  
  5234.       if (property != NULL && property->data.pvalue != NULL)
  5235.         sprintf (buffer, "%c : %s", mark, property->data.pvalue);
  5236.  
  5237.       else
  5238.         switch (tmp->type) {
  5239.         case SG_EventType :
  5240.           sprintf (buffer, "%c : (Event)", mark);
  5241.           break;
  5242.  
  5243.         case SG_DiagramType :
  5244.           sprintf (buffer, "%c : (Diagram)", 
  5245.                mark);
  5246.           break;
  5247.           
  5248.         case SG_MoveType :
  5249.           if (tmp->x != 0 && tmp->y != 0)
  5250.         sprintf (buffer, "%c : %s %c%d", 
  5251.              mark,
  5252.              tmp->color == SG_BlackStone ? "Black" : "White",
  5253.              tmp->x + 'A' + (tmp->x < 9 ? -1 : 0),
  5254.              tmp->y);
  5255.           else
  5256.         sprintf (buffer, "%c : %s passes", 
  5257.              mark,
  5258.              tmp->color == SG_BlackStone ? "Black" : "White");
  5259.           break;
  5260.         }
  5261.       
  5262.       xtargc = 0;
  5263.       XtSetArg (args[xtargc], XtNleftMargin, 8); xtargc++;
  5264.       
  5265.       entry = XtCreateManagedWidget (buffer, smeBSBObjectClass, w_menu, args, xtargc);
  5266.       
  5267.       XtAddCallback (entry, XtNcallback, menuAction, (XtPointer) mark);
  5268.       
  5269.       if (tmp == current_node) {
  5270.         XtSetArg (args[0], XtNpopupOnEntry, entry);
  5271.         XtSetValues (w_menu, args, 1);
  5272.       }
  5273.  
  5274.       mark++;
  5275.       tmp = tmp->right;
  5276.     }
  5277.       }
  5278.  
  5279.       XtAddCallback (w_menu, XtNpopdownCallback, destroyMenu, (XtPointer) NULL);
  5280.  
  5281.       nparams[0] = "variations";
  5282.  
  5283.       XtCallActionProc (w_goban, "XawPositionSimpleMenu", event, nparams, 1); 
  5284.       XtCallActionProc (w_goban, "MenuPopup"            , event, nparams, 1);
  5285.  
  5286.       return;
  5287.     }
  5288. }
  5289.  
  5290. /*******************************************************************************************************
  5291.  */
  5292.  
  5293.  
  5294. /* ARGSUSED */
  5295.  
  5296. void SelectVariation (w, event, params, num_params)
  5297. Widget    w;
  5298. XEvent   *event;
  5299. String   *params;
  5300. Cardinal *num_params;
  5301. {
  5302.   char       ch;
  5303.   SG_NodePtr tmp    = current_node;
  5304.  
  5305.   if (*num_params != 1) {
  5306.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5307.           "XGoban - selectVariation : This action routine requires one argument.");
  5308.     return;
  5309.   }
  5310.  
  5311.   ch = params[0][0];
  5312.  
  5313.   if (ch < 'a' && ch > 'z' && ch < 'A' && ch > 'Z') {
  5314.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5315.           "XGoban - selectVariation : argument should range between 'A' and 'Z'.");
  5316.     return;
  5317.   }
  5318.  
  5319.   if (current_node != NULL) 
  5320.     switch (current_mode) {
  5321.     case EditMode :
  5322.     case MailMode :
  5323.  
  5324.       ch  = tolower (ch) - 'a';
  5325.       
  5326.       while (tmp->left != NULL) 
  5327.     tmp = tmp->left;
  5328.       
  5329.       if (tmp->right != NULL) {
  5330.     while (tmp != NULL && ch != 0) {
  5331.       ch--;
  5332.       tmp = tmp->right;
  5333.     }
  5334.  
  5335.     if (ch == 0 && tmp != NULL) {
  5336.       if (tmp != current_node) {
  5337.         Unplay       (current_node);
  5338.         HideProperty (current_node);
  5339.         
  5340.         current_node = tmp; 
  5341.         
  5342.         Play           (current_node);
  5343.         ShowProperty   (current_node);
  5344.         RedisplayBoard ();
  5345.       }
  5346.  
  5347.       return;
  5348.     }
  5349.       }
  5350.       
  5351.       if (beep >= -100)
  5352.     XBell (XtDisplay (w), beep);
  5353.     }
  5354. }
  5355.  
  5356. /*******************************************************************************************************
  5357.  */
  5358.  
  5359. /* ARGSUSED */
  5360.  
  5361. void Dialog (w, event, params, num_params)
  5362. Widget    w;
  5363. XEvent   *event;
  5364. String   *params;
  5365. Cardinal *num_params;
  5366. {
  5367.   if (*num_params != 1) {
  5368.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5369.           "XGoban - dialog : This action routine requires one argument.");
  5370.     return;
  5371.   }
  5372.  
  5373.   switch (current_mode) {
  5374.   case EditMode :
  5375.     switch (params[0][0]) {
  5376.     case 'E' : case 'e' : PopupDialog (w, event, EditDialog    ); break;
  5377.     case 'L' : case 'l' : PopupDialog (w, event, modified == True ? SaveBeforeLoadDialog : LoadDialog); break;
  5378.     case 'N' : case 'n' : PopupDialog (w, event, NodeNameDialog); break;
  5379.     case 'S' : case 's' : PopupDialog (w, event, SaveAsDialog  ); break;
  5380.     case 'H' : case 'h' : PopupDialog (w, event, HelpDialog    ); break;
  5381.     default :
  5382.       XtAppWarning (XtWidgetToApplicationContext (w), 
  5383.             "XGoban - dialog : Argument should be Save, Load, Edit, Help or NodeName.");
  5384.     }
  5385.     break;
  5386.  
  5387.   case PlayMode :
  5388.     switch (params[0][0]) {
  5389.     case 'E' : case 'e' : PopupDialog (w, event, StopGameDialog); break;
  5390.     case 'S' : case 's' : PopupDialog (w, event, SaveAsDialog  ); break;
  5391.     case 'H' : case 'h' : PopupDialog (w, event, HelpDialog    ); break;
  5392.     case 'N' : case 'n' : 
  5393.     case 'L' : case 'l' :
  5394.       if (beep >= -100)
  5395.     XBell (XtDisplay (w), beep); break;
  5396.     default :
  5397.       XtAppWarning (XtWidgetToApplicationContext (w), 
  5398.             "XGoban - dialog : Argument should be Save, Load, Edit, Help or NodeName.");
  5399.     }
  5400.       
  5401.   case MailMode :
  5402.     switch (params[0][0]) {
  5403.     case 'N' : case 'n' : PopupDialog (w, event, NodeNameDialog); break;
  5404.     case 'S' : case 's' : PopupDialog (w, event, SaveAsDialog  ); break;
  5405.     case 'H' : case 'h' : PopupDialog (w, event, HelpDialog    ); break;
  5406.     case 'E' : case 'e' :
  5407.     case 'L' : case 'l' :
  5408.       if (beep >= -100)
  5409.     XBell (XtDisplay (w), beep); break;
  5410.  
  5411.     default :
  5412.       XtAppWarning (XtWidgetToApplicationContext (w), 
  5413.             "XGoban - dialog : Argument should be Save, Load, Edit, Help or NodeName.");
  5414.     }
  5415.     break;
  5416.   }
  5417. }
  5418.  
  5419. /*******************************************************************************************************
  5420.  */
  5421.  
  5422. /* ARGSUSED */
  5423.  
  5424. void NextMove (w, event, params, num_params)
  5425. Widget    w;
  5426. XEvent   *event;
  5427. String   *params;
  5428. Cardinal *num_params;
  5429. {
  5430.   Position   x;
  5431.   Position   y;
  5432.   SG_NodePtr tmp    = current_node;
  5433.  
  5434.   if (current_node != NULL)
  5435.     switch (current_mode) {
  5436.     case EditMode :
  5437.     case MailMode :
  5438.       
  5439.       if (event->type == ButtonPress) {
  5440.     
  5441.     if (current_node->type == SG_MoveType) {
  5442.       while (tmp->left != NULL)
  5443.         tmp = tmp->left;
  5444.       
  5445.       if (tmp->right != NULL) {
  5446.         
  5447.         x = (Position) ((XButtonPressedEvent *) event)->x;
  5448.         y = (Position) ((XButtonPressedEvent *) event)->y;
  5449.         
  5450.         if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  5451.  
  5452.           while (tmp != NULL) {
  5453.         if (tmp->type == SG_MoveType && tmp->color == current_node->color &&
  5454.             (Position) tmp->x == x && (Position) tmp->y == y) {
  5455.             
  5456.           Unplay           (current_node);
  5457.           HideProperty     (current_node);
  5458.             
  5459.           current_node = tmp; 
  5460.             
  5461.           Play           (current_node);
  5462.           ShowProperty   (current_node);
  5463.           RedisplayBoard ();
  5464.           
  5465.           return;
  5466.         }
  5467.  
  5468.         tmp = tmp->right;
  5469.           }
  5470.         }
  5471.       }
  5472.     }
  5473.       }
  5474.       
  5475.       if (current_node->down != NULL) {
  5476.     HideTmpProperty (current_node);
  5477.     
  5478.     current_node = current_node->down;
  5479.     
  5480.     Play           (current_node);
  5481.     ShowProperty   (current_node);
  5482.     RedisplayBoard ();
  5483.       }
  5484.       
  5485.       else if (beep >= -100)
  5486.     XBell (XtDisplay (w), beep);
  5487.     }
  5488. }
  5489.  
  5490. /*******************************************************************************************************
  5491.  */
  5492.  
  5493. /* ARGSUSED */
  5494.  
  5495. void MakeVariationDiagram (w, event, params, num_params)
  5496. Widget    w;
  5497. XEvent   *event;
  5498. String   *params;
  5499. Cardinal *num_params;
  5500. {
  5501.   SG_NodePtr  node;
  5502.  
  5503.   if (*num_params != 0)
  5504.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5505.           "XGoban - makeVariationDiagram : This action routine requires no argument.");
  5506.  
  5507.   if (current_node != NULL)
  5508.     switch (current_mode) {
  5509.     case EditMode :
  5510.     case MailMode :
  5511.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5512.  
  5513.       node = SG_MakeNode (current_node, current_node->type == SG_EventType ? SG_Event : SG_VariationDiagram);
  5514.  
  5515.       if (node == NULL) {
  5516.     PopupDialog (w, event, MemoryErrorDialog);
  5517.     return;
  5518.       }
  5519.      
  5520.       node->player = current_node->player;
  5521.       modified     = True;
  5522.       
  5523.       Unplay           (current_node);
  5524.       HideProperty     (current_node);
  5525.       
  5526.       current_node = node;
  5527.       current_mode = DiagramMode;
  5528.  
  5529.       StartDiagram ();
  5530.  
  5531.       Play           (current_node);
  5532.       ShowProperty   (current_node);
  5533.       RedisplayBoard ();
  5534.     }
  5535. }
  5536.  
  5537. /*******************************************************************************************************
  5538.  */
  5539.  
  5540. /* ARGSUSED */
  5541.  
  5542. void Add (w, event, params, num_params)
  5543. Widget    w;
  5544. XEvent   *event;
  5545. String   *params;
  5546. Cardinal *num_params;
  5547. {
  5548.   Position      x;
  5549.   Position      y;
  5550.  
  5551.   if (event->type != ButtonPress) {
  5552.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5553.           "XGoban - add : This action routine requires a ButtonPress event.");
  5554.     return;
  5555.   }
  5556.  
  5557.   if (*num_params != 1) {
  5558.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5559.           "XGoban - add : This action routine requires one argument.");
  5560.     return;
  5561.   }
  5562.  
  5563.   if (current_node != NULL)
  5564.     switch (current_mode) {
  5565.     case DiagramMode :
  5566.       
  5567.       x = (Position) ((XButtonPressedEvent *) event)->x;
  5568.       y = (Position) ((XButtonPressedEvent *) event)->y;
  5569.       
  5570.       if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE ) {
  5571.     
  5572.     switch (params[0][0]) {
  5573.     case 'B' : case 'b' : AddStone (x, y, SG_BlackStone); GbSetPoint (w_goban, x, y, GbBlackStone); break;
  5574.     case 'W' : case 'w' : AddStone (x, y, SG_WhiteStone); GbSetPoint (w_goban, x, y, GbWhiteStone); break;
  5575.     case 'E' : case 'e' : AddStone (x, y, SG_EmptyPoint); GbSetPoint (w_goban, x, y, GbEmptyPoint); break;
  5576.     default :
  5577.       XtAppWarning (XtWidgetToApplicationContext (w), 
  5578.             "XGoban - add : Argument should be Black, White or Empty.");
  5579.       return;
  5580.     }
  5581.     
  5582.     modified = True;
  5583.     RedisplayBoard ();
  5584.       }
  5585.       
  5586.       else if (beep >= -100)
  5587.     XBell (XtDisplay (w), beep);
  5588.     }
  5589. }
  5590.  
  5591. /*******************************************************************************************************
  5592.  */
  5593.  
  5594. /* ARGSUSED */
  5595.  
  5596. void SetPlayer (w, event, params, num_params)
  5597. Widget    w;
  5598. XEvent   *event;
  5599. String   *params;
  5600. Cardinal *num_params;
  5601. {
  5602.   int player;
  5603.  
  5604.   if (*num_params != 1) {
  5605.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5606.           "XGoban - player : This action routine requires one argument.");
  5607.     return;
  5608.   }
  5609.  
  5610.   if (current_node != NULL)
  5611.     switch (current_mode) {
  5612.     case EditMode :
  5613.     case MailMode :
  5614.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5615.  
  5616.       switch (params[0][0]) {
  5617.       case 'B' : case 'b' : player = SG_BlackStone; break;
  5618.       case 'W' : case 'w' : player = SG_WhiteStone; break;
  5619.       default  :
  5620.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5621.               "XGoban - player : Argument should be Black or White.");
  5622.     return;
  5623.       }
  5624.       
  5625.       if (strict == True) {
  5626.     if (current_node->type == SG_MoveType) {
  5627.       PopupDialog (w, event, PlayerNodeErrorWarning);
  5628.       return;
  5629.     }
  5630.     
  5631.     else if (current_node->down != NULL) {
  5632.       PopupDialog (w, event, PlayerMoveErrorWarning);
  5633.       return;
  5634.     }
  5635.       }
  5636.       
  5637.       HideProperty     (current_node);
  5638.       
  5639.       current_node->player = player;
  5640.       modified             = True;
  5641.       
  5642.       ShowProperty   (current_node);
  5643.       RedisplayBoard ();
  5644.     }
  5645. }
  5646.  
  5647. /*******************************************************************************************************
  5648.  */
  5649.  
  5650. /* ARGSUSED */
  5651.  
  5652. void Letter (w, event, params, num_params)
  5653. Widget    w;
  5654. XEvent   *event;
  5655. String   *params;
  5656. Cardinal *num_params;
  5657. {
  5658.   unsigned char  letter[3];
  5659.   Position       x;
  5660.   Position       y;
  5661.   
  5662.   if (event->type != ButtonPress) {
  5663.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5664.           "XGoban - letter : This action routine requires a ButtonPress event.");
  5665.     return;
  5666.   }
  5667.  
  5668.   if (current_node != NULL)
  5669.     switch (current_mode) {
  5670.     case EditMode :
  5671.     case MailMode :
  5672.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5673.  
  5674.       x = (Position) ((XButtonPressedEvent *) event)->x;
  5675.       y = (Position) ((XButtonPressedEvent *) event)->y;
  5676.  
  5677.       if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  5678.     
  5679.     letter[0] = x;
  5680.     letter[1] = y;
  5681.     letter[2] = SG_EOS;
  5682.     
  5683.     HideTmpProperty  (current_node);
  5684.     SG_MakeProperty  (current_node, SG_Letters, letter);
  5685.     ShowTmpProperty  (current_node);
  5686.     RedisplayBoard   ();
  5687.     
  5688.     modified = True;
  5689.       }
  5690.       
  5691.       else if (beep >= -100)
  5692.     XBell (XtDisplay (w), beep);
  5693.     }
  5694. }
  5695.  
  5696. /*******************************************************************************************************
  5697.  */
  5698.  
  5699. /* ARGSUSED */
  5700.  
  5701. void Mark (w, event, params, num_params)
  5702. Widget    w;
  5703. XEvent   *event;
  5704. String   *params;
  5705. Cardinal *num_params;
  5706. {
  5707.   unsigned char  mark[3];
  5708.   Position       x;
  5709.   Position       y;
  5710.   
  5711.   if (event->type != ButtonPress) {
  5712.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5713.           "XGoban - mark : This action routine requires a ButtonPress event.");
  5714.     return;
  5715.   }
  5716.  
  5717.   if (current_node != NULL)
  5718.     switch (current_mode) {
  5719.     case EditMode :
  5720.     case MailMode :
  5721.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5722.       
  5723.       x = (Position) ((XButtonPressedEvent *) event)->x;
  5724.       y = (Position) ((XButtonPressedEvent *) event)->y;
  5725.       
  5726.       if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  5727.     
  5728.     mark[0] = x;
  5729.     mark[1] = y;
  5730.     mark[2] = SG_EOS;
  5731.     
  5732.     HideTmpProperty  (current_node);
  5733.     SG_MakeProperty  (current_node, SG_Marked, mark);
  5734.     ShowTmpProperty  (current_node);
  5735.     RedisplayBoard   ();
  5736.     
  5737.     modified = True;
  5738.       }
  5739.       
  5740.       else if (beep >= -100)
  5741.     XBell (XtDisplay (w), beep);
  5742.     }
  5743. }
  5744.  
  5745. /*******************************************************************************************************
  5746.  */
  5747.  
  5748. /* ARGSUSED */
  5749.  
  5750. void DeleteMark (w, event, params, num_params)
  5751. Widget    w;
  5752. XEvent   *event;
  5753. String   *params;
  5754. Cardinal *num_params;
  5755. {
  5756.   SG_PropertyPtr  property;
  5757.   unsigned char  *ptr;
  5758.   Position        x;
  5759.   Position        y;
  5760.   
  5761.   if (event->type != ButtonPress) {
  5762.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5763.           "XGoban - deleteMark : This action routine requires a ButtonPress event.");
  5764.     return;
  5765.   }
  5766.  
  5767.   if (current_node != NULL)
  5768.     switch (current_mode) {
  5769.     case EditMode :
  5770.     case MailMode :
  5771.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5772.       
  5773.       x = (Position) ((XButtonPressedEvent *) event)->x;
  5774.       y = (Position) ((XButtonPressedEvent *) event)->y;
  5775.       
  5776.       if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  5777.     
  5778.     HideTmpProperty (current_node);
  5779.     
  5780.     property = SG_GetProperty (current_node, SG_Letters);
  5781.     
  5782.     if (property != NULL && (ptr = property->data.pvalue) != NULL) {
  5783.       
  5784.       while (*ptr != SG_EOS) {
  5785.         if ((*ptr & 0x3f) == x && (*(ptr + 1) & 0x3f) == y) {
  5786.           *ptr     = *(ptr + 1) = 0;
  5787.           modified = True;
  5788.         }
  5789.         ptr += 2;
  5790.       }
  5791.     }
  5792.     
  5793.     property = SG_GetProperty (current_node, SG_Marked);
  5794.     
  5795.     if (property != NULL && (ptr = property->data.pvalue) != NULL) {
  5796.       
  5797.       while (*ptr != SG_EOS) {
  5798.         if ((*ptr & 0x3f) == x && (*(ptr + 1) & 0x3f) == y) {
  5799.           *ptr     = *(ptr + 1) = 0;
  5800.           modified = True;
  5801.         }
  5802.         ptr += 2;
  5803.       }
  5804.     }
  5805.     
  5806.     ShowTmpProperty  (current_node);
  5807.     RedisplayBoard   ();
  5808.       }
  5809.       
  5810.       else if (beep >= -100)
  5811.     XBell (XtDisplay (w), beep);
  5812.     }
  5813. }
  5814.  
  5815. /*******************************************************************************************************
  5816.  */
  5817.  
  5818. Boolean delete_confirm = False;
  5819.  
  5820. /* ARGSUSED */
  5821.  
  5822. void DeleteMove (w, event, params, num_params)
  5823. Widget    w;
  5824. XEvent   *event;
  5825. String   *params;
  5826. Cardinal *num_params;
  5827. {
  5828.   SG_NodePtr node   = current_node;
  5829.   Boolean    replay = False;
  5830.  
  5831.   if (current_node != NULL)
  5832.     switch (current_mode) {
  5833.     case EditMode :
  5834.     case MailMode :
  5835.       if (edit           == False) { PopupDialog (w, event, EditDialog        ); return; }
  5836.       if (delete_confirm == False) { PopupDialog (w, event, ReallyDeleteDialog); return; }
  5837.       
  5838.       delete_confirm = False;
  5839.       
  5840.       Unplay        (node);
  5841.       HideProperty  (node);
  5842.       
  5843.       if (node->left != NULL)
  5844.     { current_node = node->left ; replay = True; }
  5845.       else if (node->right != NULL)
  5846.     { current_node = node->right; replay = True; }
  5847.       else if (node->up != NULL) 
  5848.     current_node = node->up;
  5849.       else
  5850.     tree = current_node = NULL;
  5851.       
  5852.       SG_RemoveNode (node);
  5853.       SG_FreeNode   (node);
  5854.       
  5855.       if (tree == NULL)
  5856.     { current_node = tree = SG_MakeNode ((SG_NodePtr) NULL, SG_Event); replay = True; }
  5857.       
  5858.       if (replay == True) {
  5859.     Play             (current_node);
  5860.     ShowProperty     (current_node);
  5861.       }
  5862.       
  5863.       else 
  5864.     ShowTmpProperty (current_node);
  5865.       
  5866.       RedisplayBoard ();
  5867.       
  5868.       modified = True;
  5869.  
  5870.       if (current_mode == MailMode) {
  5871.     Edit (False);
  5872.     edit = True;
  5873.       }
  5874.     }
  5875. }
  5876.  
  5877. /*******************************************************************************************************
  5878.  */
  5879.  
  5880. /* ARGSUSED */
  5881.  
  5882. void Pass (w, event, params, num_params)
  5883. Widget    w;
  5884. XEvent   *event;
  5885. String   *params;
  5886. Cardinal *num_params;
  5887. {
  5888.   SG_NodePtr node;
  5889.  
  5890.   if (current_node != NULL) {
  5891.     switch (current_mode) {
  5892.     case EditMode :
  5893.     case MailMode :
  5894.       if (edit == False) { PopupDialog (w, event, EditDialog); return; }
  5895.  
  5896.       if (current_node->down == NULL) 
  5897.     goto play_move;
  5898.       else
  5899.     PopupDialog (w, event, ReplaceNodeDialog);
  5900.       break;
  5901.  
  5902.     case PlayMode :
  5903.       if ((current_node->player == SG_BlackStone && black_player == Human) ||
  5904.       (current_node->player == SG_WhiteStone && white_player == Human))
  5905.         goto play_move;
  5906.       break;
  5907.     }
  5908.     return;
  5909.  
  5910.    play_move :
  5911.     HideTmpProperty (current_node);
  5912.     
  5913.     node         = SG_MakeNode (current_node, SG_Move);
  5914.     node->x      = 0;
  5915.     node->y      = 0;
  5916.     node->color  = current_node->player;
  5917.     
  5918.     Play (node);
  5919.     
  5920.     modified     = True;
  5921.     current_node = node;
  5922.  
  5923.     ShowProperty   (current_node);
  5924.     RedisplayBoard ();
  5925.  
  5926.     switch (current_mode) {
  5927.     case PlayMode : signalMove (node); break;
  5928.     case MailMode : Edit (True); break;
  5929.     }
  5930.   }
  5931. }
  5932.  
  5933. /*******************************************************************************************************
  5934.  */
  5935.  
  5936. /* ARGSUSED */
  5937.  
  5938. void MakeMove (w, event, params, num_params)
  5939. Widget    w;
  5940. XEvent   *event;
  5941. String   *params;
  5942. Cardinal *num_params;
  5943. {
  5944.   SG_NodePtr    node;
  5945.   int           player;
  5946.   int           play;
  5947.   Position      x;
  5948.   Position      y;
  5949.  
  5950.   if (event->type != ButtonPress) {
  5951.     XtAppWarning (XtWidgetToApplicationContext (w), 
  5952.           "XGoban - makeMove : This action routine requires a ButtonPress event.");
  5953.     return;
  5954.   }
  5955.  
  5956.   if (current_node != NULL)
  5957.     switch (current_mode) {
  5958.     case EditMode :
  5959.     case MailMode :
  5960.       if (edit               == False) { PopupDialog (w, event, EditDialog       ); return; }
  5961.       if (current_node->down != NULL ) { PopupDialog (w, event, ReplaceNodeDialog); return; }
  5962.  
  5963.       goto play_move;
  5964.  
  5965.     case PlayMode :
  5966.       if (current_node->player == SG_BlackStone && black_player != Human) break;
  5967.       if (current_node->player == SG_WhiteStone && white_player != Human) break;
  5968.       if (w_second_toplevel != NULL) {
  5969.     if (w == w_second_goban && current_node->player != second_player) break;
  5970.     if (w == w_goban        && current_node->player == second_player) break;
  5971.       }
  5972.  
  5973.       goto play_move;
  5974.     }
  5975.  
  5976.   if (beep >= -100)
  5977.     XBell (XtDisplay (w_goban), beep);
  5978.  
  5979.   return;
  5980.  
  5981.  play_move :
  5982.   x = (Position) ((XButtonPressedEvent *) event)->x;
  5983.   y = (Position) ((XButtonPressedEvent *) event)->y;
  5984.   
  5985.   if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  5986.     
  5987.     HideTmpProperty (current_node);
  5988.     
  5989.     player = current_node->player;
  5990.     node   =  SG_MakeNode (current_node, SG_Move);
  5991.     
  5992.     node->x     = x;
  5993.     node->y     = y;
  5994.     node->color = player;
  5995.     
  5996.     play = Play (node);
  5997.     
  5998.     switch (play) {
  5999.     case SG_PlayIllegal : PopupDialog (w, event, IllegalMoveDialog); break;
  6000.     case SG_PlayKo      : PopupDialog (w, event, KoMoveDialog     ); break;
  6001.     case SG_PlaySuicide : PopupDialog (w, event, SuicideMoveDialog); break;
  6002.     }
  6003.     
  6004.     if (play != SG_OK) {
  6005.       SG_RemoveNode   (node);
  6006.       SG_FreeNode     (node);
  6007.       ShowTmpProperty (current_node);
  6008.     }
  6009.     
  6010.     else {
  6011.       modified     = True;
  6012.       current_node = node;
  6013.  
  6014.       ShowProperty   (current_node);
  6015.       RedisplayBoard ();
  6016.  
  6017.       switch (current_mode) {
  6018.       case PlayMode : signalMove (node); break;
  6019.       case MailMode : Edit (True); break;
  6020.       }
  6021.     }
  6022.   }
  6023.  
  6024.   else if (beep >= -100)
  6025.     XBell (XtDisplay (w_goban), beep);
  6026. }
  6027.  
  6028. /*******************************************************************************************************
  6029.  */
  6030.  
  6031. /* ARGSUSED */
  6032.  
  6033. void MakeVariation (w, event, params, num_params)
  6034. Widget    w;
  6035. XEvent   *event;
  6036. String   *params;
  6037. Cardinal *num_params;
  6038. {
  6039.   SG_NodePtr   tmp = current_node;
  6040.   SG_NodePtr   node;
  6041.   int          player;
  6042.   int          play;
  6043.   Position     x;
  6044.   Position     y;
  6045.  
  6046.   if (event->type != ButtonPress) {
  6047.     XtAppWarning (XtWidgetToApplicationContext (w), 
  6048.           "XGoban - makeVariation : This action routine requires a ButtonPress event.");
  6049.     return;
  6050.   }
  6051.  
  6052.   if (current_node != NULL)
  6053.     switch (current_mode) {
  6054.     case EditMode :
  6055.     case MailMode :
  6056.  
  6057.       if (current_node->type != SG_EventType) {
  6058.     
  6059.     x = (Position) ((XButtonPressedEvent *) event)->x;
  6060.     y = (Position) ((XButtonPressedEvent *) event)->y;
  6061.     
  6062.     if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  6063.       
  6064.       tmp = current_node;
  6065.       while (tmp->left != NULL) tmp = tmp->left;
  6066.       
  6067.       player = tmp->up->player;
  6068.       
  6069.       tmp = current_node;
  6070.       while (tmp->left != NULL) tmp = tmp->left;
  6071.       
  6072.       while (tmp != NULL) {
  6073.         if (tmp->type == SG_MoveType && tmp->color == player &&
  6074.         (Position) tmp->x == x && (Position) tmp->y == y)
  6075.           return;
  6076.         
  6077.         tmp = tmp->right;
  6078.       }
  6079.       
  6080.       HideProperty (current_node);
  6081.       Unplay       (current_node);
  6082.       
  6083.       node =  SG_MakeNode (current_node, SG_VariationMove);
  6084.       
  6085.       node->x     = x;
  6086.       node->y     = y;
  6087.       node->color = player;
  6088.       
  6089.       play = Play (node);
  6090.       
  6091.       switch (play) {
  6092.       case SG_PlayIllegal : PopupDialog (w, event, IllegalMoveDialog); break;
  6093.       case SG_PlayKo      : PopupDialog (w, event, KoMoveDialog     ); break;
  6094.       case SG_PlaySuicide : PopupDialog (w, event, SuicideMoveDialog); break;
  6095.         
  6096.       }
  6097.       
  6098.       if (play != SG_OK) {
  6099.         SG_RemoveNode (node);
  6100.         SG_FreeNode   (node);
  6101.         Play          (current_node);
  6102.         ShowProperty  (current_node);
  6103.       }
  6104.       
  6105.       else {
  6106.         modified     = True;
  6107.         current_node = node;
  6108.         ShowProperty   (current_node);
  6109.         RedisplayBoard ();
  6110.       }
  6111.     }
  6112.       }
  6113.     }
  6114. }
  6115.  
  6116. /*******************************************************************************************************
  6117.  */
  6118.  
  6119. /* ARGSUSED */
  6120.  
  6121. void MakeVariationPass (w, event, params, num_params)
  6122. Widget    w;
  6123. XEvent   *event;
  6124. String   *params;
  6125. Cardinal *num_params;
  6126. {
  6127.   SG_NodePtr   tmp = current_node;
  6128.   SG_NodePtr   node;
  6129.   int          player;
  6130.   Position     x;
  6131.   Position     y;
  6132.  
  6133.   if (current_node != NULL)
  6134.     switch (current_mode) {
  6135.     case EditMode :
  6136.     case MailMode :
  6137.  
  6138.       if (current_node->type != SG_EventType) {
  6139.     
  6140.     x = 0;
  6141.     y = 0;
  6142.       
  6143.     tmp = current_node;
  6144.     while (tmp->left != NULL) tmp = tmp->left;
  6145.       
  6146.     player = tmp->up->player;
  6147.       
  6148.     tmp = current_node;
  6149.     while (tmp->left != NULL) tmp = tmp->left;
  6150.       
  6151.     while (tmp != NULL) {
  6152.       if (tmp->type == SG_MoveType && tmp->color == player &&
  6153.           (Position) tmp->x == x && (Position) tmp->y == y)
  6154.         return;
  6155.         
  6156.       tmp = tmp->right;
  6157.     }
  6158.       
  6159.     HideProperty (current_node);
  6160.     Unplay       (current_node);
  6161.     
  6162.     node =  SG_MakeNode (current_node, SG_VariationMove);
  6163.     
  6164.     node->x     = x;
  6165.     node->y     = y;
  6166.     node->color = player;
  6167.     
  6168.     (void) Play (node);
  6169.  
  6170.     current_node = node;
  6171.     modified     = True;
  6172.  
  6173.     ShowProperty   (current_node);
  6174.     RedisplayBoard ();
  6175.       }
  6176.     }
  6177. }
  6178.  
  6179. /*******************************************************************************************************
  6180.  */
  6181.  
  6182. static Dimension size;
  6183. static Position  top;
  6184. static Position  left;
  6185. static Position  bottom;
  6186. static Position  right;
  6187.  
  6188. static Position  u_top;
  6189. static Position  u_left;
  6190. static Position  u_bottom;
  6191. static Position  u_right;
  6192.  
  6193. /* ARGSUSED */
  6194.  
  6195. void SetMode (w, event, params, num_params)
  6196. Widget    w;
  6197. XEvent   *event;
  6198. String   *params;
  6199. Cardinal *num_params;
  6200. {
  6201.   Mode           md;
  6202.   Arg            args[8];
  6203.   unsigned char *ptr = NULL;
  6204.  
  6205.   if (current_node != NULL) {
  6206.     if (*num_params != 1) {
  6207.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6208.             "XGoban - mode : This action routine requires one argument.");
  6209.       return;
  6210.     }
  6211.  
  6212.     switch (params[0][0]) {
  6213.     case 'E' : case 'e' : md = EditMode   ; break;
  6214.     case 'D' : case 'd' : md = DiagramMode; break;
  6215.     case 'S' : case 's' : md = SizeMode   ; break;
  6216.     case 'V' : case 'v' : md = ViewMode   ; break;
  6217.     default  :
  6218.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6219.             "XGoban - mode : Argument should be Edit, Read, View, Diagram or Size.");
  6220.       return;
  6221.     }
  6222.  
  6223.     if (md != EditMode && edit         == False   ) { PopupDialog (w, event, EditDialog    ); return; }
  6224.     
  6225.     switch (md) {
  6226.     case EditMode :
  6227.  
  6228.       switch (current_mode) {
  6229.  
  6230.       case SizeMode :
  6231.     XtSetArg (args[0], XtNgameSize  , (XtArgVal) size);
  6232.     XtSetValues (w_goban, args, 1);
  6233.  
  6234.       case ViewMode :
  6235.  
  6236.     XtSetArg (args[0], XtNviewTop   , (XtArgVal) top   );
  6237.     XtSetArg (args[1], XtNviewLeft  , (XtArgVal) left  );
  6238.     XtSetArg (args[2], XtNviewBottom, (XtArgVal) bottom);
  6239.     XtSetArg (args[3], XtNviewRight , (XtArgVal) right );
  6240.     XtSetValues (w_goban, args, 4);
  6241.     
  6242.     RedisplayBoard ();
  6243.     break;
  6244.  
  6245.       case DiagramMode :
  6246.     ptr = EndDiagram ();
  6247.  
  6248.     if (ptr != NULL) {
  6249.  
  6250.       current_node->setup = ptr;
  6251.  
  6252.       Play (current_node);
  6253.       ShowProperty (current_node);
  6254.     }
  6255.     break;
  6256.  
  6257.       default :
  6258.     if (beep >= -100) 
  6259.       XBell (XtDisplay (w_goban), beep); 
  6260.     return;
  6261.       }
  6262.       
  6263.       md = (mail_node == NULL) ? EditMode : MailMode;
  6264.  
  6265.       break;
  6266.  
  6267.     case DiagramMode   : 
  6268.       if (current_mode != EditMode && current_mode != MailMode) 
  6269.     { if (beep >= -100) XBell (XtDisplay (w_goban), beep); return; }
  6270.       if (current_node->type == SG_MoveType) 
  6271.     { PopupDialog (w, event, DiagramBadNodeWarning); return; }
  6272.       
  6273.       Unplay (current_node);
  6274.       StartDiagram ();
  6275.       Play (current_node);
  6276.     
  6277.       break;
  6278.     
  6279.     case SizeMode      : 
  6280.       if (current_mode != EditMode) { if (beep >= -100) XBell (XtDisplay (w_goban), beep); return; }
  6281.       if (current_node->type  != SG_EventType) { PopupDialog (w, event, SizeBadNodeWarning); return; }
  6282.       if (current_node->down  != NULL        ) { PopupDialog (w, event, RemoveStonesDialog); return; }
  6283.  
  6284.       HideProperty (current_node);
  6285.       Unplay       (current_node);
  6286.  
  6287.       free (current_node->setup);
  6288.       current_node->setup = NULL;
  6289.  
  6290.       RedisplayBoard ();
  6291.  
  6292.       break;
  6293.     
  6294.     case ViewMode      : 
  6295.       if (current_mode != EditMode && current_mode != MailMode)
  6296.     { if (beep >= -100) XBell (XtDisplay (w_goban), beep); return; }
  6297.  
  6298.       XtSetArg (args[0], XtNgameSize  , (XtArgVal) &size);
  6299.       XtGetValues (w_goban, args, 1);
  6300.  
  6301.       XtSetArg (args[0], XtNviewTop   , (XtArgVal) &top   );
  6302.       XtSetArg (args[1], XtNviewLeft  , (XtArgVal) &left  );
  6303.       XtSetArg (args[2], XtNviewBottom, (XtArgVal) &bottom);
  6304.       XtSetArg (args[3], XtNviewRight , (XtArgVal) &right );
  6305.       XtGetValues (w_goban, args, 4);
  6306.    
  6307.       HideProperty (current_node);
  6308.  
  6309.       XtSetArg (args[0], XtNviewTop   , (XtArgVal) &u_top   );
  6310.       XtSetArg (args[1], XtNviewLeft  , (XtArgVal) &u_left  );
  6311.       XtSetArg (args[2], XtNviewBottom, (XtArgVal) &u_bottom);
  6312.       XtSetArg (args[3], XtNviewRight , (XtArgVal) &u_right );
  6313.       XtGetValues (w_goban, args, 4);
  6314.     
  6315.       ShowProperty (current_node);
  6316.  
  6317.       XtSetArg (args[0], XtNviewTop   , (XtArgVal) size);
  6318.       XtSetArg (args[1], XtNviewLeft  , (XtArgVal) 1   );
  6319.       XtSetArg (args[2], XtNviewBottom, (XtArgVal) 1   );
  6320.       XtSetArg (args[3], XtNviewRight , (XtArgVal) size);
  6321.       XtSetValues (w_goban, args, 4);
  6322.       
  6323.       RedisplayBoard ();
  6324.       break;
  6325.     
  6326.       default :
  6327.     return;
  6328.     }
  6329.  
  6330.     current_mode = md;
  6331.  
  6332.     ShowCursor (current_node);
  6333.   }
  6334. }
  6335.  
  6336. /*******************************************************************************************************
  6337.  *
  6338.  *    Drag a rectangle on screen to set property SiZe or VieW.
  6339.  *    Must be called by user as 'drag(Start)' 'drag()' and 'drag(Stop)'.
  6340.  */
  6341.  
  6342. static Position x0;
  6343. static Position y0;
  6344. static Position x1;
  6345. static Position y1;
  6346.  
  6347. static int      drag_in_progress = 0;
  6348. static GC       drag_gc;
  6349.  
  6350. void Drag (w, event, params, num_params)
  6351. Widget    w;
  6352. XEvent   *event;
  6353. String   *params;
  6354. Cardinal *num_params;
  6355. {
  6356.   static Boolean  gc_created = False;
  6357.  
  6358.   int             size;
  6359.   Arg             args[4];
  6360.   Position        x;
  6361.   Position        y;
  6362.   Position        xmax;
  6363.   Position        ymax;
  6364.   Dimension       point_size;
  6365.   long            value;
  6366.  
  6367.   if (current_mode == SizeMode || current_mode == ViewMode) {
  6368.     
  6369.     if (event->type != MotionNotify && event->type != ButtonPress && event->type != ButtonRelease) {
  6370.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6371.             "XGoban - drag : This action routine requires a button event.");
  6372.       return;
  6373.     }
  6374.  
  6375.     if (gc_created == False) {
  6376.       XGCValues      values;
  6377.  
  6378.       values.function = GXinvert;
  6379.       drag_gc         = XCreateGC (XtDisplay (w_goban), XtWindow (w_goban), GCFunction, &values);
  6380.       gc_created      = True;
  6381.     }
  6382.  
  6383.     switch (*num_params) {
  6384.  
  6385.     case 0 :
  6386.     
  6387.     /*
  6388.      *   drag() : erase previous rectangle, update coordinates and redraw rectangle on screen.
  6389.      */
  6390.  
  6391.       if (event->type != MotionNotify) {
  6392.     XtAppWarning (XtWidgetToApplicationContext (w), 
  6393.               "XGoban - drag() : This action routine requires a MotionNotify event.");
  6394.     return;
  6395.       }
  6396.  
  6397.       if (drag_in_progress == 1) {
  6398.  
  6399.     x = (Position) ((XButtonEvent *) event)->x;
  6400.     y = (Position) ((XButtonEvent *) event)->y;
  6401.     
  6402.     if (GbGetStoneFromPosition (w_goban, &x, &y) != TRUE) return;
  6403.       
  6404.     xmax = 19;
  6405.     ymax = 1;
  6406.  
  6407.     GbGetPositionFromStone (w_goban, &x   , &y   );
  6408.     GbGetPositionFromStone (w_goban, &xmax, &ymax);
  6409.     
  6410.     if (x > x0 && y > y0 && (x != x1 || y != y1)) {
  6411.       
  6412.       XtSetArg (args[0], XtNpointSize, &point_size);
  6413.       XtGetValues (w_goban, args, 1);
  6414.       
  6415.       if (x0 != x1 || y0 != y1)
  6416.         XDrawRectangle (XtDisplay (w), XtWindow (w), drag_gc, 
  6417.                 x0 - point_size / 2, y0 - point_size / 2, 
  6418.                 x1 - x0 + point_size, y1 - y0 + point_size);
  6419.             
  6420.       if (current_mode == SizeMode) {
  6421.         x = x0 + Min (xmax - x0, Min (ymax - y0, Max (x - x0, y - y0)));
  6422.         y = y0 + Min (xmax - x0, Min (ymax - y0, Max (x - x0, y - y0)));
  6423.       }
  6424.       
  6425.       x1 = x;
  6426.       y1 = y;
  6427.     
  6428.       XDrawRectangle (XtDisplay (w), XtWindow (w), drag_gc, 
  6429.               x0 - point_size / 2, y0 - point_size / 2, 
  6430.               x1 - x0 + point_size, y1 - y0 + point_size);
  6431.  
  6432.       XFlush (XtDisplay (w));
  6433.     }
  6434.       }
  6435.       break;
  6436.  
  6437.     case 1 :
  6438.  
  6439.       switch (params[0][2]) {
  6440.  
  6441.       case 'A' : 
  6442.       case 'a' :
  6443.     
  6444.     /*
  6445.      *   drag(Start) : initialize rectangle (x0 y0 x1 y1).
  6446.      */
  6447.  
  6448.     if (event->type != ButtonPress) {
  6449.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6450.             "XGoban - drag(Start) : This action routine requires a ButtonPress event.");
  6451.       return;
  6452.     }
  6453.  
  6454.     x = (Position) ((XButtonEvent *) event)->x;
  6455.     y = (Position) ((XButtonEvent *) event)->y;
  6456.     
  6457.     if (GbGetStoneFromPosition (w_goban, &x, &y) == TRUE) {
  6458.     
  6459.       GbGetPositionFromStone (w_goban, &x, &y);
  6460.     
  6461.       x1 = x0 = x;
  6462.       y1 = y0 = y;
  6463.       
  6464.       XtSetArg (args[0], XtNcursor, XC_bottom_right_corner);
  6465.       XtSetValues (w_goban, args, 1);
  6466.       
  6467.       drag_in_progress = 1;
  6468.     }
  6469.     break;
  6470.   
  6471.       case 'O' : 
  6472.       case 'o' :
  6473.     
  6474.     /*
  6475.      *   drag(Stop) : erase rectangle on screen and create desired property.
  6476.      */
  6477.  
  6478.     if (event->type != ButtonRelease) {
  6479.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6480.             "XGoban - drag(Stop) : This action routine requires a ButtonRelease event.");
  6481.       return;
  6482.     }
  6483.       
  6484.     if (drag_in_progress == 1) {
  6485.       XtSetArg (args[0], XtNpointSize, &point_size);
  6486.       XtGetValues (w_goban, args, 1);
  6487.     
  6488.       XDrawRectangle (XtDisplay (w), XtWindow (w), drag_gc, 
  6489.               x0 - point_size / 2, y0 - point_size / 2, 
  6490.               x1 - x0 + point_size, y1 - y0 + point_size);
  6491.     
  6492.       GbGetStoneFromPosition (w_goban, &x0, &y0);
  6493.       GbGetStoneFromPosition (w_goban, &x1, &y1);
  6494.  
  6495.       size = Max (x1 - x0 + 1, y0 - y1 + 1);
  6496.     
  6497.       switch (current_mode) {
  6498.  
  6499.         /*        
  6500.          *   Create SiZe property.
  6501.          */
  6502.  
  6503.       case SizeMode :
  6504.       
  6505.         if (size > 1 && size < 20) {
  6506.           XtSetArg (args[0], XtNgameSize , (XtArgVal) size);
  6507.           XtSetValues (w_goban, args, 1);
  6508.  
  6509.           value = ((long) size << 24) + (1 << 16) + (1 << 8) + (long) size;
  6510.  
  6511.           SG_MakeProperty (current_node, SG_SiZe, size );
  6512.           SG_MakeProperty (current_node, SG_VieW, value);
  6513.  
  6514.           modified = True;
  6515.         }
  6516.  
  6517.         break;
  6518.  
  6519.         /*        
  6520.          *   Create VieW property.
  6521.          */
  6522.       
  6523.       case ViewMode :
  6524.         
  6525.         if (y0 > y1 && x1 > x0) {
  6526.    
  6527.           XtSetArg (args[0], XtNviewTop   , (XtArgVal) y0);
  6528.           XtSetArg (args[1], XtNviewLeft  , (XtArgVal) x0);
  6529.           XtSetArg (args[2], XtNviewBottom, (XtArgVal) y1);
  6530.           XtSetArg (args[3], XtNviewRight , (XtArgVal) x1);
  6531.           XtSetValues (w_goban, args, 4);
  6532.  
  6533.           value = ((long) u_top << 24) + ((long) u_left << 16) + ((long) u_bottom << 8) + (long) u_right;
  6534.           SG_MakeProperty (current_node, SG_unVieW, value);
  6535.  
  6536.           value = ((long) y0    << 24) + ((long) x0     << 16) + ((long) y1       << 8) + (long) x1     ;
  6537.           SG_MakeProperty (current_node, SG_VieW  , value);
  6538.  
  6539.           modified = True;
  6540.         }
  6541.         break;
  6542.       }
  6543.     }
  6544.  
  6545.     /*        
  6546.      *   Redisplay current node.
  6547.      */
  6548.  
  6549.     current_mode     = (mail_node == NULL) ? EditMode : MailMode;
  6550.     drag_in_progress = 0;
  6551.  
  6552.     ShowCursor     (current_node);
  6553.     RedisplayBoard ();
  6554.     break;
  6555.  
  6556.       default  :
  6557.     XtAppWarning (XtWidgetToApplicationContext (w), 
  6558.               "XGoban - drag : Argument should be Start or Stop.");
  6559.     return;
  6560.       }
  6561.       break;
  6562.  
  6563.     default :
  6564.       XtAppWarning (XtWidgetToApplicationContext (w), 
  6565.             "XGoban - drag : This action routine requires one or no argument.");
  6566.       return;
  6567.     }
  6568.   }
  6569. }
  6570. SHAR_EOF
  6571. fi # end of overwriting check
  6572. if test -f 'misc.c'
  6573. then
  6574.     echo shar: will not over-write existing file "'misc.c'"
  6575. else
  6576. cat << \SHAR_EOF > 'misc.c'
  6577. /****************************************************************************************************************
  6578.  *
  6579.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  6580.  *
  6581.  *  This program is distributed in the hope that it will be useful.
  6582.  *  Use and copying of this software and preparation of derivative works
  6583.  *  based upon this software are permitted, so long as the following
  6584.  *  conditions are met:
  6585.  *       o credit to the authors is acknowledged following current
  6586.  *         academic behaviour
  6587.  *       o no fees or compensation are charged for use, copies, or
  6588.  *         access to this software
  6589.  *       o this copyright notice is included intact.
  6590.  *  This software is made available AS IS, and no warranty is made about 
  6591.  *  the software or its performance. 
  6592.  * 
  6593.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  6594.  *  Send them to    dumesnil@etca.fr   or to:
  6595.  *       
  6596.  *       Antoine de Maricourt
  6597.  *       ETCA CREA-SP
  6598.  *       16 bis, avenue Prieur de la Cote d'Or
  6599.  *       94114 Arcueil Cedex
  6600.  *       France
  6601.  */
  6602.  
  6603. #include <X11/Intrinsic.h>
  6604. #include <X11/Shell.h>
  6605. #include <X11/StringDefs.h>
  6606.  
  6607. #include <X11/cursorfont.h>
  6608. #include <X11/Xaw/AsciiText.h>
  6609. #include <X11/Xaw/Label.h>
  6610.  
  6611. #include "xgoban.h"
  6612.  
  6613. /*******************************************************************************************************
  6614.  *
  6615.  */
  6616.  
  6617. void CenterWindow (w, button)
  6618. Widget    w;
  6619. Widget    button;
  6620. {
  6621.   Display          *display = XtDisplay (w);
  6622.   Window            root;
  6623.   Window            child;
  6624.   int               rx;
  6625.   int               ry;
  6626.   int               bw;
  6627.   int               ignore;
  6628.   unsigned int      mask;
  6629.   Arg               args[4];
  6630.   Dimension         butw;
  6631.   Dimension         buth;
  6632.   Dimension         width;
  6633.   Dimension         height;
  6634.   Position          x;
  6635.   Position          y;
  6636.   XWindowAttributes attr;
  6637.  
  6638.   if (XtIsRealized (w) == FALSE) XtRealizeWidget (w);
  6639.  
  6640.   XGetWindowAttributes (display, XtWindow (w), &attr);
  6641.   bw = attr.border_width;
  6642.   XGetWindowAttributes (display, RootWindowOfScreen (XtScreen (w)), &attr);
  6643.  
  6644.   XQueryPointer (display, XtWindow (w), &root, &child, &rx, &ry, &ignore, &ignore, &mask);
  6645.  
  6646.   XtSetArg (args[0], XtNwidth , (XtArgVal) &width );
  6647.   XtSetArg (args[1], XtNheight, (XtArgVal) &height);
  6648.  
  6649.   XtGetValues (w, args, 2);
  6650.  
  6651.   if (button != NULL) {
  6652.     XtSetArg (args[0], XtNx      , (XtArgVal) &x    );
  6653.     XtSetArg (args[1], XtNy      , (XtArgVal) &y    );
  6654.     XtSetArg (args[2], XtNwidth  , (XtArgVal) &butw );
  6655.     XtSetArg (args[3], XtNheight , (XtArgVal) &buth );
  6656.  
  6657.     XtGetValues (button, args, 4);
  6658.  
  6659.     rx = rx - x - 3 * butw / 4;
  6660.     ry = ry - y - 2 * buth / 3;
  6661.   }
  6662.  
  6663.   else {
  6664.     rx = rx - width  / 2;
  6665.     ry = ry - height / 2;
  6666.   }
  6667.  
  6668.   rx = (rx < 2) ? 2 : rx;
  6669.   rx = (rx > attr.width  - width  - 2 * bw - 4) ? attr.width  - width  - 2 * bw - 4 : rx;
  6670.  
  6671.   ry = (ry < 2) ? 2 : ry;
  6672.   ry = (ry > attr.height - height - 2 * bw - 4) ? attr.height - height - 2 * bw - 4 : ry;
  6673.  
  6674.   XtMoveWidget (w, rx, ry); 
  6675. }
  6676.  
  6677. /*******************************************************************************************************
  6678.  *
  6679.  */
  6680.  
  6681. void ShowCursor (node)
  6682. SG_NodePtr node;
  6683. {
  6684.   Arg            args[2];
  6685.   int            cursor = XC_question_arrow;
  6686.     
  6687.   switch (current_mode) {
  6688.     
  6689.   case EditMode      :
  6690.   case PlayMode      :
  6691.   case MailMode      :
  6692.     
  6693.     if (node != NULL) {
  6694.       
  6695.       switch (node->type) {
  6696.     
  6697.       case SG_EventType   :
  6698.       case SG_DiagramType :
  6699.     if (node->left != NULL || node->right != NULL)
  6700.       cursor = GbCGrayStone;
  6701.     else
  6702.       cursor = (node->player == SG_BlackStone) ? GbCBlackStone : GbCWhiteStone;
  6703.     break;
  6704.     
  6705.       case SG_MoveType :
  6706.     if (node->left != NULL || node->right != NULL)
  6707.       cursor = GbCGrayStone;
  6708.     else
  6709.       cursor = (node->color == SG_BlackStone) ? GbCWhiteStone : GbCBlackStone;
  6710.     break;
  6711.       }
  6712.     }
  6713.  
  6714.     else
  6715.       cursor =  GbCGrayStone;
  6716.  
  6717.     break;
  6718.     
  6719.   case SizeMode :
  6720.   case ViewMode :
  6721.     cursor =  XC_top_left_corner;
  6722.     break;
  6723.     
  6724.   case DiagramMode :
  6725.     cursor =  XC_dot;
  6726.     break;
  6727.  
  6728.   default :
  6729.     return;
  6730.   }
  6731.   
  6732.   XtSetArg (args[0], XtNcursor, (XtArgVal) cursor);
  6733.   XtSetValues (w_goban,  args, 1);
  6734.  
  6735.   if (w_second_goban != NULL)   
  6736.     XtSetValues (w_second_goban,  args, 1);
  6737. }
  6738.  
  6739. /*******************************************************************************************************
  6740.  *
  6741.  */
  6742.  
  6743. Boolean LoadFile (w, event, name)
  6744. Widget  w;
  6745. XEvent *event;
  6746. char   *name;
  6747. {
  6748.   FILE       *file;
  6749.   SG_NodePtr  node;
  6750.   char        tmp_name[1024];
  6751.   char       *src = path;
  6752.   char       *dst;
  6753.  
  6754.   if (*name == '/') {
  6755.     if ((file = fopen (name, "r")) == NULL)
  6756.       goto failed;
  6757.   }
  6758.   
  6759.   else 
  6760.     do {
  6761.       dst = tmp_name;
  6762.       
  6763.       while (*src != ':' && *src != '\0')
  6764.     *dst++ = *src++;
  6765.       
  6766.       if (*src == '\0' && dst == tmp_name) {
  6767.        failed :
  6768.  
  6769.     if (w != NULL) 
  6770.       PopupDialog (w, event, CantOpenFileDialog);
  6771.     
  6772.     return False;
  6773.       }
  6774.       
  6775.       *dst++ = '/';
  6776.       *dst++ = '\0';
  6777.       
  6778.       if (*src == ':') src++;
  6779.       
  6780.       (void) strcat (tmp_name, name);
  6781.       file = fopen (tmp_name, "r");
  6782.       
  6783.     } while (file == NULL);
  6784.  
  6785.   node = SG_ReadTree (file);
  6786.   fclose (file);
  6787.   
  6788.   if (node != NULL) {
  6789.     do {
  6790.       while (node->up != NULL)
  6791.     node = node->up;
  6792.       while (node->left != NULL)
  6793.     node = node->left;
  6794.     } while (node->up != NULL);
  6795.     
  6796.     SG_FreeNode (tree);
  6797.  
  6798.     tree         = node;
  6799.     current_node = node;
  6800.     modified     = False;
  6801.  
  6802.     (void) strcpy (file_name, tmp_name); 
  6803.   }
  6804.  
  6805.   return True;
  6806. }
  6807.  
  6808. /*******************************************************************************************************
  6809.  */
  6810.  
  6811. Boolean SaveFile (w, event, name)
  6812. Widget  w;
  6813. XEvent *event;
  6814. char   *name;
  6815. {
  6816.   FILE       *file;
  6817.   char        tmp_name[256];
  6818.   int         saved;
  6819.  
  6820.   if (*name != '/')
  6821.     (void) strcpy (tmp_name, "./");
  6822.  
  6823.   (void) strcat (tmp_name, name);
  6824.   file = fopen (tmp_name, "w");
  6825.     
  6826.   if (file == NULL && w != NULL) {
  6827.     PopupDialog (w, event, CantOpenFileDialog);
  6828.     return False;
  6829.   }
  6830.  
  6831.   HideTmpProperty (current_node);
  6832.   ShowTmpProperty (current_node);
  6833.  
  6834.   saved = SG_WriteTree (tree, file, short_print == True ? 1 : 0);
  6835.   fclose (file);
  6836.  
  6837.   if (saved != 0 && w != NULL) {
  6838.     PopupDialog (w, event, CantOpenFileDialog);
  6839.     return False;
  6840.   }
  6841.  
  6842.   (void) strcpy (file_name, name);
  6843.   modified = False;
  6844.  
  6845.   return saved == 0 ? True : False;
  6846. }
  6847.  
  6848. /*******************************************************************************************************
  6849.  */
  6850.  
  6851. void Edit (flag)
  6852. Boolean flag;
  6853. {
  6854.   Arg args[4];
  6855.  
  6856.   if (flag == True) {
  6857.     XtSetArg (args[0], XtNeditType         , (XtArgVal) XawtextEdit        );
  6858.     XtSetArg (args[1], XtNdisplayCaret     , (XtArgVal) True               );
  6859.  
  6860.     XtSetValues (c_comment, args, 2);
  6861.  
  6862.     edit = True;
  6863.   }
  6864.  
  6865.   else {
  6866.     XtSetArg (args[0], XtNeditType         , (XtArgVal) XawtextRead        );
  6867.     XtSetArg (args[1], XtNdisplayCaret     , (XtArgVal) False              );
  6868.  
  6869.     XtSetValues (c_comment, args, 2);
  6870.  
  6871.     edit = False;
  6872.   }
  6873. }
  6874. SHAR_EOF
  6875. fi # end of overwriting check
  6876. if test -f 'display.c'
  6877. then
  6878.     echo shar: will not over-write existing file "'display.c'"
  6879. else
  6880. cat << \SHAR_EOF > 'display.c'
  6881. /****************************************************************************************************************
  6882.  *
  6883.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  6884.  *
  6885.  *  This program is distributed in the hope that it will be useful.
  6886.  *  Use and copying of this software and preparation of derivative works
  6887.  *  based upon this software are permitted, so long as the following
  6888.  *  conditions are met:
  6889.  *       o credit to the authors is acknowledged following current
  6890.  *         academic behaviour
  6891.  *       o no fees or compensation are charged for use, copies, or
  6892.  *         access to this software
  6893.  *       o this copyright notice is included intact.
  6894.  *  This software is made available AS IS, and no warranty is made about 
  6895.  *  the software or its performance. 
  6896.  * 
  6897.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  6898.  *  Send them to    dumesnil@etca.fr   or to:
  6899.  *       
  6900.  *       Antoine de Maricourt
  6901.  *       ETCA CREA-SP
  6902.  *       16 bis, avenue Prieur de la Cote d'Or
  6903.  *       94114 Arcueil Cedex
  6904.  *       France
  6905.  */
  6906.  
  6907. #include "xgoban.h"
  6908.  
  6909. #include <X11/Shell.h>
  6910. #include <X11/Xlib.h>
  6911. #include <X11/Xutil.h>
  6912.  
  6913. /*******************************************************************************************************
  6914.  */
  6915.  
  6916. void ShowTmpProperty (node)
  6917. SG_NodePtr node;
  6918. {
  6919.   SG_NodePtr     tmp;
  6920.   char           mark     = 'A';
  6921.   char           letter   = 'a';
  6922.   Position       x;
  6923.   Position       y;
  6924.   SG_PropertyPtr property;
  6925.   unsigned char *ptr;
  6926.   Arg            arg;
  6927.  
  6928.   if (node != NULL) {
  6929.     property = node->property;
  6930.     
  6931.     while (property != NULL) {
  6932.  
  6933.       switch (property->id) {
  6934.     
  6935.       case SG_Comment :
  6936.     if (property->data.pvalue != NULL)
  6937.       { XtSetArg (arg, XtNstring, (XtArgVal) property->data.pvalue); XtSetValues (c_comment, &arg, 1); }
  6938.     break;
  6939.  
  6940.       case SG_Letters :
  6941.     if ((ptr = property->data.pvalue) != NULL) {
  6942.  
  6943.       while (*ptr != SG_EOS) {
  6944.         x = (*ptr++ & 0x3f);
  6945.         y = (*ptr++ & 0x3f);
  6946.         
  6947.         if (x != 0 || y != 0) {
  6948.           GbSetMark (w_goban, x, y, letter, 0);
  6949.           if (w_second_goban != NULL) 
  6950.         GbSetMark (w_second_goban, x, y, letter, 0);
  6951.           letter++;
  6952.         }
  6953.       }
  6954.     }
  6955.     break;
  6956.  
  6957.       case SG_Marked :
  6958.     if ((ptr = property->data.pvalue) != NULL) {
  6959.  
  6960.       while (*ptr != SG_EOS) {
  6961.         x = (*ptr++ & 0x3f);
  6962.         y = (*ptr++ & 0x3f);
  6963.         
  6964.         if (x != 0 || y != 0) {
  6965.           GbSetMark (w_goban, x, y, 0, GbMTriangleMark);
  6966.           if (w_second_goban != NULL) 
  6967.         GbSetMark (w_second_goban, x, y, 0, GbMTriangleMark);
  6968.         }
  6969.       }
  6970.     }
  6971.     break;
  6972.  
  6973.       case SG_nodeName :
  6974.  
  6975.     if (property->data.pvalue != NULL) {
  6976.       XtSetArg (arg, XtNtitle, (XtArgVal) property->data.pvalue); 
  6977.       XtSetValues (c_toplevel, &arg, 1);
  6978.     }
  6979.     break;
  6980.  
  6981.       case SG_GameName :
  6982.  
  6983.     if (property->data.pvalue != NULL) {
  6984.       XtSetArg (arg, XtNtitle, (XtArgVal) property->data.pvalue); 
  6985.       XtSetValues (w_toplevel, &arg, 1);
  6986.     }
  6987.     break;
  6988.       }
  6989.  
  6990.       property = property->next;
  6991.     }
  6992.  
  6993.     switch (node->type) {
  6994.       
  6995.     case SG_EventType   :
  6996.     case SG_DiagramType :
  6997.       break;
  6998.       
  6999.     case SG_MoveType :
  7000.       tmp = node;
  7001.  
  7002.       while (tmp->left != NULL)
  7003.     tmp = tmp->left;
  7004.       
  7005.       if (tmp->right != NULL)
  7006.     while (tmp != NULL) {
  7007.       if (tmp->type == SG_MoveType && tmp->color == node->color && tmp->x != 0 && tmp->y != 0) {
  7008.         GbSetMark (w_goban, tmp->x, tmp->y, mark, 0);
  7009.         
  7010.         if (w_second_goban != NULL) 
  7011.           GbSetMark (w_second_goban, tmp->x, tmp->y, mark, 0);
  7012.       }
  7013.       
  7014.       mark++;
  7015.       tmp = tmp->right;
  7016.     }
  7017.       
  7018.       else if (autonum == TRUE) {
  7019.     GbSetNum   (w_goban, node->x, node->y, node->num);
  7020.  
  7021.     if (w_second_goban != NULL) 
  7022.       GbSetNum   (w_second_goban, node->x, node->y, node->num);
  7023.       }
  7024.  
  7025.       break;
  7026.     }
  7027.   }
  7028.  
  7029.   ShowCursor (node);
  7030. }
  7031.  
  7032. /*******************************************************************************************************
  7033.  */
  7034.  
  7035. void ShowProperty (node)
  7036. SG_NodePtr node;
  7037. {
  7038.   unsigned char *setup;
  7039.   int            color;
  7040.   int            x;
  7041.   int            y;
  7042.   int            view = 0;
  7043.   SG_PropertyPtr property;
  7044.   Position       top;
  7045.   Position       left;
  7046.   Position       bottom;
  7047.   Position       right;
  7048.   Arg            args[4];
  7049.   long           value;
  7050.  
  7051.   if (node != NULL) {
  7052.     property = node->property;
  7053.     
  7054.     while (property != NULL) {
  7055.       switch (property->id) {
  7056.     
  7057.       case SG_SiZe :
  7058.     XtSetArg (args[0], XtNgameSize, property->data.ivalue); 
  7059.     XtSetValues (w_goban, args, 1);
  7060.     if (w_second_goban != NULL) 
  7061.       XtSetValues (w_second_goban, args, 1);
  7062.     break;
  7063.     
  7064.       case SG_GameName : 
  7065.     if (property->data.pvalue != NULL) {
  7066.       XtSetArg (args[0], XtNtitle, property->data.pvalue); 
  7067.       XtSetValues (w_goban, args, 1);
  7068.       if (w_second_goban != NULL) 
  7069.         XtSetValues (w_second_goban, args, 1);
  7070.     }
  7071.     break;
  7072.     
  7073.       case SG_VieW :
  7074.     XtSetArg (args[0], XtNviewTop   , &top   );
  7075.     XtSetArg (args[1], XtNviewLeft  , &left  );
  7076.     XtSetArg (args[2], XtNviewBottom, &bottom);
  7077.     XtSetArg (args[3], XtNviewRight , &right );
  7078.  
  7079.     XtGetValues (w_goban, args, 4);
  7080.     if (w_second_goban != NULL) 
  7081.       XtGetValues (w_second_goban, args, 4);
  7082.  
  7083.     value = ((long) top << 24) + ((long) left << 16) + ((long) bottom << 8) + ((long) right);
  7084.  
  7085.     SG_MakeProperty (node, SG_unVieW, value);
  7086.     
  7087.     XtSetArg (args[0], XtNviewTop   , (Position) ((property->data.ivalue >> 24))       );
  7088.     XtSetArg (args[1], XtNviewLeft  , (Position) ((property->data.ivalue >> 16) & 0xff));
  7089.     XtSetArg (args[2], XtNviewBottom, (Position) ((property->data.ivalue >>  8) & 0xff));
  7090.     XtSetArg (args[3], XtNviewRight , (Position) ((property->data.ivalue      ) & 0xff));
  7091.     
  7092.     XtSetValues (w_goban, args, 4);
  7093.     if (w_second_goban != NULL) 
  7094.       XtSetValues (w_second_goban, args, 4);
  7095.     
  7096.     view++;
  7097.  
  7098.     break;
  7099.       }
  7100.       
  7101.       property = property->next;
  7102.     }
  7103.     
  7104.     switch (node->type) {
  7105.       
  7106.     case SG_EventType   :
  7107.       GbClearBoard (w_goban);
  7108.       if (w_second_goban != NULL) 
  7109.     GbClearBoard (w_second_goban);
  7110.  
  7111.       if (view == 0) {
  7112.     XtSetArg (args[0], XtNviewTop   , 19);
  7113.     XtSetArg (args[1], XtNviewLeft  ,  0);
  7114.     XtSetArg (args[2], XtNviewBottom,  0);
  7115.     XtSetArg (args[3], XtNviewRight , 19);
  7116.     
  7117.     XtSetValues (w_goban, args, 4);
  7118.     if (w_second_goban != NULL) 
  7119.       XtSetValues (w_second_goban, args, 4);
  7120.       }
  7121.  
  7122.     case SG_DiagramType :
  7123.       if ((setup = node->setup) != NULL)
  7124.     while (*setup != SG_EOS) {
  7125.       color = (*setup & 0xc0);
  7126.       x     = (*setup++ & 0x3f);
  7127.       y     = (*setup++ & 0x3f);
  7128.       
  7129.       switch (color) {
  7130.       case SG_SETB  : GbSetPoint (w_goban, x, y, GbBlackStone); break;
  7131.       case SG_SETW  : GbSetPoint (w_goban, x, y, GbWhiteStone); break;
  7132.       case SG_SETEB :
  7133.       case SG_SETEW : GbSetPoint (w_goban, x, y, GbEmptyPoint); break;
  7134.       }
  7135.  
  7136.       if (w_second_goban != NULL) 
  7137.         switch (color) {
  7138.         case SG_SETB  : GbSetPoint (w_second_goban, x, y, GbBlackStone); break;
  7139.         case SG_SETW  : GbSetPoint (w_second_goban, x, y, GbWhiteStone); break;
  7140.         case SG_SETEB :
  7141.         case SG_SETEW : GbSetPoint (w_second_goban, x, y, GbEmptyPoint); break;
  7142.         }
  7143.     }
  7144.       break;
  7145.       
  7146.     case SG_MoveType :
  7147.       x     = node->x;
  7148.       y     = node->y;
  7149.       color = (int) ((node->color == SG_BlackStone) ? GbBlackStone : GbWhiteStone);
  7150.  
  7151.       GbSetPoint (w_goban, x, y, color);
  7152.       if (w_second_goban != NULL)       
  7153.     GbSetPoint (w_second_goban, x, y, color);
  7154.  
  7155.       if ((setup = node->setup) != NULL)
  7156.     while (*setup != SG_EOS) {
  7157.       x     = (*setup++ & 0x3f);
  7158.       y     = (*setup++ & 0x3f);
  7159.       
  7160.       GbSetPoint (w_goban, x, y, GbEmptyPoint);
  7161.       if (w_second_goban != NULL) 
  7162.         GbSetPoint (w_second_goban, x, y, GbEmptyPoint);
  7163.     }
  7164.     
  7165.       break;
  7166.     }
  7167.     
  7168.     ShowTmpProperty  (node);
  7169.   }
  7170. }
  7171.  
  7172. /*******************************************************************************************************
  7173.  */
  7174.  
  7175. void HideTmpProperty (node)
  7176. SG_NodePtr node;
  7177. {
  7178.   SG_PropertyPtr  property;
  7179.   String          text;
  7180.   unsigned char  *ptr;
  7181.   int             x;
  7182.   int             y;
  7183.   Arg             arg;
  7184.  
  7185.   if (edit == True) {
  7186.     XtSetArg (arg, XtNstring, &text); XtGetValues (c_comment, &arg, 1);
  7187.  
  7188.     if (node != NULL) {
  7189.       property = SG_GetProperty (node, SG_Comment);
  7190.  
  7191.       if (property != NULL && strcmp (property->data.pvalue, text) != 0) {
  7192.     SG_strcpy (&property->data.pvalue, text, '\0');
  7193.     modified = True;
  7194.       }
  7195.  
  7196.       else if (strcmp (text, "") != 0 && property == NULL) {
  7197.     SG_MakeProperty (node, SG_Comment, text);
  7198.     modified = True;
  7199.       }
  7200.     }
  7201.   }
  7202.  
  7203.   if (node != NULL) {
  7204.     property = node->property;
  7205.  
  7206.     while (property != NULL) {
  7207.       switch (property->id) {
  7208.     
  7209.       case SG_Comment  : XtSetArg (arg, XtNstring, (XtArgVal) ""); XtSetValues (c_comment , &arg, 1); break;
  7210.       case SG_nodeName : XtSetArg (arg, XtNtitle , (XtArgVal) ""); XtSetValues (c_toplevel, &arg, 1); break;
  7211.       case SG_GameName : 
  7212.     XtSetArg (arg, XtNtitle , (XtArgVal) ApplicationName); XtSetValues (w_toplevel, &arg, 1); break;
  7213.  
  7214.       case SG_Marked   :
  7215.       case SG_Letters  :
  7216.     if ((ptr = property->data.pvalue) != NULL) {
  7217.  
  7218.       while (*ptr != SG_EOS) {
  7219.         x = (*ptr++ & 0x3f);
  7220.         y = (*ptr++ & 0x3f);
  7221.         
  7222.         if (x != 0 || y != 0) {
  7223.           GbSetMark (w_goban, x, y, 0, 0);
  7224.           if (w_second_goban != NULL) 
  7225.         GbSetMark (w_second_goban, x, y, 0, 0);
  7226.         }
  7227.       }
  7228.     }
  7229.     break;
  7230.       }
  7231.       
  7232.       property = property->next;
  7233.     }
  7234.     
  7235.     switch (node->type) {
  7236.       
  7237.     case SG_MoveType    :
  7238.       while (node->left != NULL)
  7239.     node = node->left;
  7240.       
  7241.       while (node != NULL) {
  7242.     if (node->type == SG_MoveType) {
  7243.       GbSetMark (w_goban, node->x, node->y, 0, 0);
  7244.  
  7245.       if (w_second_goban != NULL) 
  7246.         GbSetMark (w_second_goban, node->x, node->y, 0, 0);
  7247.     }
  7248.     
  7249.     node = node->right;
  7250.       } 
  7251.  
  7252.       break;
  7253.     }
  7254.   }
  7255. }
  7256.  
  7257. /*******************************************************************************************************
  7258.  */
  7259.  
  7260. void HideProperty (node)
  7261. SG_NodePtr node;
  7262. {
  7263.   Arg            args[5];
  7264.   unsigned char *setup;
  7265.   int            color;
  7266.   int            x;
  7267.   int            y;
  7268.   SG_PropertyPtr property;
  7269.  
  7270.   if (node != NULL) {
  7271.     property = node->property;
  7272.     
  7273.     while (property != NULL) {
  7274.       switch (property->id) {
  7275.  
  7276.       case SG_unVieW :
  7277.     XtSetArg (args[0], XtNviewTop   , (Position) ((property->data.ivalue >> 24)));
  7278.     XtSetArg (args[1], XtNviewLeft  , (Position) ((property->data.ivalue >> 16) & 0xff));
  7279.     XtSetArg (args[2], XtNviewBottom, (Position) ((property->data.ivalue >>  8) & 0xff));
  7280.     XtSetArg (args[3], XtNviewRight , (Position) ((property->data.ivalue      ) & 0xff));
  7281.  
  7282.     XtSetValues (w_goban, args, 4);
  7283.     if (w_second_goban != NULL) 
  7284.       XtSetValues (w_second_goban, args, 4);
  7285.     break;
  7286.       }
  7287.       
  7288.       property = property->next;
  7289.     }
  7290.     
  7291.     switch (node->type) {
  7292.       
  7293.     case SG_EventType   :
  7294.       XtSetArg (args[0], XtNgameSize  , 19);
  7295.       XtSetArg (args[1], XtNviewTop   , 19);
  7296.       XtSetArg (args[2], XtNviewLeft  , 1 );
  7297.       XtSetArg (args[3], XtNviewBottom, 1 );
  7298.       XtSetArg (args[4], XtNviewRight , 19);
  7299.  
  7300.       XtSetValues (w_goban, args, 5);
  7301.       if (w_second_goban != NULL) 
  7302.     XtSetValues (w_second_goban, args, 5);
  7303.  
  7304.     case SG_DiagramType :
  7305.       
  7306.       if ((setup = node->setup) != NULL)
  7307.     while (*setup != SG_EOS) {
  7308.       color = (*setup & 0xc0);
  7309.       x     = (*setup++ & 0x3f);
  7310.       y     = (*setup++ & 0x3f);
  7311.       
  7312.       switch (color) {
  7313.       case SG_SETB  :
  7314.       case SG_SETW  : GbSetPoint (w_goban, x, y, GbEmptyPoint); break;
  7315.       case SG_SETEB : GbSetPoint (w_goban, x, y, GbBlackStone); break;
  7316.       case SG_SETEW : GbSetPoint (w_goban, x, y, GbWhiteStone); break;
  7317.       }
  7318.       
  7319.       if (w_second_goban != NULL) 
  7320.         switch (color) {
  7321.         case SG_SETB  :
  7322.         case SG_SETW  : GbSetPoint (w_second_goban, x, y, GbEmptyPoint); break;
  7323.         case SG_SETEB : GbSetPoint (w_second_goban, x, y, GbBlackStone); break;
  7324.         case SG_SETEW : GbSetPoint (w_second_goban, x, y, GbWhiteStone); break;
  7325.         }
  7326.     }
  7327.       break;
  7328.       
  7329.     case SG_MoveType :
  7330.       x     = node->x;
  7331.       y     = node->y;
  7332.  
  7333.       GbSetPoint (w_goban, x, y, GbEmptyPoint);
  7334.       if (w_second_goban != NULL) 
  7335.     GbSetPoint (w_second_goban, x, y, GbEmptyPoint);
  7336.       
  7337.       if ((setup = node->setup) != NULL) {
  7338.     color = (int) ((node->color == SG_BlackStone) ? GbWhiteStone : GbBlackStone);
  7339.  
  7340.     while (*setup != SG_EOS) {
  7341.       x     = (*setup++ & 0x3f);
  7342.       y     = (*setup++ & 0x3f);
  7343.       
  7344.       GbSetPoint (w_goban, x, y, color);
  7345.       if (w_second_goban != NULL) 
  7346.         GbSetPoint (w_second_goban, x, y, color);
  7347.     }
  7348.       }
  7349.  
  7350.       break;
  7351.     }
  7352.     
  7353.     HideTmpProperty (node);
  7354.   }
  7355. }
  7356.  
  7357. /*******************************************************************************************************
  7358.  */
  7359. SHAR_EOF
  7360. fi # end of overwriting check
  7361. if test -f 'game.c'
  7362. then
  7363.     echo shar: will not over-write existing file "'game.c'"
  7364. else
  7365. cat << \SHAR_EOF > 'game.c'
  7366. /****************************************************************************************************************
  7367.  *
  7368.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  7369.  *
  7370.  *  This program is distributed in the hope that it will be useful.
  7371.  *  Use and copying of this software and preparation of derivative works
  7372.  *  based upon this software are permitted, so long as the following
  7373.  *  conditions are met:
  7374.  *       o credit to the authors is acknowledged following current
  7375.  *         academic behaviour
  7376.  *       o no fees or compensation are charged for use, copies, or
  7377.  *         access to this software
  7378.  *       o this copyright notice is included intact.
  7379.  *  This software is made available AS IS, and no warranty is made about 
  7380.  *  the software or its performance. 
  7381.  * 
  7382.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  7383.  *  Send them to    dumesnil@etca.fr   or to:
  7384.  *       
  7385.  *       Antoine de Maricourt
  7386.  *       ETCA CREA-SP
  7387.  *       16 bis, avenue Prieur de la Cote d'Or
  7388.  *       94114 Arcueil Cedex
  7389.  *       France
  7390.  */
  7391.  
  7392. #include <stdio.h>
  7393. #include <fcntl.h>
  7394. #include <signal.h>
  7395.  
  7396. /*
  7397.  *   RESIGN 
  7398.  *   TERMINAISONS ...
  7399.  */
  7400.  
  7401. #include <X11/Intrinsic.h>
  7402.  
  7403. #include "xgoban.h"
  7404.  
  7405. static FILE *to_black;
  7406. static FILE *from_black;
  7407. static FILE *to_white;
  7408. static FILE *from_white;
  7409.  
  7410. static int   white_pid = -1;
  7411. static int   black_pid = -1;
  7412.  
  7413. /*******************************************************************************************************
  7414.  */
  7415.  
  7416. void signalMove (node)
  7417. SG_NodePtr node;
  7418. {
  7419.   int    x       = node->x;
  7420.   int    y       = node->y;
  7421.   Player player  = (node->player == SG_BlackStone) ? black_player : white_player;
  7422.   FILE  *to_file = (node->player == SG_BlackStone) ? to_black     : to_white;
  7423.  
  7424.   switch (player) {
  7425.   case Wally :
  7426.     if (x == 0 && y == 0)
  7427.       (void) fprintf (to_file, "pass\n");
  7428.     else
  7429.       (void) fprintf (to_file, "%c%d\n", 'a' + ((x > 8) ? x : x - 1), 20 - y);
  7430.  
  7431.     (void) fflush  (to_file);
  7432.     break;
  7433.  
  7434.   case Gnugo :
  7435.     if (x == 0 && y == 0)
  7436.       (void) fprintf (to_file, "pass\n");
  7437.     else
  7438.       (void) fprintf (to_file, "%c%d\n", 'A' + ((x > 8) ? x : x - 1), y);
  7439.  
  7440.     (void) fflush  (to_file);
  7441.     break;
  7442.  
  7443.   case Human :
  7444.     if (w_second_toplevel != NULL && beep >= -100)
  7445.       if (second_player == node->player)
  7446.     XBell (XtDisplay (w_second_goban), beep);
  7447.       else
  7448.     XBell (XtDisplay (w_goban)       , beep);
  7449.     break;
  7450.   }
  7451. }
  7452.  
  7453. static void receive_data (file)
  7454. FILE *file;
  7455. {
  7456.   char       buffer[256];
  7457.   char      *pat;
  7458.   int        x = -1;
  7459.   int        y = -1;
  7460.   SG_NodePtr node;
  7461.  
  7462.   if (current_mode == PlayMode) {
  7463.     if (fgets (buffer, 256, file) == NULL)
  7464.       return;
  7465.  
  7466.     switch (current_node->player == SG_BlackStone ? black_player : white_player) {
  7467.     case Wally :
  7468.       if ((pat = strstr (buffer, "Wally moves to")) != NULL) {
  7469.     sscanf (pat + 16, "%d", &y);
  7470.     x = *(pat + 15) - 'a' + 1; 
  7471.     x = x > 8 ? x - 1 : x;
  7472.     y = 20 - y;
  7473.       }
  7474.       else if ((pat = strstr (buffer, "Wally passes")) != NULL) {
  7475.     x = 0;
  7476.     y = 0;
  7477.       }
  7478.       break;
  7479.       
  7480.     case Gnugo :
  7481.       if ((pat = strstr (buffer, "my move: ")) != NULL) {
  7482.     x = *(pat + 9) - 'A' + 1; 
  7483.     x = x > 8 ? x - 1 : x;
  7484.     sscanf (pat + 10, "%d", &y);
  7485.       }
  7486.       break;
  7487.     }
  7488.     
  7489.     if (x != -1 && y != -1) {
  7490.  
  7491.       HideTmpProperty (current_node);
  7492.     
  7493.       node         =  SG_MakeNode (current_node, SG_Move);
  7494.       node->x      = x;
  7495.       node->y      = y;
  7496.       node->color  = current_node->player;
  7497.       
  7498.       Play (node);
  7499.  
  7500.       modified     = True;
  7501.       current_node = node;
  7502.  
  7503.       ShowProperty   (current_node);
  7504.       RedisplayBoard ();
  7505.  
  7506.       if (x == 0 && y == 0)
  7507.     switch (node->player) {
  7508.     case SG_BlackStone : PopupDialog (w_goban, NULL, BlackPassDialog); break;
  7509.     case SG_WhiteStone : PopupDialog (w_goban, NULL, WhitePassDialog); break;
  7510.     }
  7511.     
  7512.       signalMove (node);
  7513.       
  7514.       if (beep >= -100)
  7515.     XBell (XtDisplay (w_goban), beep);
  7516.     }
  7517.   }
  7518. }
  7519.  
  7520. void startGame (app_context)
  7521. XtAppContext app_context;
  7522. {
  7523.   int   from_pipe [2];
  7524.   int   to_pipe[2];
  7525.   char *argv[10];
  7526.   int   argc = 0;
  7527.  
  7528.   /*
  7529.    *   Start black player program
  7530.    */
  7531.  
  7532.   if (black_player != Human) {
  7533.     pipe (from_pipe);
  7534.     pipe (to_pipe  );
  7535.  
  7536.     if ((black_pid = fork ()) == 0) {
  7537.       fcntl(from_pipe[0], F_SETFL, O_NDELAY);
  7538.  
  7539.       close (0); dup (to_pipe  [0]);
  7540.       close (1); dup (from_pipe[1]);
  7541.       
  7542.       close (to_pipe  [0]);
  7543.       close (to_pipe  [1]);
  7544.       close (from_pipe[0]);
  7545.       close (from_pipe[1]);
  7546.       
  7547.       switch (black_player) {
  7548.       case Wally :
  7549.     argv[argc++] = "wally";
  7550.     argv[argc++] = "\0\0\0"; sprintf (argv[argc - 1], "%d", board_size);
  7551.     if (handicap == 0) argv[argc++] = "-even";
  7552.     argv[argc++] = NULL;
  7553.     
  7554.     if (execvp ("wally", argv) == -1)
  7555.       { fprintf (stderr, "XGoban : can't exec wally\n"); stopGame (); exit (1); }
  7556.     break;
  7557.  
  7558.       case Gnugo :
  7559.     if (execlp ("gnugo", "gnugo", (char *) NULL) == -1)
  7560.       { fprintf (stderr, "XGoban : can't exec gnugo\n"); stopGame (); exit (1); }
  7561.     break;
  7562.        
  7563.       case Human : break;
  7564.       }
  7565.     }
  7566.  
  7567.     if (black_pid == -1) 
  7568.       { fprintf (stderr, "XGoban : fork failed \n"); stopGame (); exit (1); }
  7569.     
  7570.     /*
  7571.      *    XGoban : install pipe with black player
  7572.      */
  7573.  
  7574.     else {
  7575.       close (to_pipe  [0]);
  7576.       close (from_pipe[1]);
  7577.       
  7578.       from_black = fdopen (from_pipe[0], "r");
  7579.       to_black   = fdopen (to_pipe  [1], "w");
  7580.     
  7581.       setbuf (from_black, (char *) NULL);
  7582.       setbuf (to_black  , (char *) NULL);
  7583.       
  7584.       XtAppAddInput (app_context, fileno (from_black), (XtPointer) XtInputReadMask, 
  7585.              (XtInputCallbackProc) receive_data, (XtPointer) from_black);
  7586.       
  7587.       switch (black_player) {
  7588.       case Wally : break;
  7589.       case Gnugo :
  7590.     (void) fprintf (to_black, "\n%d\nw\n", handicap);
  7591.     (void) fflush  (to_black);
  7592.     break;
  7593.       case Human : break;
  7594.       }
  7595.     }
  7596.   }
  7597.  
  7598.   /*
  7599.    *   Start white player program
  7600.    */
  7601.  
  7602.   if (white_player != Human) {
  7603.     pipe (from_pipe);
  7604.     pipe (to_pipe  );
  7605.  
  7606.     if ((white_pid = fork ()) == 0) {
  7607.       fcntl(from_pipe[0], F_SETFL, O_NDELAY);
  7608.  
  7609.       close (0); dup (to_pipe  [0]);
  7610.       close (1); dup (from_pipe[1]);
  7611.       
  7612.       close (to_pipe  [0]);
  7613.       close (to_pipe  [1]);
  7614.       close (from_pipe[0]);
  7615.       close (from_pipe[1]);
  7616.       
  7617.       switch (white_player) {
  7618.       case Gnugo :
  7619.     if (execlp ("gnugo", "gnugo", (char *) NULL) == -1)
  7620.       { fprintf (stderr, "XGoban : can't exec wally\n"); stopGame (); exit (1); }
  7621.     break;
  7622.       case Wally : break;
  7623.       case Human : break;
  7624.       }
  7625.     }
  7626.  
  7627.     if (white_pid == -1) 
  7628.       { fprintf (stderr, "XGoban : fork failed \n"); stopGame (); exit (1); }
  7629.  
  7630.     /*
  7631.      *    XGoban : install pipe with white player
  7632.      */
  7633.  
  7634.     close (to_pipe  [0]);
  7635.     close (from_pipe[1]);
  7636.       
  7637.     from_white = fdopen (from_pipe[0], "r");
  7638.     to_white   = fdopen (to_pipe  [1], "w");
  7639.     
  7640.     setbuf (from_white, (char *) NULL);
  7641.     setbuf (to_white  , (char *) NULL);
  7642.     
  7643.     XtAppAddInput (app_context, fileno (from_white), (XtPointer) XtInputReadMask,
  7644.            (XtInputCallbackProc) receive_data, (XtPointer) from_white);
  7645.     
  7646.     switch (white_player) {
  7647.     case Wally : break;
  7648.     case Human : break;
  7649.     case Gnugo :
  7650.       (void) fprintf (to_white, "\n%d\nb\n", handicap);
  7651.       (void) fflush  (to_white);
  7652.       break;
  7653.     }
  7654.   }
  7655. }
  7656.  
  7657. void stopGame ()
  7658. {
  7659.   if (black_pid != -1) (void) kill (black_pid, SIGKILL);
  7660.   if (white_pid != -1) (void) kill (white_pid, SIGKILL);
  7661.  
  7662.   current_mode = EditMode;
  7663. }
  7664. SHAR_EOF
  7665. fi # end of overwriting check
  7666. if test -f 'blackstone.bm'
  7667. then
  7668.     echo shar: will not over-write existing file "'blackstone.bm'"
  7669. else
  7670. cat << \SHAR_EOF > 'blackstone.bm'
  7671. #define blackstone_width 16
  7672. #define blackstone_height 16
  7673. #define blackstone_x_hot 7
  7674. #define blackstone_y_hot 8
  7675. static char blackstone_bits[] = {
  7676.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  7677.    0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0xfe, 0x77, 0xfe, 0x7b,
  7678.    0xfc, 0x3c, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  7679. SHAR_EOF
  7680. fi # end of overwriting check
  7681. if test -f 'graystone.bm'
  7682. then
  7683.     echo shar: will not over-write existing file "'graystone.bm'"
  7684. else
  7685. cat << \SHAR_EOF > 'graystone.bm'
  7686. #define graystone_width 16
  7687. #define graystone_height 16
  7688. #define graystone_x_hot 7
  7689. #define graystone_y_hot 8
  7690. static char graystone_bits[] = {
  7691.    0xc0, 0x03, 0xb0, 0x0e, 0x58, 0x15, 0xac, 0x2a, 0x56, 0x55, 0xaa, 0x6a,
  7692.    0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xba, 0x56, 0x5d, 0xaa, 0x6e,
  7693.    0x54, 0x37, 0xa8, 0x1a, 0x70, 0x0d, 0xc0, 0x03};
  7694. SHAR_EOF
  7695. fi # end of overwriting check
  7696. if test -f 'stonemask.bm'
  7697. then
  7698.     echo shar: will not over-write existing file "'stonemask.bm'"
  7699. else
  7700. cat << \SHAR_EOF > 'stonemask.bm'
  7701. #define stonemask_width 16
  7702. #define stonemask_height 16
  7703. #define stonemask_x_hot 7
  7704. #define stonemask_y_hot 8
  7705. static char stonemask_bits[] = {
  7706.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  7707.    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x7f,
  7708.    0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  7709. SHAR_EOF
  7710. fi # end of overwriting check
  7711. if test -f 'whitestone.bm'
  7712. then
  7713.     echo shar: will not over-write existing file "'whitestone.bm'"
  7714. else
  7715. cat << \SHAR_EOF > 'whitestone.bm'
  7716. #define whitestone_width 16
  7717. #define whitestone_height 16
  7718. #define whitestone_x_hot 7
  7719. #define whitestone_y_hot 8
  7720. static char whitestone_bits[] = {
  7721.    0xc0, 0x03, 0x30, 0x0c, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40,
  7722.    0x01, 0x80, 0x01, 0x80, 0x01, 0x90, 0x01, 0x90, 0x02, 0x48, 0x02, 0x44,
  7723.    0x04, 0x23, 0x08, 0x10, 0x30, 0x0c, 0xc0, 0x03};
  7724. SHAR_EOF
  7725. fi # end of overwriting check
  7726. if test -f 'icon.bm'
  7727. then
  7728.     echo shar: will not over-write existing file "'icon.bm'"
  7729. else
  7730. cat << \SHAR_EOF > 'icon.bm'
  7731. #define icon_width 82
  7732. #define icon_height 82
  7733. static char icon_bits[] = {
  7734.    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  7735.    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  7736.    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01,
  7737.    0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04,
  7738.    0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff,
  7739.    0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40,
  7740.    0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
  7741.    0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
  7742.    0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
  7743.    0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
  7744.    0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00,
  7745.    0x20, 0x00, 0x01, 0x04, 0x10, 0xf0, 0x01, 0x01, 0x04, 0x10, 0x00, 0x20,
  7746.    0x00, 0x01, 0x04, 0x10, 0xf8, 0x03, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00,
  7747.    0x01, 0x04, 0x10, 0xfc, 0x07, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01,
  7748.    0x04, 0x10, 0xfc, 0x07, 0x01, 0x04, 0x10, 0x00, 0xf8, 0xff, 0xff, 0xff,
  7749.    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10,
  7750.    0xfc, 0x06, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x7c,
  7751.    0x07, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0xf8, 0x03,
  7752.    0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0xf0, 0x01, 0x01,
  7753.    0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
  7754.    0x10, 0x00, 0x20, 0xc0, 0x07, 0x1f, 0x7c, 0xf0, 0x01, 0x01, 0x04, 0x10,
  7755.    0x00, 0x20, 0x20, 0x88, 0x20, 0x82, 0xf8, 0x03, 0x01, 0x04, 0x10, 0x00,
  7756.    0x20, 0x10, 0x50, 0x40, 0x01, 0xfd, 0x07, 0x01, 0x04, 0x10, 0x00, 0x20,
  7757.    0x10, 0x50, 0x40, 0x01, 0xfd, 0x07, 0x01, 0x04, 0x10, 0x00, 0xf8, 0x1f,
  7758.    0x70, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x10, 0x54,
  7759.    0x50, 0x41, 0xfd, 0x06, 0x01, 0x04, 0x10, 0x00, 0x20, 0x10, 0x52, 0x48,
  7760.    0x21, 0x7d, 0x07, 0x01, 0x04, 0x10, 0x00, 0x20, 0x20, 0x88, 0x20, 0x82,
  7761.    0xf8, 0x03, 0x01, 0x04, 0x10, 0x00, 0x20, 0xc0, 0x07, 0x1f, 0x7c, 0xf0,
  7762.    0x01, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
  7763.    0x01, 0x04, 0x10, 0x00, 0x20, 0xc0, 0x07, 0x1f, 0x7c, 0xf0, 0xc1, 0x07,
  7764.    0x04, 0x10, 0x00, 0x20, 0x20, 0x88, 0x3f, 0xfe, 0x08, 0xe2, 0x0f, 0x04,
  7765.    0x10, 0x00, 0x20, 0x10, 0xd0, 0x7f, 0xff, 0x05, 0xf4, 0x1f, 0x04, 0x10,
  7766.    0x00, 0x20, 0x10, 0xd0, 0x7f, 0xff, 0x05, 0xf4, 0x1f, 0x04, 0x10, 0x00,
  7767.    0xf8, 0x1f, 0xf0, 0xff, 0xff, 0x07, 0xfc, 0xff, 0xff, 0x7f, 0x00, 0x20,
  7768.    0x10, 0xd4, 0x6f, 0xbf, 0x05, 0xf5, 0x1b, 0x04, 0x10, 0x00, 0x20, 0x10,
  7769.    0xd2, 0x77, 0xdf, 0x85, 0xf4, 0x1d, 0x04, 0x10, 0x00, 0x20, 0x20, 0x88,
  7770.    0x3f, 0xfe, 0x08, 0xe2, 0x0f, 0x04, 0x10, 0x00, 0x20, 0xc0, 0x07, 0x1f,
  7771.    0x7c, 0xf0, 0xc1, 0x07, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10,
  7772.    0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0xf0,
  7773.    0x01, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x08, 0x02,
  7774.    0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x04, 0x04, 0x01,
  7775.    0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x04, 0x04, 0x01, 0x04,
  7776.    0x10, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x07, 0xfc, 0xff, 0xff, 0x7f,
  7777.    0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x04, 0x05, 0x01, 0x04, 0x10, 0x00,
  7778.    0x20, 0x00, 0x01, 0x04, 0x10, 0x84, 0x04, 0x01, 0x04, 0x10, 0x00, 0x20,
  7779.    0x00, 0x01, 0x04, 0x10, 0x08, 0x02, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00,
  7780.    0x01, 0x04, 0x10, 0xf0, 0x01, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01,
  7781.    0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x1f,
  7782.    0x7c, 0x40, 0x00, 0x01, 0x1f, 0x10, 0x00, 0x20, 0x00, 0x81, 0x3f, 0xfe,
  7783.    0x40, 0x00, 0x81, 0x3f, 0x10, 0x00, 0x20, 0x00, 0xc1, 0x7f, 0xff, 0x41,
  7784.    0x00, 0xc1, 0x7f, 0x10, 0x00, 0x20, 0x00, 0xc1, 0x7f, 0xff, 0x41, 0x00,
  7785.    0xc1, 0x7f, 0x10, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  7786.    0xff, 0x7f, 0x00, 0x20, 0x00, 0xc1, 0x6f, 0xbf, 0x41, 0x00, 0xc1, 0x6f,
  7787.    0x10, 0x00, 0x20, 0x00, 0xc1, 0x77, 0xdf, 0x41, 0x00, 0xc1, 0x77, 0x10,
  7788.    0x00, 0x20, 0x00, 0x81, 0x3f, 0xfe, 0x40, 0x00, 0x81, 0x3f, 0x10, 0x00,
  7789.    0x20, 0x00, 0x01, 0x1f, 0x7c, 0x40, 0x00, 0x01, 0x1f, 0x10, 0x00, 0x20,
  7790.    0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00,
  7791.    0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01,
  7792.    0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04,
  7793.    0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10,
  7794.    0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
  7795.    0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
  7796.    0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
  7797.    0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
  7798.    0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
  7799.    0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00,
  7800.    0x20, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20,
  7801.    0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00,
  7802.    0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01,
  7803.    0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0xf8, 0xff, 0xff, 0xff,
  7804.    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10,
  7805.    0x40, 0x00, 0x01, 0x04, 0x10, 0x00, 0x20, 0x00, 0x01, 0x04, 0x10, 0x40,
  7806.    0x00, 0x01, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  7807.    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  7808.    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  7809.    0x00, 0x00};
  7810. SHAR_EOF
  7811. fi # end of overwriting check
  7812. if test -f 'Goban.h'
  7813. then
  7814.     echo shar: will not over-write existing file "'Goban.h'"
  7815. else
  7816. cat << \SHAR_EOF > 'Goban.h'
  7817. /****************************************************************************************************************
  7818.  *
  7819.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  7820.  *
  7821.  *  This program is distributed in the hope that it will be useful.
  7822.  *  Use and copying of this software and preparation of derivative works
  7823.  *  based upon this software are permitted, so long as the following
  7824.  *  conditions are met:
  7825.  *       o credit to the authors is acknowledged following current
  7826.  *         academic behaviour
  7827.  *       o no fees or compensation are charged for use, copies, or
  7828.  *         access to this software
  7829.  *       o this copyright notice is included intact.
  7830.  *  This software is made available AS IS, and no warranty is made about 
  7831.  *  the software or its performance. 
  7832.  * 
  7833.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  7834.  *  Send them to    dumesnil@etca.fr   or to:
  7835.  *       
  7836.  *       Antoine de Maricourt
  7837.  *       ETCA CREA-SP
  7838.  *       16 bis, avenue Prieur de la Cote d'Or
  7839.  *       94114 Arcueil Cedex
  7840.  *       France
  7841.  */
  7842.  
  7843. #ifndef _Goban_h
  7844. #define _Goban_h
  7845.  
  7846. /* Resources:
  7847.  
  7848.  Name               Class          RepType        Default Value
  7849.  ----               -----          -------        -------------
  7850.  autoRedisplay         AutoRedisplay      Boolean         True
  7851.  background           Background      Pixel          XtDefaultBackground
  7852.  blackStoneBackground  Background      Pixel          black
  7853.  blackStoneBorder      BorderColor      Pixel          black
  7854.  blackStoneForeground  Foreground      Pixel          white
  7855.  border               BorderColor      Pixel          XtDefaultForeground
  7856.  borderWidth           BorderWidth      Dimension      1
  7857.  cursor                Cursor             Integer         GbGrayCursor
  7858.  destroyCallback       Callback          Pointer      NULL
  7859.  displayCoordinates    DisplayCoordinates Boolean      True
  7860.  font                  Font               XFontStruct*    fixed
  7861.  foreground            Foreground         Pixel           XtDefaultForeground
  7862.  gameSize              Size               Dimension       19
  7863.  height               Height          Dimension      computed at create
  7864.  mappedWhenManaged     MappedWhenManaged  Boolean      True
  7865.  pointSize             Size               Dimension       24
  7866.  sensitive           Sensitive      Boolean      True
  7867.  viewBottom            Position           Position        computed at create
  7868.  viewLeft              Position           Position        computed at create
  7869.  viewRight             Position           Position        computed at create
  7870.  viewTop               Position           Position        computed at create
  7871.  whiteStoneBackground  Background      Pixel          white
  7872.  whiteStoneBorder      BorderColor      Pixel          black
  7873.  whiteStoneForeground  Foreground      Pixel          black
  7874.  width               Width          Dimension      computed at create
  7875.  x               Position          Position      0
  7876.  y               Position          Position      0
  7877. */
  7878.  
  7879. /* define any special resource names here that are not in <X11/StringDefs.h> */
  7880.  
  7881. #define XtNautoRedisplay         "autoRedisplay"
  7882. #define XtNviewBottom            "viewBottom"
  7883.  
  7884. #ifndef XtNcursor
  7885. #define XtNcursor                "cursor"
  7886. #endif
  7887.  
  7888. #define XtNgameSize              "gameSize"
  7889. #define XtNviewLeft              "viewLeft"
  7890. #define XtNdisplayCoordinates    "displayCoordinates"
  7891. #define XtNpointSize             "pointSize"
  7892. #define XtNviewRight             "viewRight"
  7893. #define XtNviewTop               "viewTop"
  7894. #define XtNblackStoneBorder      "blackStoneBorder"
  7895. #define XtNblackStoneForeground  "blackStoneForeground"
  7896. #define XtNblackStoneBackground  "blackStoneBackground"
  7897. #define XtNwhiteStoneBorder      "whiteStoneBorder"
  7898. #define XtNwhiteStoneForeground  "whiteStoneForeground"
  7899. #define XtNwhiteStoneBackground  "whiteStoneBackground"
  7900.  
  7901. #define XtCAutoRedisplay         "AutoRedisplay"
  7902. #define XtCDisplayCoordinates    "DisplayCoordinates"
  7903. #define XtCSize                  "Size"
  7904.  
  7905. #define XtEgbWhiteStone          "white"
  7906. #define XtEgbBlackStone          "black"
  7907. #define XtEgbGrayStone           "gray"
  7908.  
  7909. /* declare specific GobanWidget class and instance datatypes */
  7910.  
  7911. typedef struct _GobanClassRec*     GobanWidgetClass;
  7912. typedef struct _GobanRec*     GobanWidget;
  7913.  
  7914. /* declare the class constant */
  7915.  
  7916. extern WidgetClass gobanWidgetClass;
  7917.  
  7918. /* cursors */
  7919.  
  7920. #define GbCGrayStone         256
  7921. #define GbCBlackStone        257
  7922. #define GbCWhiteStone        258
  7923.  
  7924. /* special marks */
  7925.  
  7926. #define GbMSquareMark        1
  7927. #define GbMTriangleMark      2
  7928. #define GbMVCrossMark        3
  7929. #define GbMDCrossMark        4
  7930. #define GbMDiamondMark       5
  7931.  
  7932. /* colors */
  7933.  
  7934. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone } GbPointState;
  7935.  
  7936. /* user functions */
  7937.  
  7938. #define GbRemoveMark(w,x,y)  GbSetMark (w, x, y, 0, 0)
  7939.  
  7940. extern void GbRedisplayBoard ( /* Widget w */ );
  7941. extern void GbClearBoard     ( /* Widget w */ );
  7942. extern void GbSetPoint       ( /* Widget w, Position x, Position y, GbPointState color */ );
  7943. extern void GbSetNum         ( /* Widget w, Position x, Position y, int num   */ );
  7944. extern void GbSetMark        ( /* Widget w, Position x, Position y, unsigned char mark1, unsigned char mark2 */ );
  7945.  
  7946. extern Boolean GbGetPositionFromStone ( /* Widget w, Position *x, Position *y */ );
  7947. extern Boolean GbGetStoneFromPosition ( /* Widget w, Position *x, Position *y */ );
  7948.  
  7949. #endif /* _Goban_h */
  7950.  
  7951. SHAR_EOF
  7952. fi # end of overwriting check
  7953. if test -f 'GobanP.h'
  7954. then
  7955.     echo shar: will not over-write existing file "'GobanP.h'"
  7956. else
  7957. cat << \SHAR_EOF > 'GobanP.h'
  7958. /****************************************************************************************************************
  7959.  *
  7960.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  7961.  *
  7962.  *  This program is distributed in the hope that it will be useful.
  7963.  *  Use and copying of this software and preparation of derivative works
  7964.  *  based upon this software are permitted, so long as the following
  7965.  *  conditions are met:
  7966.  *       o credit to the authors is acknowledged following current
  7967.  *         academic behaviour
  7968.  *       o no fees or compensation are charged for use, copies, or
  7969.  *         access to this software
  7970.  *       o this copyright notice is included intact.
  7971.  *  This software is made available AS IS, and no warranty is made about 
  7972.  *  the software or its performance. 
  7973.  * 
  7974.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  7975.  *  Send them to    dumesnil@etca.fr   or to:
  7976.  *       
  7977.  *       Antoine de Maricourt
  7978.  *       ETCA CREA-SP
  7979.  *       16 bis, avenue Prieur de la Cote d'Or
  7980.  *       94114 Arcueil Cedex
  7981.  *       France
  7982.  */
  7983.  
  7984. #ifndef _GobanP_h
  7985. #define _GobanP_h
  7986.  
  7987. #include "Goban.h"
  7988.  
  7989. /* include superclass private header file */
  7990. #include <X11/CoreP.h>
  7991.  
  7992. /* define unique representation types not found in <X11/StringDefs.h> */
  7993.  
  7994. #define XtRGobanResource "GobanResource"
  7995.  
  7996. typedef struct {
  7997.     int empty;
  7998. } GobanClassPart;
  7999.  
  8000. typedef struct _GobanClassRec {
  8001.     CoreClassPart    core_class;
  8002.     GobanClassPart    goban_class;
  8003. } GobanClassRec;
  8004.  
  8005. extern GobanClassRec gobanClassRec;
  8006.  
  8007. typedef struct {
  8008.   unsigned int free  : 1;
  8009.   unsigned int black : 1;
  8010.   unsigned int mark1 : 8;
  8011.   unsigned int mark2 : 8;
  8012.   unsigned int num   : 10;
  8013. } PointState;
  8014.  
  8015. typedef struct {
  8016.     /* resources */
  8017.  
  8018.   Boolean       auto_redisplay;
  8019.   Position      bottom;
  8020.   int           cursor;
  8021.   XFontStruct  *font;
  8022.   Pixel         foreground;
  8023.   Dimension     game_size;
  8024.   Position      left;
  8025.   Boolean       display_coordinates;
  8026.   Dimension     point_size;
  8027.   Position      right;
  8028.   Position      top;
  8029.  
  8030.     /* private state */
  8031.  
  8032.   PointState    points[20][20];
  8033.   Position      x_offset;
  8034.   Position      y_offset;
  8035.  
  8036.   Pixmap        black_stone;
  8037.   Pixmap        board;
  8038.   Pixmap        gray_stone;
  8039.   Pixmap        mouse_mask;
  8040.   Pixmap        picture;
  8041.   Pixmap        white_stone;
  8042.  
  8043.   GC            background_gc;
  8044.   GC            foreground_gc;
  8045.   GC            black_fg_gc;
  8046.   GC            black_bg_gc;
  8047.   GC            black_bd_gc;
  8048.   GC            white_fg_gc;
  8049.   GC            white_bg_gc;
  8050.   GC            white_bd_gc;
  8051.   GC            copy_gc;
  8052.  
  8053.   Cursor        black_cursor;
  8054.   Cursor        gray_cursor;
  8055.   Cursor        white_cursor;
  8056.   Cursor        font_cursor;
  8057.  
  8058.   Pixel         white_bg;
  8059.   Pixel         white_fg;
  8060.   Pixel         white_bd;
  8061.   Pixel         black_bg;
  8062.   Pixel         black_fg;
  8063.   Pixel         black_bd;
  8064. } GobanPart;
  8065.  
  8066. typedef struct _GobanRec {
  8067.     CorePart    core;
  8068.     GobanPart    goban;
  8069. } GobanRec;
  8070.  
  8071. #define Min(x,y)      ((x) > (y) ? (y) : (x))
  8072. #define Max(x,y)      ((x) > (y) ? (x) : (y))
  8073.  
  8074. #endif /* _GobanP_h */
  8075. SHAR_EOF
  8076. fi # end of overwriting check
  8077. if test -f 'sg.h'
  8078. then
  8079.     echo shar: will not over-write existing file "'sg.h'"
  8080. else
  8081. cat << \SHAR_EOF > 'sg.h'
  8082. /****************************************************************************************************************
  8083.  *
  8084.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  8085.  *
  8086.  *  This program is distributed in the hope that it will be useful.
  8087.  *  Use and copying of this software and preparation of derivative works
  8088.  *  based upon this software are permitted, so long as the following
  8089.  *  conditions are met:
  8090.  *       o credit to the authors is acknowledged following current
  8091.  *         academic behaviour
  8092.  *       o no fees or compensation are charged for use, copies, or
  8093.  *         access to this software
  8094.  *       o this copyright notice is included intact.
  8095.  *  This software is made available AS IS, and no warranty is made about 
  8096.  *  the software or its performance. 
  8097.  * 
  8098.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  8099.  *  Send them to    dumesnil@etca.fr   or to:
  8100.  *       
  8101.  *       Antoine de Maricourt
  8102.  *       ETCA CREA-SP
  8103.  *       16 bis, avenue Prieur de la Cote d'Or
  8104.  *       94114 Arcueil Cedex
  8105.  *       France
  8106.  */
  8107.  
  8108. #ifndef _sg_h_
  8109. #define _sg_h_
  8110.  
  8111. #include <stdio.h>
  8112. #include <ctype.h>
  8113. #include <string.h>
  8114. #include <malloc.h>
  8115.  
  8116. #define SG_Black              1            /*  Done  */
  8117. #define SG_White              2            /*  Done  */
  8118. #define SG_Comment            3            /*  Done  */
  8119. #define SG_nodeName           4            /*  Done  */
  8120. #define SG_nodeValue          5
  8121. #define SG_CHeck              6
  8122. #define SG_GoodBlack          7
  8123. #define SG_GoodWhite          8
  8124. #define SG_TEsuji             9
  8125. #define SG_BadMove           10
  8126. #define SG_BlackLeft         11            /*  Done  */
  8127. #define SG_WhiteLeft         12            /*  Done  */
  8128. #define SG_FiGure            13
  8129. #define SG_AddBlack          14            /*  Done  */
  8130. #define SG_AddWhite          15            /*  Done  */
  8131. #define SG_AddEmpty          16            /*  Done  */
  8132. #define SG_PLayer            17
  8133. #define SG_GameName          18            /*  Done  */
  8134. #define SG_GameComment       19            /*  Done  */
  8135. #define SG_EVent             20            /*  Done  */
  8136. #define SG_ROund             21            /*  Done  */
  8137. #define SG_DaTe              22            /*  Done  */
  8138. #define SG_PlaCe             23            /*  Done  */
  8139. #define SG_PlayerBlack       24            /*  Done  */
  8140. #define SG_PlayerWhite       25            /*  Done  */
  8141. #define SG_REsult            26            /*  Done  */
  8142. #define SG_USer              27            /*  Done  */
  8143. #define SG_TiMe              28            /*  Done  */
  8144. #define SG_SOurce            29            /*  Done  */
  8145. #define SG_GaMe              30
  8146. #define SG_SiZe              31
  8147. #define SG_VieW              32            /*  Done  */
  8148. #define SG_BlackSpec         33
  8149. #define SG_WhiteSpec         34
  8150. #define SG_EvaLuation        35
  8151. #define SG_EXpected          36
  8152. #define SG_SeLected          37
  8153. #define SG_Marked            38
  8154. #define SG_Letters           39
  8155. #define SG_BlackRank         40            /*  Done  */
  8156. #define SG_WhiteRank         41            /*  Done  */
  8157. #define SG_HAndicap          42            /*  Done  */
  8158. #define SG_KoMi              43            /*  Done  */
  8159. #define SG_TerritoryBlack    44
  8160. #define SG_TerritoryWhite    45
  8161. #define SG_SeCure            46
  8162. #define SG_ReGion            47
  8163. #define SG_KO                48
  8164. #define SG_Illegal           49
  8165.  
  8166. #define SG_MaxID             SG_Illegal
  8167.  
  8168. #define SG_unVieW            SG_Illegal + 1
  8169. #define SG_ko                SG_Illegal + 2
  8170.  
  8171. typedef struct _SG_Property {
  8172.   int id;
  8173.  
  8174.   union {
  8175.     long           ivalue;
  8176.     unsigned char *pvalue;
  8177.   } data;
  8178.  
  8179.   struct _SG_Property *next;
  8180.  
  8181. } SG_Property, *SG_PropertyPtr;
  8182.  
  8183. typedef struct _SG_Node {
  8184.  
  8185.   short             type;
  8186.  
  8187.   short             num;
  8188.   char              color;
  8189.   char              x;
  8190.   char              y;
  8191.   char              player;
  8192.  
  8193.   unsigned char    *setup;
  8194.   SG_PropertyPtr    property;
  8195.     
  8196.   struct _SG_Node  *up;
  8197.   struct _SG_Node  *down;
  8198.   struct _SG_Node  *left;
  8199.   struct _SG_Node  *right;
  8200.  
  8201. } SG_Node, *SG_NodePtr;  
  8202.  
  8203. #define SG_NoType               0
  8204. #define SG_EventType            1
  8205. #define SG_MoveType             2
  8206. #define SG_DiagramType          4
  8207.  
  8208. #define SG_EmptyPoint           0
  8209. #define SG_Border               1
  8210. #define SG_WhiteStone           2
  8211. #define SG_BlackStone           3
  8212.  
  8213. #define SG_Event                0
  8214. #define SG_Move                 1
  8215. #define SG_VariationMove        2
  8216. #define SG_Diagram              3
  8217. #define SG_VariationDiagram     4
  8218.  
  8219. #define SG_SetupProperty        1
  8220. #define SG_CommentProperty      2
  8221. #define SG_GameNameProperty     3
  8222.  
  8223. #define SG_EOS                  0xff
  8224.  
  8225. #define SG_SETMASK              ((1 << 7) | (1 << 6))
  8226. #define SG_SETB                 ((1 << 7) | (1 << 6))
  8227. #define SG_SETW                 (1 << 7)
  8228. #define SG_SETEB                (1 << 6)
  8229. #define SG_SETEW                0
  8230. #define SG_SETE                 SG_SETEB
  8231.  
  8232. #define SG_OK                   0
  8233. #define SG_PlaySuicide          1
  8234. #define SG_PlayKo               2
  8235. #define SG_PlayIllegal          3
  8236.  
  8237. #define SG_EOFERR               1
  8238. #define SG_NSTERR               2
  8239. #define SG_NCLERR               3
  8240. #define SG_NCTERR               4
  8241. #define SG_NDGERR               5
  8242.  
  8243. typedef struct {
  8244.   char             *keyword;
  8245.   char             *print;
  8246.   int               id;
  8247.   int               node_id;
  8248. } SG_KWData;
  8249.  
  8250. extern SG_KWData                sg_keywords[];
  8251.  
  8252. extern SG_NodePtr               SG_MakeNode     ();
  8253. extern SG_PropertyPtr           SG_GetProperty  ();
  8254. extern void                     SG_MakeProperty ();
  8255. extern void                     SG_FreeNode     ();
  8256. extern SG_NodePtr               SG_RemoveNode   ();
  8257. extern SG_NodePtr               SG_ReadTree     ();
  8258. extern int                      SG_WriteTree    ();
  8259.  
  8260. extern void                     SG_strcat       ();
  8261. extern void                     SG_strcpy       ();
  8262.  
  8263. #endif    /* _sg_h_ */
  8264. SHAR_EOF
  8265. fi # end of overwriting check
  8266. if test -f 'xgoban.h'
  8267. then
  8268.     echo shar: will not over-write existing file "'xgoban.h'"
  8269. else
  8270. cat << \SHAR_EOF > 'xgoban.h'
  8271. /****************************************************************************************************************
  8272.  *
  8273.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  8274.  *
  8275.  *  This program is distributed in the hope that it will be useful.
  8276.  *  Use and copying of this software and preparation of derivative works
  8277.  *  based upon this software are permitted, so long as the following
  8278.  *  conditions are met:
  8279.  *       o credit to the authors is acknowledged following current
  8280.  *         academic behaviour
  8281.  *       o no fees or compensation are charged for use, copies, or
  8282.  *         access to this software
  8283.  *       o this copyright notice is included intact.
  8284.  *  This software is made available AS IS, and no warranty is made about 
  8285.  *  the software or its performance. 
  8286.  * 
  8287.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  8288.  *  Send them to    dumesnil@etca.fr   or to:
  8289.  *       
  8290.  *       Antoine de Maricourt
  8291.  *       ETCA CREA-SP
  8292.  *       16 bis, avenue Prieur de la Cote d'Or
  8293.  *       94114 Arcueil Cedex
  8294.  *       France
  8295.  */
  8296.  
  8297. #ifndef _xgoban_h_
  8298. #define _xgoban_h_
  8299.  
  8300. #include <X11/Intrinsic.h>
  8301. #include <X11/StringDefs.h>
  8302.  
  8303. #include "sg.h"
  8304. #include "Goban.h"
  8305.  
  8306. typedef enum { Human, Wally, Gnugo } Player;
  8307. typedef enum { EditMode, DiagramMode, SizeMode, ViewMode, PlayMode, MailMode } Mode;
  8308.  
  8309. #define ApplicationName           "XGoban"
  8310.  
  8311. #define LoadDialog                2
  8312. #define EditDialog                3
  8313. #define SaveBeforeQuitDialog      5
  8314. #define SaveAsAndQuitDialog       6
  8315. #define ReallyQuitDialog          7
  8316. #define SaveBeforeLoadDialog      8
  8317. #define SaveAsAndLoadDialog       9
  8318. #define SaveAsDialog              10
  8319. #define CantSaveRetryDialog       11
  8320. #define CantLoadRetryDialog       12
  8321. #define HelpDialog                13
  8322.  
  8323. #define PlayerNodeErrorWarning    14
  8324. #define MemoryErrorDialog         15
  8325. #define CantOpenFileDialog        16
  8326. #define IllegalMoveDialog         17
  8327. #define SuicideMoveDialog         18
  8328. #define KoMoveDialog              19
  8329. #define BadHandicapWarning        20
  8330. #define RemainingStonesWarning    21
  8331. #define ReadOnlyWarning           22
  8332. #define DiagramBadNodeWarning     23
  8333. #define SizeBadNodeWarning        24
  8334. #define ReallyDeleteDialog        25
  8335. #define PlayerMoveErrorWarning    26
  8336. #define WallyWhitePlayWarning     27
  8337. #define WallyBadSizeWarning       28
  8338. #define WallyBadHandicapWarning   29
  8339. #define StopGameDialog            30
  8340. #define RemoveStonesDialog        31
  8341. #define BlackPassDialog           32
  8342. #define WhitePassDialog           33
  8343. #define NodeNameDialog            34
  8344. #define MailNoMoveDialog          35
  8345. #define MailConfirmMoveDialog     36
  8346. #define StopGameBeforeQuitDialog  37  
  8347.  
  8348. #define ReplaceNodeDialog         40
  8349.  
  8350. #define BadHandicapMsg            " Don't know how to place \n    handicap stones      \n  for this size of board "
  8351. #define RemainingStonesMsg        "  Don't know how to place  \n remaining handicap stones "
  8352. #define PlayerNodeErrorMsg        " Player can be changed only \n  at Event or Diagram node  "
  8353. #define PlayerMoveErrorMsg        " Following  move is already \n done : can't change Player "
  8354. #define IllegalMoveMsg            " This move is illegal "
  8355. #define KoMoveMsg                 " You can't retake the \n        ko now        "
  8356. #define SuicideMoveMsg            " Suicide is not allowed "
  8357. #define DiagramBadNodeMsg         " Diagram can't be edited \n      at Move node       "
  8358. #define SizeBadNodeMsg            " Goban can be resized \n  only at Event node  "
  8359. #define CantOpenFileMsg           " Can't open file "
  8360. #define WallyWhitePlayMsg         " Wally only plays black "
  8361. #define WallyBadSizeMsg           " Wally plays on a 9x9, \n 13x13 or 19x19 board  "
  8362. #define WallyBadHandicapMsg       " Wally plays with no or \n   9 handicap stones    "
  8363. #define BlackPassMsg              " Black passes "
  8364. #define WhitePassMsg              " White passes "
  8365.  
  8366. #define LoadFileMsg               "Load file :"
  8367. #define SaveFileMsg               "Save file :"
  8368. #define EditFileMsg               "Edit file ?"
  8369. #define ReplaceNodeMsg            "Replace current node ?"
  8370. #define ReallyQuitMsg             "Really quit ?"
  8371. #define ReallyDeleteMsg           "Really delete current node ?"
  8372. #define SaveFileBeforeMsg         "Save file before ?"
  8373. #define StopGameMsg               "Stop current game ?"
  8374. #define RemoveStonesMsg           "Remove further moves ?"
  8375. #define NodeNameMsg               "Enter node name :"
  8376. #define MailNoMoveMsg             "No move done : really quit ?"
  8377. #define MailConfirmMoveMsg        "Confirm your move ?"
  8378.  
  8379. #define YesLabel                  "Yes"
  8380. #define NoLabel                   "No"
  8381. #define CancelLabel               "Cancel"
  8382. #define SaveLabel                 "Save"
  8383. #define LoadLabel                 "Load"
  8384. #define EditLabel                 "Edit"
  8385. #define QuitLabel                 "Quit"
  8386. #define ReplaceLabel              "Replace"
  8387. #define OkLabel                   "Ok"
  8388. #define DeleteLabel               "Delete"
  8389. #define RemoveLabel               "Remove"
  8390. #define StopLabel                 "Stop"
  8391. #define ConfirmLabel              "Confirm"
  8392.  
  8393. #define ReadOnlyMsg               " File is read-only "
  8394. #define MemoryErrorMsg            " Memory error "
  8395.  
  8396. #define UsageString               "\
  8397. XGoban version 1.0\n\n\
  8398. Usage : \n\
  8399.    xgoban [ <toolkit options> ... ] [ <options> ... ] [ <file> ]  \n\n\
  8400. where options include : \n\
  8401.    -help                         print out this message  \n\
  8402.    -size         <size>          set goban size          \n\
  8403.    -handicap     <handicap>      setup handicap stones   \n\
  8404.    -path         <path>          path for smart-go files \n\
  8405.    -pointSize    <pointSize>     size of points in pixels\n\
  8406.    -silent                       turn off bell           \n\
  8407.    -nonum                        turn off auto numbering \n\
  8408.    -versatile                    turn off strict moves   \n\
  8409.    -black        <blackPlayer>   black player            \n\
  8410.    -white        <whitePlayer>   white player            \n\
  8411.    [-short | -s]                 short save mode         \n\
  8412.    [-mail  | -m] <filename>      mail mode               \n\
  8413. \n"
  8414.  
  8415. #define HelpString                "\n\
  8416.                XGoban 1.0    by  A. de Maricourt  (c) 1992                    \n\
  8417. \n\
  8418. \n\
  8419.    a      : Append stones to diagram       Bt1    : select variation          \n\
  8420.    b      : Black to play                           or move forward           \n\
  8421.    d      : select Diagram                 Bt2    : select diagram            \n\
  8422.    e      : Edit current file              Bt3    : move backward             \n\
  8423.    l      : Load file                                                         \n\
  8424.    p      : Pass                           S-Bt1  : make next move            \n\
  8425.    q      : Quit                           S-Bt3  : delete move               \n\
  8426.    s      : Save                                                              \n\
  8427.    v      : View                           CS-Bt1 : make variation move       \n\
  8428.    w      : White to play                  CS-Bt2 : make variation diagram    \n\
  8429.    z      : siZe                                                              \n\
  8430.    >      : move forward                   C-Bt1  : add letter                \n\
  8431.    <      : move backward                  C-Bt2  : add mark                  \n\
  8432.    }      : next comment                   C-Bt3  : delete letter             \n\
  8433.    {      : previous comment                                                  \n\
  8434.    ]      : next variation branch        diagram editing :                    \n\
  8435.    [      : previous variation branch      Bt1    : add black stone           \n\
  8436.    ?      : help                           Bt2    : add white stone           \n\
  8437.    i      : event Informations             Bt3    : remove stone              \n\
  8438.    CS-P   : make variation pass            Esc    : diagram done              \n\
  8439.  \n\
  8440.                    Press any key or click to dismiss ...      \n\
  8441. \n"
  8442.  
  8443. #define Max(x,y)                  ((x)>(y)?(x):(y))
  8444. #define Min(x,y)                  ((x)>(y)?(y):(x))
  8445. #define Abs(x)                    ((x)>0?(x):-(x))
  8446.  
  8447. extern Widget      w_toplevel;
  8448. extern Widget      w_goban;
  8449. extern Widget      w_menu;
  8450. extern Widget      c_toplevel;
  8451. extern Widget      c_comment;
  8452. extern Widget      w_second_toplevel;
  8453. extern Widget      w_second_form;
  8454. extern Widget      w_second_goban;
  8455.  
  8456. extern SG_NodePtr  tree;
  8457. extern SG_NodePtr  current_node;
  8458. extern SG_NodePtr  mail_node;
  8459.  
  8460. extern Mode        current_mode;
  8461.  
  8462. extern Player      black_player;
  8463. extern Player      white_player;
  8464. extern int         handicap;
  8465. extern int         board_size;
  8466. extern int         second_player;
  8467.  
  8468. extern Boolean     edit;
  8469. extern Boolean     modified;
  8470. extern int         beep;
  8471. extern Boolean     autonum;
  8472. extern Boolean     strict;
  8473. extern Boolean     short_print;
  8474.  
  8475. extern char        file_name[512];
  8476. extern char        mail_file_name[512];
  8477. extern char       *path;
  8478.  
  8479. extern Boolean     delete_confirm;
  8480.  
  8481. extern void             PopupDialog      ();
  8482. extern void             makeDialogWindow ();
  8483. extern void             makeEventWindow  ();
  8484.  
  8485. extern void             CenterWindow    ();
  8486. extern Boolean          LoadFile        ();
  8487. extern Boolean          SaveFile        ();
  8488. extern void             ShowCursor      ();
  8489.  
  8490.  
  8491. extern void             ShowTmpProperty ();
  8492. extern void             HideTmpProperty ();
  8493. extern void             ShowProperty    ();
  8494. extern void             HideProperty    ();
  8495.  
  8496. extern void             Edit            ();
  8497.  
  8498. extern int              Play            ();
  8499. extern void             Unplay          ();
  8500. extern void             StartDiagram    ();
  8501. extern void             AddStone        ();
  8502. extern unsigned char   *EndDiagram      ();
  8503.  
  8504. extern void             signalMove      ();
  8505. extern void             stopGame        ();
  8506. extern void             startGame       ();
  8507.  
  8508.  
  8509. #define RedisplayBoard() { GbRedisplayBoard (w_goban); if (w_second_goban != NULL) GbRedisplayBoard (w_second_goban); }
  8510. #endif
  8511. SHAR_EOF
  8512. fi # end of overwriting check
  8513. if test -f 'Goban.doc'
  8514. then
  8515.     echo shar: will not over-write existing file "'Goban.doc'"
  8516. else
  8517. cat << \SHAR_EOF > 'Goban.doc'
  8518. Goban Widget 
  8519. ------------
  8520.  
  8521.  The Goban widget displays a full or partial go board within a rectangular area and 
  8522.  allows an application to put or remove stones on it. The application can also draw 
  8523.  numbers on stones, and marks (consisting of a one or two characters string) on stones 
  8524.  or empty points. It has no knowledge of the game and thus doesn't remove dead stones 
  8525.  if any (it is the application's responsability).
  8526.  
  8527.  For every position specification, the coordinate system uses an x axis going from left
  8528.  to right, and an y axis going from bottom to top.
  8529.  
  8530. Resources
  8531. ---------
  8532.  
  8533.  Name               Class          RepType        Default Value
  8534.  ----               -----          -------        -------------
  8535.  autoRedisplay         AutoRedisplay      Boolean         True
  8536.  background           Background      Pixel          XtDefaultBackground
  8537.  blackStoneBackground  Background      Pixel          black
  8538.  blackStoneBorder      BorderColor      Pixel          black
  8539.  blackStoneForeground  Foreground      Pixel          white
  8540.  border               BorderColor      Pixel          XtDefaultForeground
  8541.  borderWidth           BorderWidth      Dimension      1
  8542.  cursor                Cursor             Integer         GbGrayCursor
  8543.  destroyCallback       Callback          Pointer      NULL
  8544.  displayCoordinates    DisplayCoordinates Boolean      True
  8545.  font                  Font               XFontStruct*    fixed
  8546.  foreground            Foreground         Pixel           XtDefaultForeground
  8547.  gameSize              Size               Dimension       19
  8548.  height               Height          Dimension      computed at create
  8549.  mappedWhenManaged     MappedWhenManaged  Boolean      True
  8550.  pointSize             Size               Dimension       24
  8551.  sensitive           Sensitive      Boolean      True
  8552.  viewBottom            Position           Position        computed at create
  8553.  viewLeft              Position           Position        computed at create
  8554.  viewRight             Position           Position        computed at create
  8555.  viewTop               Position           Position        computed at create
  8556.  whiteStoneBackground  Background      Pixel          white
  8557.  whiteStoneBorder      BorderColor      Pixel          black
  8558.  whiteStoneForeground  Foreground      Pixel          black
  8559.  width               Width          Dimension      computed at create
  8560.  x               Position          Position      0
  8561.  y               Position          Position      0
  8562.  
  8563.  autoRedisplay          If this resource is True, then all changes on the widget (put or remove
  8564.               stones, put numbers or marks) will be immediatly flushed to the screen.
  8565.               This can be set to False in conjonction with GbRedisplay in order to 
  8566.               improve the speed when displaying a position.
  8567.  
  8568.  background          As usual.
  8569.  backgroundPixmap     As usual.
  8570.  
  8571.  blackStoneBackground This color will be used to fill the black stones (usually black)
  8572.  blackStoneBorder     This color will be used to draw a circle arround the black stones. This is
  8573.                       usefull with white stones to delimit the circumference of the stone.
  8574.  blackStoneForeground This color will be used to draw marks and numbers on black stones.
  8575.  
  8576.  border              As usual.
  8577.  borderWidth          As usual.
  8578.  
  8579.  
  8580.  cursor              The cursor that will be displayed : should be GbCGrayStone, GbCWhiteStone
  8581.               or GbCBlackStone or a valid cursorFont ID.
  8582.  
  8583.  destroyCallback      As usual.
  8584.  
  8585.  font              The font that will be used to put numbers and marks on the board and to
  8586.               display the coordinate marks.
  8587.  
  8588.  foreground          As usual.
  8589.  
  8590.  gameSize          The board size : board is always square and its size must range between
  8591.               2 and 19.
  8592.  
  8593.  height              As usual.
  8594.  
  8595.  mappedWhenManaged    As usual.
  8596.  
  8597.  displayCoordinates   If this resource is True, then the coordinate marks will be displayed 
  8598.               around the board.
  8599.  
  8600.  pointSize          The distance in pixels between points.
  8601.      
  8602.  sensitive          As usual.
  8603.  
  8604.  viewBottom           The bottom of the partial goban that is viewed. Must range between 1 and
  8605.               gameSize - 1.
  8606.  
  8607.  viewLeft          The left of the partial goban that is viewed. Must range between 1 and
  8608.               gameSize - 1.
  8609.  
  8610.  viewRight          The right of the partial goban that is viewed. Must range between 
  8611.               viewLeft + 1 and gameSize.
  8612.  
  8613.  viewTop          The top of the partial goban that is viewed. Must range between
  8614.               viewBottom + 1 and gameSize.
  8615.  
  8616.  width              As usual.
  8617.  
  8618.  whiteStoneBackground This color will be used to fill the white stones (usually white)
  8619.  whiteStoneBorder     This color will be used to draw a circle arround the white stones.
  8620.  whiteStoneForeground This color will be used to draw marks and numbers on white stones.
  8621.  
  8622.  x              As usual.
  8623.  y              As usual.
  8624.  
  8625.  
  8626. Procedures provided for application
  8627. -----------------------------------  
  8628.  
  8629. void GbRedisplayBoard (w)
  8630. GobanWidget w;
  8631.  
  8632.  Redisplay the entire board <w> on the screen.
  8633.  
  8634. void GbClearBoard (w)
  8635. GobanWidget w;
  8636.  
  8637.  Remove all stones of the board <w> and call GbRedisplayBoard.
  8638.  
  8639.  
  8640. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone, } GbPointState;
  8641.  
  8642. void GbSetPoint (w, x, y, color)     
  8643. GobanWidget  w;
  8644. Position     x;
  8645. Position     y; 
  8646. GbPointState color;
  8647.  
  8648.  Put a stone of color <color> at location <x><y> on the board <w>.
  8649.  If color is GbEmptyPoint, then the stone (if any) is removed from location <x><y>.
  8650.  All marks on this point are removed.
  8651.  If autoRedisplay if set to False the change will not be visible on the screen until
  8652.  the application calls GbRedisplay.
  8653.  
  8654.  
  8655. void GbSetNum (w, x, y, num)
  8656. GobanWidget  w;
  8657. Position     x;
  8658. Position     y;
  8659. unsigned int num;
  8660.  
  8661.  Draw the number <num> on the stone at location <x><y> on the board <w>.
  8662.  <num> must range between 0 and 999 and no number is displayed if there is no stone
  8663.  at this location.
  8664.  If <num> is equal to 0, all previous num (if any) is removed from stone.
  8665.  When the representation of <num> is to bigger than the stone size (according to font size) 
  8666.  no number is displayed.
  8667.  
  8668.  
  8669. void GbSetMark (w, x, y, mark1, mark2)
  8670. GobanWidget   w;
  8671. Position      x;
  8672. Position      y;
  8673. unsigned char mark1;
  8674. unsigned char mark2;
  8675.  
  8676.  Draw the two characters mark at location <x><y> on the board <w>.
  8677.  <x><y> may be an empty point.
  8678.  If <mark1> and <mark2> are equal to 0, the previous mark (if any) is removed from point.
  8679.  If <mark2> is equal to 0, only one character will be displayed.
  8680.  If <mark1> is equal to 0, <mark2> can be one of GbMSquareMark, GbMTriangleMark, GbMVCrossMark, 
  8681.  GbMDCrossMark or GbMDiamondMark. In this case, geometric marks are drawn.
  8682.  When the representation of the mark is to bigger than the stone size (according to font size) 
  8683.  no mark is displayed.
  8684.  GbRemoveMark(w,x,y) is defined as a macro call for GbSetMark(w,x,y,0,0).
  8685.  
  8686.  
  8687. Boolean GbGetStoneFromPosition (w, x, y)
  8688. GobanWidget   w;
  8689. Position     *x;
  8690. Position     *y;
  8691.  
  8692.  Provide a way to know on what point occurs a mouse event.
  8693.  If the event occurs on a valid point on the board, GbGetStoneFromEvent returns TRUE,
  8694.  and <x> <y> variables are set to the coordinates of that point.
  8695.  If not, GbGetStoneFromEvent returns FALSE and <event> is unchanged.
  8696.  
  8697.  
  8698. Boolean GbGetPositionFromStone (w, x, y)
  8699. GobanWidget   w;
  8700. Position     *x;
  8701. Position     *y;
  8702.  
  8703.  Provide a way to know what are the coordinates (in pixel) for the center of a given 
  8704.  point. It works as GbGetStoneFromPosition.
  8705.  Those functions are not reverse of each other ...
  8706.  
  8707. SHAR_EOF
  8708. fi # end of overwriting check
  8709. if test -f 'xgoban.doc'
  8710. then
  8711.     echo shar: will not over-write existing file "'xgoban.doc'"
  8712. else
  8713. cat << \SHAR_EOF > 'xgoban.doc'
  8714.  
  8715.  
  8716.  
  8717. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  8718.  
  8719.  
  8720.  
  8721. NAME
  8722.      xgoban - X11 files editor for the game of go / interface  to
  8723.      gnugo and wally
  8724.  
  8725. SYNOPSIS
  8726.      xgoban [ -toolkitoptions ... ] [ -options ... ] [ _f_i_l_e_n_a_m_e ]
  8727.  
  8728. DESCRIPTION
  8729.      _x_g_o_b_a_n works under 3 major modes : Edit, Play and Mail.
  8730.  
  8731.      In Edit mode, the _x_g_o_b_a_n program displays  a  go  board  and
  8732.      allows  the  user  to  edit  go files. It can read and write
  8733.      files with the Smart-Go format. When started in  Edit  mode,
  8734.      _x_g_o_b_a_n  shows 2 windows : one for the board and the other to
  8735.      display comments.  The title of the comment window is set to
  8736.      the  name of current node if there is one.  The title of the
  8737.      board is set to the name of the current game.
  8738.  
  8739.      In Play mode, _x_g_o_b_a_n can be used to play against go programs
  8740.      (currently  supported  :  wally  and gnugo) or against human
  8741.      opponent.  The game can also be saved with the Smart-Go for-
  8742.      mat.   When  started in Play mode, the program can switch to
  8743.      Edit mode and thus allows the user to edit the played  game.
  8744.      There is no comment window in this mode.
  8745.  
  8746.      Mail mode is designed to be used  in  combination  with  the
  8747.      _m_a_i_l_g_o script from Adrian Mariano.
  8748.  
  8749. OPTIONS
  8750.      _x_g_o_b_a_n accepts all of  the  standard  toolkit  command  line
  8751.      options as well as the following :
  8752.  
  8753.      -size _s_i_z_e
  8754.              This option specifies the size of the goban  :  _s_i_z_e
  8755.              must  range between 2 and 19. It can be used in Play
  8756.              or Edit mode. The default size is 19.
  8757.  
  8758.      -handicap _h_a_n_d_i_c_a_p
  8759.              In Play mode, this option specifies  the  number  of
  8760.              handicap  stones  that  are  to  be put on the goban
  8761.              before the game starts. Legal  values  for  _h_a_n_d_i_c_a_p
  8762.              depend  on  the size of the board and on the playing
  8763.              program. Whitin Edit mode, a first node  is  created
  8764.              and  handicap stones are put under the AddBlack pro-
  8765.              perty.
  8766.  
  8767.      -black _b_l_a_c_k_p_l_a_y_e_r
  8768.              This options indicates the name of the black player.
  8769.              _x_g_o_b_a_n  is  started within Play mode and _b_l_a_c_k_p_l_a_y_e_r
  8770.              is added on the root node under the PlayerBlack pro-
  8771.              perty.  _x_g_o_b_a_n recognize 2 program names : gnugo and
  8772.              wally.  When _b_l_a_c_k_p_l_a_y_e_r is one of them, an  attempt
  8773.  
  8774.  
  8775.  
  8776. Sun Release 4.1     Last change: 15 May 1992                    1
  8777.  
  8778.  
  8779.  
  8780.  
  8781.  
  8782.  
  8783. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  8784.  
  8785.  
  8786.  
  8787.              is made to run the corresponding program (which must
  8788.              be found  using  the  current  environment  variable
  8789.              PATH).
  8790.  
  8791.      -white _w_h_i_t_e_p_l_a_y_e_r
  8792.              This option is the same as -black, but for the white
  8793.              player.
  8794.  
  8795.      -path _p_a_t_h
  8796.              This option  specifies  the  path  where  files  are
  8797.              searched  before  loading  them.   A _p_a_t_h _i_s _a _c_o_m_m_a
  8798.              _s_e_p_a_r_a_t_e_d _l_i_s_t _o_f _d_i_r_e_c_t_o_r_i_e_s.
  8799.  
  8800.      -pointSize _s_i_z_e
  8801.              This option specifies the size in pixels for a small
  8802.              square of the board.
  8803.  
  8804.      -nonumber
  8805.              This option turns off the automatic numbering facil-
  8806.              ity.
  8807.  
  8808.      -silent
  8809.              This option turns off the bell.  -beep _v_o_l_u_m_e
  8810.              This option specifies the volume of the bell when it
  8811.              is  not turned off.  Legal values range between -100
  8812.              and 100. I am not sure it will work on all keyboards
  8813.              ...  Default value is 0.
  8814.  
  8815.      -versatile
  8816.              This option turns off  strong  verification  of  the
  8817.              tree : see below.  This also turns off the automatic
  8818.              numbering facility.
  8819.  
  8820.      -help
  8821.              Displays a list of allowed options.  _x_g_o_b_a_n  is  not
  8822.              started.
  8823.  
  8824.      [ -mail | -m ] _m_a_i_l_f_i_l_e
  8825.              Start _x_g_o_b_a_n in Mail mode. A file should  be  speci-
  8826.              fied  with _f_i_l_e_n_a_m_e argument. This file is read, and
  8827.              _x_g_o_b_a_n automatically moves to the end  of  the  main
  8828.              variation.  When you quit _x_g_o_b_a_n, the game tree will
  8829.              be saved to _m_a_i_l_f_i_l_e. The exit value will be 0 if  a
  8830.              move  has been made and 1 otherwise. This option has
  8831.              been designed to work with the  _m_a_i_l_g_o  script  from
  8832.              Adrian Mariano (adrian@u.washington.edu).  -m option
  8833.              is for compatibility with _m_g_t.
  8834.  
  8835.      [ -short | -s ]
  8836.              This option forces _x_g_o_b_a_n to  save  files  in  short
  8837.              mode  :  only  uppercase  letters  of  keywords  are
  8838.              printed, and there is no carriage return. -s  option
  8839.  
  8840.  
  8841.  
  8842. Sun Release 4.1     Last change: 15 May 1992                    2
  8843.  
  8844.  
  8845.  
  8846.  
  8847.  
  8848.  
  8849. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  8850.  
  8851.  
  8852.  
  8853.              is for compatibility with _m_g_t.
  8854.  
  8855.      -stipple<x>
  8856.              These options set the backgroundPixmap ressource  of
  8857.              the  Goban  widget  to  predefined gray pixmaps (<x>
  8858.              must be one of 1, 2 or 3). You may like  it  if  you
  8859.              use  a  black  and white display. This is an idea of
  8860.              Stephen Coffin.
  8861.  
  8862.      One of -white, -black option starts  _x_g_o_b_a_n  in  Play  mode.
  8863.      Default is Edit mode.
  8864.  
  8865. OPERATIONS
  8866.      When used in Edit mode, _x_g_o_b_a_n allows the user  to  edit  go
  8867.      files.   Commands  are entered form the keyboard or from the
  8868.      mouse. Most of the window that are poped down contain a Con-
  8869.      firm  (or  Yes)  an  a  Cancel (or No) button. Escape key is
  8870.      associated with the Cancel button, while Return Key is asso-
  8871.      ciated with the Confirm button.
  8872.  
  8873.      When an action is not allowed (because the mode your are in)
  8874.      you  will  hear  a  beep.  Of course you hear nothing if you
  8875.      turned the bell off.
  8876.  
  8877.      First are commands that can be used to only view a file :
  8878.  
  8879.      >       Moves to next node along the tree and  displays  its
  8880.              properties.
  8881.  
  8882.      <       Hides properties of current node and moves to previ-
  8883.              ous node along the tree.
  8884.  
  8885.      }       Goes down along the tree until a commented node or a
  8886.              variation node is seen.
  8887.  
  8888.      {       Goes up along the tree until a commented node or the
  8889.              top of the tree is seen.
  8890.  
  8891.      ]       Goes down along the tree until a variation  node  or
  8892.              the bottom of the tree is seen.
  8893.  
  8894.      [       Goes up along the tree until a variation node or the
  8895.              top of the tree is seen.
  8896.  
  8897.      ?       Pops down a short help window.
  8898.  
  8899.      q       Exits from the program.
  8900.  
  8901.      l       Loads a file.
  8902.  
  8903.      s       Saves the current tree to a file.
  8904.  
  8905.  
  8906.  
  8907.  
  8908. Sun Release 4.1     Last change: 15 May 1992                    3
  8909.  
  8910.  
  8911.  
  8912.  
  8913.  
  8914.  
  8915. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  8916.  
  8917.  
  8918.  
  8919.      i       Pops down a window that contains some properties  of
  8920.              the current event (GameName, PlayerWhite, WhiteRank,
  8921.              WhiteSpecies ... and  GameComment)  You  can  change
  8922.              these properties or just view them.
  8923.  
  8924.      A-Z     When there are some variations, an uppercase  letter
  8925.              is  displayed  on  each  point corresponding to each
  8926.              possible move.  The A-Z keys can be used  to  select
  8927.              the corresponding node.  See also Btn2 action
  8928.  
  8929.      Btn1    When there are variations and the mouse points at  a
  8930.              marked  point  (with  uppercase letter), selects the
  8931.              corresponding node.  Otherwise it is the same as key
  8932.              `>'.
  8933.  
  8934.      Btn2    It can arise that not all variations can  be  marked
  8935.              with  an  uppercase  letter  :  if  a variation is a
  8936.              diagram (having AddBlack, AddWhite or AddEmpty  pro-
  8937.              perty),  if  there  is  variations on the same level
  8938.              with differently colored move (Black and White),  or
  8939.              if  there  is  a pass move. In this case, the cursor
  8940.              will be gray.  Pressing the middle button pops up  a
  8941.              menu  where  all  variations  are  listed.   You can
  8942.              choose the one you want to display
  8943.  
  8944.      Btn3    Same as key `<'.
  8945.  
  8946.      Following commands can be used to change a tree :
  8947.  
  8948.      v       Enters the View sub-mode  and  allows  the  user  to
  8949.              select  a partial view of the board. A VieW property
  8950.              is then attached to the node.
  8951.  
  8952.      z       Enters the Size sub-mode and allows the user to  set
  8953.              the  size  of  the board.  SiZe property can only be
  8954.              change at Event node (see below) and  the  board  is
  8955.              cleared.
  8956.  
  8957.      w       Set the PLayer property to  white  for  the  current
  8958.              node.  The next move will be a white stone.
  8959.  
  8960.      b       Set the PLayer property to  black  for  the  current
  8961.              node.  The next move will a black stone.
  8962.  
  8963.      n       Prompt a dialog to edit the name of current node.
  8964.  
  8965.      a       If the current node is a diagram, Enters the Diagram
  8966.              sub-mode and allows the user to edit the diagram.
  8967.  
  8968.      Shift Btn1
  8969.              Adds a move after the current node. The new node  is
  8970.              created  with  property  White or Black according to
  8971.  
  8972.  
  8973.  
  8974. Sun Release 4.1     Last change: 15 May 1992                    4
  8975.  
  8976.  
  8977.  
  8978.  
  8979.  
  8980.  
  8981. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  8982.  
  8983.  
  8984.  
  8985.              the color of the last move. The mouse must point  on
  8986.              the intersection where you want to put the stone.
  8987.  
  8988.      Shift Btn3
  8989.              Deletes the current node and all its sub-nodes.
  8990.  
  8991.      Ctrl Shift Btn1
  8992.              Makes a variation move.  The color is  the  same  as
  8993.              the  PLayer  property  of  previous node.  The mouse
  8994.              must point on the intersection where you want to put
  8995.              a the stone.
  8996.  
  8997.      Ctrl Shift P
  8998.              Makes a variation move which is a  pass  move.   The
  8999.              color is the same as the PLayer property of previous
  9000.              node.
  9001.  
  9002.      Ctrl Shift Btn2
  9003.              Makes a variation diagram.  It enters in the Diagram
  9004.              sub-mode (see below) to allow the user to put stones
  9005.              on the diagram.
  9006.  
  9007.      Ctrl Btn1
  9008.              Puts a letter (downcase) on the mouse pointed inter-
  9009.              section.
  9010.  
  9011.      Ctrl Btn2
  9012.              Puts a triangle mark on the mouse pointed  intersec-
  9013.              tion.
  9014.  
  9015.      Ctrl Btn3
  9016.              Remove any letter or mark  from  the  mouse  pointed
  9017.              intersection.
  9018.  
  9019.      There are sub-modes of Edit mode that can be  Diagram,  View
  9020.      or  Size.  Whitin these sub-modes, actions are changed.  The
  9021.      Diagram sub-mode is signaled by a `point' cursor, while  the
  9022.      View  and  Size  sub-modes are signalled by the `upper-left-
  9023.      corner' cursor.
  9024.  
  9025.      Escape
  9026.              Quit the Diagram, Size or View sub-mode.
  9027.  
  9028.      Btn1    Within Diagram sub-mode : puts a black stone on  the
  9029.              mouse pointed intersection.
  9030.  
  9031.      Btn2    Within Diagram sub-mode : puts a white stone on  the
  9032.              mouse pointed intersection.
  9033.  
  9034.      Btn3    Within Diagram sub-mode : removes any stone from the
  9035.              mouse pointed intersection.
  9036.  
  9037.  
  9038.  
  9039.  
  9040. Sun Release 4.1     Last change: 15 May 1992                    5
  9041.  
  9042.  
  9043.  
  9044.  
  9045.  
  9046.  
  9047. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  9048.  
  9049.  
  9050.  
  9051.      Btn1 Press
  9052.              Within View or Size sub-mode : start draging a  rec-
  9053.              tangle to select the view or the size.
  9054.  
  9055.      Btn1 Motion
  9056.              Within View or Size sub-mode : drags the rectangle.
  9057.  
  9058.      Btn1 Release
  9059.              Within View or Size sub-mode : stop draging the rec-
  9060.              tangle  and  add  a  VieW  or  SiZe  property to the
  9061.              current node.
  9062.  
  9063. GAME TREE
  9064.      Game trees that can be  made  are  slightly  different  from
  9065.      Smart-Go  format.   I  wanted  them to be closer to a `real'
  9066.      game.
  9067.  
  9068.      Node  are  either  of  type  Diagram  (they  have  AddBlack,
  9069.      AddWhite  or  AddEmpty  property) or of type Move (they have
  9070.      Black or White property).   Only  a  Diagram  can  have  the
  9071.      PLayer  property  (default  is  PLayer[B]), which can be set
  9072.      only if the diagram does not have a successor.  A file is  a
  9073.      collection  of  Event  nodes,  which are of type Diagram.  A
  9074.      node can have one or more successors (in which case, succes-
  9075.      sors  are  variations).   If  a node has only one successor,
  9076.      that successor can only be of type Move.  If a  node  is  of
  9077.      type  Move, the color of any successor can only be the oppo-
  9078.      site of its color.  If a node is of type Diagram, the  color
  9079.      of  any  successor is the same as the PLayer property of the
  9080.      diagram.
  9081.  
  9082.      However, I noticed that most  of  the  avaible  game  record
  9083.      doesn't  match  these  restrictions.   _x_g_o_b_a_n  can read such
  9084.      unrestricted files but not edit them and create  new  unres-
  9085.      tricted  nodes.  Thus I added a -versatile option that turns
  9086.      off strong verification for accepted colors of nodes.   When
  9087.      you  specify  -versatile  option,  you can change the PLayer
  9088.      property even at Move nodes or at any node that already have
  9089.      a successor.
  9090.  
  9091. RESOURCES
  9092.      Resources can be set via xrdb  or  in  the  .Xdefault  file.
  9093.      Default resources are as follow :
  9094.  
  9095.           XGoban*size : 19
  9096.           XGoban*handicap : 0
  9097.           XGoban*path : "."
  9098.           XGoban*pointSize : 26
  9099.           XGoban*autonum : True
  9100.           XGoban*beep : True
  9101.           XGoban*versatile : False
  9102.  
  9103.  
  9104.  
  9105.  
  9106. Sun Release 4.1     Last change: 15 May 1992                    6
  9107.  
  9108.  
  9109.  
  9110.  
  9111.  
  9112.  
  9113. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  9114.  
  9115.  
  9116.  
  9117.      You can change the board color if you  want.  Remember  that
  9118.      the  board  background shouldn't be black : thus, on a black
  9119.      and white display the only valid background is white.
  9120.  
  9121.           XGoban*goban.background : tan1
  9122.           XGoban*goban.foreground : black
  9123.  
  9124.      But everything else can be black on a  white  background  if
  9125.      you like it :
  9126.  
  9127.           XGoban*background  : black
  9128.           XGoban*foreground  : white
  9129.           XGoban*borderColor : white
  9130.  
  9131.      You can also control the geometry of windows :
  9132.  
  9133.           XGoban.geometry         : 500x500+30+30
  9134.           XGoban.comment.geometry : 500x200+30+580
  9135.  
  9136.      You can change the translation table for  the  goban  Widget
  9137.      (see  xgoban.c  for the default translation table). You must
  9138.      be carefull by doing this because of  multiple  modes.  Some
  9139.      action  work only in a specified mode, and you can bind them
  9140.      to the same event if they don't work in the same  mode.  But
  9141.      don't  bind  two  actions  working in the same mode with the
  9142.      same event ... you may have trouble.  A good way  to  change
  9143.      the  translation table is just to change the left part (name
  9144.      of events) and to leave the right part (action)  as  it  is.
  9145.      To  change  the translation table see a doc on X Toolkit and
  9146.      modify your .Xdefaults accordly.
  9147.  
  9148. EXAMPLES
  9149.      To read and edit the file 001_001.s :
  9150.           xgoban 001_001.s
  9151.      To play black against gnugo with 5 handicap stones :
  9152.           xgoban -handicap 5 -white gnugo
  9153.      To play white against wally :
  9154.           xgoban -black wally
  9155.      To make wally play against gnugo :
  9156.           xgoban -black wally -white gnugo
  9157.  
  9158. BUGS
  9159.      When read, a file is supposed to  be  syntacticaly  correct.
  9160.      This  is normally the case, when you didn't create this file
  9161.      by hand ...
  9162.  
  9163.      File names are limited to 512 bytes.
  9164.  
  9165.      -pointSize option doesn't work with smaller size than 19x19.
  9166.      The  board  size  is calculated as if it were a 19x19 board,
  9167.      and then the board size is changed whitin the same square.
  9168.  
  9169.  
  9170.  
  9171.  
  9172. Sun Release 4.1     Last change: 15 May 1992                    7
  9173.  
  9174.  
  9175.  
  9176.  
  9177.  
  9178.  
  9179. XGOBAN(6)                GAMES AND DEMOS                XGOBAN(6)
  9180.  
  9181.  
  9182.  
  9183.      Resign is not supported in Play mode, and you can't use  the
  9184.      counting features of gnugo or wally.
  9185.  
  9186. SEE ALSO
  9187.      _m_g_t from Greg Hale.
  9188.      _m_a_i_l_g_o from Adrian Mariano.
  9189.  
  9190.      _m_g_t,   _m_a_i_l_g_o   and   game   records   are   available    at
  9191.      milton.u.washington.edu.
  9192.  
  9193. AUTHORS
  9194.      Antoine Dumesnil de Maricourt (dumesnil@etca.fr)
  9195.  
  9196.  
  9197.  
  9198.  
  9199.  
  9200.  
  9201.  
  9202.  
  9203.  
  9204.  
  9205.  
  9206.  
  9207.  
  9208.  
  9209.  
  9210.  
  9211.  
  9212.  
  9213.  
  9214.  
  9215.  
  9216.  
  9217.  
  9218.  
  9219.  
  9220.  
  9221.  
  9222.  
  9223.  
  9224.  
  9225.  
  9226.  
  9227.  
  9228.  
  9229.  
  9230.  
  9231.  
  9232.  
  9233.  
  9234.  
  9235.  
  9236.  
  9237.  
  9238. Sun Release 4.1     Last change: 15 May 1992                    8
  9239.  
  9240.  
  9241.  
  9242. SHAR_EOF
  9243. fi # end of overwriting check
  9244. if test -f 'xgoban.man'
  9245. then
  9246.     echo shar: will not over-write existing file "'xgoban.man'"
  9247. else
  9248. cat << \SHAR_EOF > 'xgoban.man'
  9249. .TH XGOBAN 6  "15 May 1992"
  9250. .SH NAME
  9251. xgoban - X11 files editor for the game of go / 
  9252. interface to gnugo and wally
  9253. .SH SYNOPSIS
  9254. .B xgoban 
  9255. .B \-toolkitoptions ...
  9256. ]
  9257. .B \-options ... 
  9258. ]
  9259. [ \fIfilename\fP ]
  9260. .SH DESCRIPTION
  9261. .PP
  9262. \fIxgoban\fP works under 3 major modes : Edit, Play and Mail.
  9263. .LP
  9264. In Edit mode, the \fIxgoban\fP program displays a go board and allows 
  9265. the user to edit go files. 
  9266. It can read and write files with the Smart-Go format. 
  9267. When started in Edit mode, \fIxgoban\fP shows 2 windows : one for the
  9268. board and the other to display comments.
  9269. The title of the comment window is set to the name of current node if
  9270. there is one.
  9271. The title of the board is set to the name of the current game.
  9272. .LP
  9273. In Play mode, \fIxgoban\fP can be used to play against go
  9274. programs (currently supported : wally and gnugo) or against human opponent.
  9275. The game can also be saved with the Smart-Go format.
  9276. When started in Play mode, the program can switch to Edit mode and thus
  9277. allows the user to edit the played game.
  9278. There is no comment window in this mode.
  9279. .LP
  9280. Mail mode is designed to be used in combination with the \fImailgo\fP
  9281. script from Adrian Mariano.
  9282. .SH OPTIONS
  9283. \fIxgoban\fP accepts all of the standard toolkit command line options as
  9284. well as the following :
  9285. .TP 8
  9286. .B \-size \fIsize\fP
  9287. This option specifies the size of the goban : \fIsize\fP must range between
  9288. 2 and 19. It can be used in Play or Edit mode. The default size is 19.
  9289. .TP 8
  9290. .B \-handicap \fIhandicap\fP
  9291. In Play mode, this option specifies the number of handicap stones that 
  9292. are to be put on the goban before the game starts. 
  9293. Legal values for \fIhandicap\fP depend on the size of the board and on
  9294. the playing program. 
  9295. Whitin Edit mode, a first node is created and handicap stones are put 
  9296. under the AddBlack property.
  9297. .TP 8
  9298. .B \-black \fIblackplayer\fP
  9299. This options indicates the name of the black player. \fIxgoban\fP 
  9300. is started within Play mode and \fIblackplayer\fP is added on the root 
  9301. node under the PlayerBlack property. 
  9302. \fIxgoban\fP recognize 2 program names : gnugo and wally.
  9303. When \fIblackplayer\fP is one of them, an attempt is made to run the
  9304. corresponding program (which must be found using the current environment variable
  9305. PATH).
  9306. .TP 8
  9307. .B \-white \fIwhiteplayer\fP
  9308. This option is the same as -black, but for the white player.
  9309. .TP 8
  9310. .B \-path \fIpath\fP
  9311. This option specifies the path where files are searched before loading them.
  9312. A \fIpath\fp is a comma separated list of directories.
  9313. .TP 8
  9314. .B \-pointSize \fIsize\fP
  9315. This option specifies the size in pixels for a small square of the board.
  9316. .TP 8
  9317. .B \-nonumber
  9318. This option turns off the automatic numbering facility.
  9319. .TP 8
  9320. .B \-silent
  9321. .br
  9322. This option turns off the bell.
  9323. .B \-beep \fIvolume\fP
  9324. .br
  9325. This option specifies the volume of the bell when it is not turned off.
  9326. Legal values range between -100 and 100. 
  9327. I am not sure it will work on all keyboards ...
  9328. Default value is 0. 
  9329. .TP 8
  9330. .B \-versatile
  9331. This option turns off strong verification of the tree : see below.
  9332. This also turns off the automatic numbering facility.
  9333. .TP 8
  9334. .B \-help
  9335. .br
  9336. Displays a list of allowed options.
  9337. \fIxgoban\fP is not started.
  9338. .TP 8
  9339. .B [ \-mail | \-m ] \fImailfile\fP
  9340. Start \fIxgoban\fP in Mail mode. A file should be specified with 
  9341. \fIfilename\fP argument. This file is read, and \fIxgoban\fP automatically
  9342. moves to the end of the main variation. 
  9343. When you quit \fIxgoban\fP, the game tree will be saved to
  9344. \fImailfile\fP. The exit value will be 0 if a move has been made
  9345. and 1 otherwise. This option has been designed to work with the
  9346. \fImailgo\fP script from Adrian Mariano (adrian@u.washington.edu).
  9347. \-m option is for compatibility with \fImgt\fP.
  9348. .TP 8
  9349. .B [ \-short | \-s ]
  9350. This option forces \fIxgoban\fP to save files in short mode : only
  9351. uppercase letters of keywords are printed, and there is no carriage
  9352. return. \-s option is for compatibility with \fImgt\fP.
  9353. .TP 8
  9354. .B -stipple<x>
  9355. These options set the backgroundPixmap ressource of the Goban widget
  9356. to predefined gray pixmaps (<x> must be one of 1, 2 or 3). 
  9357. You may like it if you use a black and white
  9358. display. This is an idea of Stephen Coffin.
  9359. .LP
  9360. One of \-white, \-black option starts \fIxgoban\fP in Play mode.
  9361. Default is Edit mode.
  9362. .SH OPERATIONS
  9363. .B 
  9364. When used in Edit mode, \fIxgoban\fP allows the user to edit go files.
  9365. Commands are entered form the keyboard or from the mouse. 
  9366. Most of the window that are poped down contain a Confirm (or Yes) an a 
  9367. Cancel (or No) button. 
  9368. Escape key is associated with the Cancel button, while Return
  9369. Key is associated with the Confirm button.
  9370. .LP
  9371. When an action is not allowed (because the mode your are in)
  9372. you will hear a beep. Of course you hear nothing if you turned
  9373. the bell off.
  9374. .LP
  9375. First are commands that can be used to only view a file :
  9376. .LP
  9377. .TP 8
  9378. Moves to next node along the tree and displays its properties.
  9379. .LP
  9380. .TP 8
  9381. <
  9382. Hides properties of current node and moves to previous node 
  9383. along the tree.
  9384. .LP
  9385. .TP 8
  9386. }
  9387. Goes down along the tree until a commented node or a variation node
  9388. is seen. 
  9389. .LP
  9390. .TP 8
  9391. {
  9392. Goes up along the tree until a commented node or the top of the tree
  9393. is seen. 
  9394. .LP
  9395. .TP 8
  9396. ]
  9397. Goes down along the tree until a variation node or the bottom of the
  9398. tree is seen. 
  9399. .LP
  9400. .TP 8
  9401. [
  9402. Goes up along the tree until a variation node or the top of the tree
  9403. is seen. 
  9404. .LP
  9405. .TP 8
  9406. ?
  9407. Pops down a short help window.
  9408. .LP
  9409. .TP 8
  9410. q
  9411. Exits from the program.
  9412. .LP
  9413. .TP 8
  9414. l
  9415. Loads a file.
  9416. .LP
  9417. .TP 8
  9418. s
  9419. Saves the current tree to a file.
  9420. .LP
  9421. .TP 8
  9422. i
  9423. Pops down a window that contains some properties of the current event
  9424. (GameName, PlayerWhite, WhiteRank, WhiteSpecies ... and GameComment)
  9425. You can change these properties or just view them.
  9426. .LP
  9427. .TP 8
  9428. A-Z
  9429. When there are some variations, an uppercase letter is displayed on each
  9430. point corresponding to each possible move.
  9431. The A-Z keys can be used to select the corresponding node.
  9432. See also Btn2 action
  9433. .LP
  9434. .TP 8
  9435. Btn1
  9436. When there are variations and the mouse points at a marked point (with
  9437. uppercase letter), selects the corresponding node.
  9438. Otherwise it is the same as key `>'.
  9439. .LP
  9440. .TP 8
  9441. Btn2
  9442. It can arise that not all variations can be marked with an uppercase
  9443. letter : if a variation is a diagram (having AddBlack, AddWhite or AddEmpty
  9444. property), if there is variations on the same level
  9445. with differently colored move (Black and White), or if there is a pass move. 
  9446. In this case, the cursor will be gray.
  9447. Pressing the middle button pops up a menu where all variations are listed.
  9448. You can choose the one you want to display
  9449. .LP
  9450. .TP 8
  9451. Btn3
  9452. Same as key `<'.
  9453. .LP
  9454. Following commands can be used to change a tree :
  9455. .LP
  9456. .TP 8
  9457. v
  9458. Enters the View sub-mode and allows the user to select a partial view of the
  9459. board. A VieW property is then attached to the node.
  9460. .LP
  9461. .TP 8
  9462. z
  9463. Enters the Size sub-mode and allows the user to set the size of the board.
  9464. SiZe property can only be change at Event node (see below) and the board
  9465. is cleared.
  9466. .LP
  9467. .TP 8
  9468. w
  9469. Set the PLayer property to white for the current node.
  9470. The next move will be a white stone.
  9471. .LP
  9472. .TP 8
  9473. b
  9474. Set the PLayer property to black for the current node.
  9475. The next move will a black stone.
  9476. .LP
  9477. .TP 8
  9478. n
  9479. Prompt a dialog to edit the name of current node.
  9480. .LP
  9481. .TP 8
  9482. a
  9483. If the current node is a diagram,
  9484. Enters the Diagram sub-mode and allows the user to edit the diagram.
  9485. .LP
  9486. .TP 8
  9487. Shift Btn1
  9488. Adds a move after the current node. 
  9489. The new node is created with property
  9490. White or Black according to the color of the last move. 
  9491. The mouse must point on the intersection where you want to put the stone.
  9492. .LP
  9493. .TP 8
  9494. Shift Btn3
  9495. Deletes the current node and all its sub-nodes.
  9496. .LP
  9497. .TP 8
  9498. Ctrl Shift Btn1
  9499. Makes a variation move.
  9500. The color is the same as the PLayer property of previous node.
  9501. The mouse must point on the intersection where you want to put a the stone.
  9502. .LP
  9503. .TP 8
  9504. Ctrl Shift P
  9505. Makes a variation move which is a pass move.
  9506. The color is the same as the PLayer property of previous node.
  9507. .LP
  9508. .TP 8
  9509. Ctrl Shift Btn2
  9510. Makes a variation diagram.
  9511. It enters in the Diagram sub-mode (see below) to allow the user to put stones on 
  9512. the diagram.
  9513. .LP
  9514. .TP 8
  9515. Ctrl Btn1
  9516. Puts a letter (downcase) on the mouse pointed intersection.
  9517. .LP
  9518. .TP 8
  9519. Ctrl Btn2
  9520. Puts a triangle mark on the mouse pointed intersection.
  9521. .LP
  9522. .TP 8
  9523. Ctrl Btn3
  9524. Remove any letter or mark from the mouse pointed intersection.
  9525. .LP
  9526. There are sub-modes of Edit mode that can be Diagram, View or Size.
  9527. Whitin these sub-modes, actions are changed.
  9528. The Diagram sub-mode is signaled by a `point' cursor, while the View and
  9529. Size sub-modes are signalled by the `upper-left-corner' cursor.
  9530. .LP
  9531. .TP 8
  9532. Escape
  9533. .br
  9534. Quit the Diagram, Size or View sub-mode.
  9535. .LP
  9536. .TP 8
  9537. Btn1
  9538. Within Diagram sub-mode : puts a black stone on the mouse pointed intersection.
  9539. .LP
  9540. .TP 8
  9541. Btn2
  9542. Within Diagram sub-mode : puts a white stone on the mouse pointed intersection.
  9543. .LP
  9544. .TP 8
  9545. Btn3
  9546. Within Diagram sub-mode : removes any stone from the mouse pointed intersection.
  9547. .LP
  9548. .TP 8
  9549. Btn1 Press
  9550. Within View or Size sub-mode : start draging a rectangle to select the view
  9551. or the size.
  9552. .LP
  9553. .TP 8
  9554. Btn1 Motion
  9555. Within View or Size sub-mode : drags the rectangle.
  9556. .LP
  9557. .TP 8
  9558. Btn1 Release
  9559. Within View or Size sub-mode : stop draging the rectangle and add a VieW or SiZe 
  9560. property to the current node.
  9561. .SH GAME TREE
  9562. Game trees that can be made are slightly different from Smart-Go format.
  9563. I wanted them to be closer to a `real' game. 
  9564. .LP
  9565. Node are either of type Diagram (they have AddBlack, AddWhite or AddEmpty property)
  9566. or of type Move (they have Black or White property).
  9567. Only a Diagram can have the PLayer property (default is PLayer[B]), which
  9568. can be set only if the diagram does not have a successor.
  9569. A file is a collection of Event nodes, which are of type Diagram.
  9570. A node can have one or more successors (in which case, successors are variations).
  9571. If a node has only one successor, that successor can only be of type Move.
  9572. If a node is of type Move, the color of any successor can only be the opposite
  9573. of its color.
  9574. If a node is of type Diagram, the color of any successor is the same as the PLayer
  9575. property of the diagram.
  9576. .LP
  9577. However, I noticed that most of the avaible game record doesn't match these restrictions.
  9578. \fIxgoban\fP can read such unrestricted files but not edit them and create new 
  9579. unrestricted nodes.
  9580. Thus I added a \-versatile option that turns off strong verification for accepted colors
  9581. of nodes.
  9582. When you specify \-versatile option, you can change the PLayer property even at Move nodes
  9583. or at any node that already have a successor.
  9584. .SH RESOURCES
  9585. Resources can be set via xrdb or in the .Xdefault file. 
  9586. Default resources are as follow :
  9587. .sp
  9588. .nf
  9589. .ta .5i
  9590.     XGoban*size : 19
  9591.     XGoban*handicap : 0
  9592.     XGoban*path : "."
  9593.     XGoban*pointSize : 26
  9594.     XGoban*autonum : True
  9595.     XGoban*beep : True
  9596.     XGoban*versatile : False
  9597. .fi
  9598. .LP
  9599. You can change the board color if you want. Remember that the board background
  9600. shouldn't be black : thus, on a black and white display the only valid background 
  9601. is white.
  9602. .sp
  9603. .nf
  9604. .ta .5i
  9605.     XGoban*goban.background : tan1
  9606.     XGoban*goban.foreground : black
  9607. .fi
  9608. .LP
  9609. But everything else can be black on a white background if you like it :
  9610. .sp
  9611. .nf
  9612. .ta .5i
  9613.     XGoban*background  : black
  9614.     XGoban*foreground  : white
  9615.     XGoban*borderColor : white
  9616. .fi
  9617. .LP
  9618. You can also control the geometry of windows :
  9619. .sp
  9620. .nf
  9621. .ta .5i
  9622.     XGoban.geometry         : 500x500+30+30
  9623.     XGoban.comment.geometry : 500x200+30+580
  9624. .fi
  9625. .LP
  9626. You can change the translation table for the goban Widget (see xgoban.c for the
  9627. default translation table). You must be carefull by doing this because of multiple
  9628. modes. Some action work only in a specified mode, and you can bind them to the same
  9629. event if they don't work in the same mode. But don't bind two actions working in the
  9630. same mode with the same event ... you may have trouble.
  9631. A good way to change the translation table is just to change the left part (name of
  9632. events) and to leave the right part (action) as it is.
  9633. To change the translation table see a doc on X Toolkit and modify your .Xdefaults
  9634. accordly.
  9635. .SH EXAMPLES
  9636. .PD 0
  9637. .TP 5
  9638. To read and edit the file 001_001.s :
  9639. .B xgoban 001_001.s
  9640. .TP 5
  9641. To play black against gnugo with 5 handicap stones :
  9642. .B xgoban -handicap 5 -white gnugo 
  9643. .TP 5
  9644. To play white against wally :
  9645. .B xgoban -black wally 
  9646. .TP 5
  9647. To make wally play against gnugo :
  9648. .B xgoban -black wally -white gnugo
  9649. .PD
  9650. .SH BUGS
  9651. .LP
  9652. When read, a file is supposed to be syntacticaly correct.
  9653. This is normally the case, when you didn't create this file by hand ...
  9654. .LP
  9655. File names are limited to 512 bytes.
  9656. .LP
  9657. \-pointSize option doesn't work with smaller size than 19x19.
  9658. The board size is calculated as if it were a 19x19 board, and 
  9659. then the board size is changed whitin the same square.
  9660. .LP
  9661. Resign is not supported in Play mode, and you can't use the counting
  9662. features of gnugo or wally.
  9663. .LP
  9664. Once you edit a file, you can't start editing another one without quiting
  9665. \fIxgoban\fP. You can also delete all top nodes but beware from erasing you
  9666. previous file with the save command.
  9667. .SH SEE ALSO
  9668. \fImgt\fP from Greg Hale.
  9669. .br
  9670. \fImailgo\fP from Adrian Mariano.
  9671. .LP
  9672. \fImgt\fP, \fImailgo\fP and game records 
  9673. are available at milton.u.washington.edu.
  9674. .SH AUTHORS
  9675. Antoine Dumesnil de Maricourt (dumesnil@etca.fr)
  9676. SHAR_EOF
  9677. fi # end of overwriting check
  9678. if test -f 'xgoban.6'
  9679. then
  9680.     echo shar: will not over-write existing file "'xgoban.6'"
  9681. else
  9682. cat << \SHAR_EOF > 'xgoban.6'
  9683. .TH XGOBAN 6  "15 May 1992"
  9684. .SH NAME
  9685. xgoban - X11 files editor for the game of go / 
  9686. interface to gnugo and wally
  9687. .SH SYNOPSIS
  9688. .B xgoban 
  9689. .B \-toolkitoptions ...
  9690. ]
  9691. .B \-options ... 
  9692. ]
  9693. [ \fIfilename\fP ]
  9694. .SH DESCRIPTION
  9695. .PP
  9696. \fIxgoban\fP works under 3 major modes : Edit, Play and Mail.
  9697. .LP
  9698. In Edit mode, the \fIxgoban\fP program displays a go board and allows 
  9699. the user to edit go files. 
  9700. It can read and write files with the Smart-Go format. 
  9701. When started in Edit mode, \fIxgoban\fP shows 2 windows : one for the
  9702. board and the other to display comments.
  9703. The title of the comment window is set to the name of current node if
  9704. there is one.
  9705. The title of the board is set to the name of the current game.
  9706. .LP
  9707. In Play mode, \fIxgoban\fP can be used to play against go
  9708. programs (currently supported : wally and gnugo) or against human opponent.
  9709. The game can also be saved with the Smart-Go format.
  9710. When started in Play mode, the program can switch to Edit mode and thus
  9711. allows the user to edit the played game.
  9712. There is no comment window in this mode.
  9713. .LP
  9714. Mail mode is designed to be used in combination with the \fImailgo\fP
  9715. script from Adrian Mariano.
  9716. .SH OPTIONS
  9717. \fIxgoban\fP accepts all of the standard toolkit command line options as
  9718. well as the following :
  9719. .TP 8
  9720. .B \-size \fIsize\fP
  9721. This option specifies the size of the goban : \fIsize\fP must range between
  9722. 2 and 19. It can be used in Play or Edit mode. The default size is 19.
  9723. .TP 8
  9724. .B \-handicap \fIhandicap\fP
  9725. In Play mode, this option specifies the number of handicap stones that 
  9726. are to be put on the goban before the game starts. 
  9727. Legal values for \fIhandicap\fP depend on the size of the board and on
  9728. the playing program. 
  9729. Whitin Edit mode, a first node is created and handicap stones are put 
  9730. under the AddBlack property.
  9731. .TP 8
  9732. .B \-black \fIblackplayer\fP
  9733. This options indicates the name of the black player. \fIxgoban\fP 
  9734. is started within Play mode and \fIblackplayer\fP is added on the root 
  9735. node under the PlayerBlack property. 
  9736. \fIxgoban\fP recognize 2 program names : gnugo and wally.
  9737. When \fIblackplayer\fP is one of them, an attempt is made to run the
  9738. corresponding program (which must be found using the current environment variable
  9739. PATH).
  9740. .TP 8
  9741. .B \-white \fIwhiteplayer\fP
  9742. This option is the same as -black, but for the white player.
  9743. .TP 8
  9744. .B \-path \fIpath\fP
  9745. This option specifies the path where files are searched before loading them.
  9746. A \fIpath\fp is a comma separated list of directories.
  9747. .TP 8
  9748. .B \-pointSize \fIsize\fP
  9749. This option specifies the size in pixels for a small square of the board.
  9750. .TP 8
  9751. .B \-nonumber
  9752. This option turns off the automatic numbering facility.
  9753. .TP 8
  9754. .B \-silent
  9755. .br
  9756. This option turns off the bell.
  9757. .B \-beep \fIvolume\fP
  9758. .br
  9759. This option specifies the volume of the bell when it is not turned off.
  9760. Legal values range between -100 and 100. 
  9761. I am not sure it will work on all keyboards ...
  9762. Default value is 0. 
  9763. .TP 8
  9764. .B \-versatile
  9765. This option turns off strong verification of the tree : see below.
  9766. This also turns off the automatic numbering facility.
  9767. .TP 8
  9768. .B \-help
  9769. .br
  9770. Displays a list of allowed options.
  9771. \fIxgoban\fP is not started.
  9772. .TP 8
  9773. .B [ \-mail | \-m ] \fImailfile\fP
  9774. Start \fIxgoban\fP in Mail mode. A file should be specified with 
  9775. \fIfilename\fP argument. This file is read, and \fIxgoban\fP automatically
  9776. moves to the end of the main variation. 
  9777. When you quit \fIxgoban\fP, the game tree will be saved to
  9778. \fImailfile\fP. The exit value will be 0 if a move has been made
  9779. and 1 otherwise. This option has been designed to work with the
  9780. \fImailgo\fP script from Adrian Mariano (adrian@u.washington.edu).
  9781. \-m option is for compatibility with \fImgt\fP.
  9782. .TP 8
  9783. .B [ \-short | \-s ]
  9784. This option forces \fIxgoban\fP to save files in short mode : only
  9785. uppercase letters of keywords are printed, and there is no carriage
  9786. return. \-s option is for compatibility with \fImgt\fP.
  9787. .TP 8
  9788. .B -stipple<x>
  9789. These options set the backgroundPixmap ressource of the Goban widget
  9790. to predefined gray pixmaps (<x> must be one of 1, 2 or 3). 
  9791. You may like it if you use a black and white
  9792. display. This is an idea of Stephen Coffin.
  9793. .LP
  9794. One of \-white, \-black option starts \fIxgoban\fP in Play mode.
  9795. Default is Edit mode.
  9796. .SH OPERATIONS
  9797. .B 
  9798. When used in Edit mode, \fIxgoban\fP allows the user to edit go files.
  9799. Commands are entered form the keyboard or from the mouse. 
  9800. Most of the window that are poped down contain a Confirm (or Yes) an a 
  9801. Cancel (or No) button. 
  9802. Escape key is associated with the Cancel button, while Return
  9803. Key is associated with the Confirm button.
  9804. .LP
  9805. When an action is not allowed (because the mode your are in)
  9806. you will hear a beep. Of course you hear nothing if you turned
  9807. the bell off.
  9808. .LP
  9809. First are commands that can be used to only view a file :
  9810. .LP
  9811. .TP 8
  9812. Moves to next node along the tree and displays its properties.
  9813. .LP
  9814. .TP 8
  9815. <
  9816. Hides properties of current node and moves to previous node 
  9817. along the tree.
  9818. .LP
  9819. .TP 8
  9820. }
  9821. Goes down along the tree until a commented node or a variation node
  9822. is seen. 
  9823. .LP
  9824. .TP 8
  9825. {
  9826. Goes up along the tree until a commented node or the top of the tree
  9827. is seen. 
  9828. .LP
  9829. .TP 8
  9830. ]
  9831. Goes down along the tree until a variation node or the bottom of the
  9832. tree is seen. 
  9833. .LP
  9834. .TP 8
  9835. [
  9836. Goes up along the tree until a variation node or the top of the tree
  9837. is seen. 
  9838. .LP
  9839. .TP 8
  9840. ?
  9841. Pops down a short help window.
  9842. .LP
  9843. .TP 8
  9844. q
  9845. Exits from the program.
  9846. .LP
  9847. .TP 8
  9848. l
  9849. Loads a file.
  9850. .LP
  9851. .TP 8
  9852. s
  9853. Saves the current tree to a file.
  9854. .LP
  9855. .TP 8
  9856. i
  9857. Pops down a window that contains some properties of the current event
  9858. (GameName, PlayerWhite, WhiteRank, WhiteSpecies ... and GameComment)
  9859. You can change these properties or just view them.
  9860. .LP
  9861. .TP 8
  9862. A-Z
  9863. When there are some variations, an uppercase letter is displayed on each
  9864. point corresponding to each possible move.
  9865. The A-Z keys can be used to select the corresponding node.
  9866. See also Btn2 action
  9867. .LP
  9868. .TP 8
  9869. Btn1
  9870. When there are variations and the mouse points at a marked point (with
  9871. uppercase letter), selects the corresponding node.
  9872. Otherwise it is the same as key `>'.
  9873. .LP
  9874. .TP 8
  9875. Btn2
  9876. It can arise that not all variations can be marked with an uppercase
  9877. letter : if a variation is a diagram (having AddBlack, AddWhite or AddEmpty
  9878. property), if there is variations on the same level
  9879. with differently colored move (Black and White), or if there is a pass move. 
  9880. In this case, the cursor will be gray.
  9881. Pressing the middle button pops up a menu where all variations are listed.
  9882. You can choose the one you want to display
  9883. .LP
  9884. .TP 8
  9885. Btn3
  9886. Same as key `<'.
  9887. .LP
  9888. Following commands can be used to change a tree :
  9889. .LP
  9890. .TP 8
  9891. v
  9892. Enters the View sub-mode and allows the user to select a partial view of the
  9893. board. A VieW property is then attached to the node.
  9894. .LP
  9895. .TP 8
  9896. z
  9897. Enters the Size sub-mode and allows the user to set the size of the board.
  9898. SiZe property can only be change at Event node (see below) and the board
  9899. is cleared.
  9900. .LP
  9901. .TP 8
  9902. w
  9903. Set the PLayer property to white for the current node.
  9904. The next move will be a white stone.
  9905. .LP
  9906. .TP 8
  9907. b
  9908. Set the PLayer property to black for the current node.
  9909. The next move will a black stone.
  9910. .LP
  9911. .TP 8
  9912. n
  9913. Prompt a dialog to edit the name of current node.
  9914. .LP
  9915. .TP 8
  9916. a
  9917. If the current node is a diagram,
  9918. Enters the Diagram sub-mode and allows the user to edit the diagram.
  9919. .LP
  9920. .TP 8
  9921. Shift Btn1
  9922. Adds a move after the current node. 
  9923. The new node is created with property
  9924. White or Black according to the color of the last move. 
  9925. The mouse must point on the intersection where you want to put the stone.
  9926. .LP
  9927. .TP 8
  9928. Shift Btn3
  9929. Deletes the current node and all its sub-nodes.
  9930. .LP
  9931. .TP 8
  9932. Ctrl Shift Btn1
  9933. Makes a variation move.
  9934. The color is the same as the PLayer property of previous node.
  9935. The mouse must point on the intersection where you want to put a the stone.
  9936. .LP
  9937. .TP 8
  9938. Ctrl Shift P
  9939. Makes a variation move which is a pass move.
  9940. The color is the same as the PLayer property of previous node.
  9941. .LP
  9942. .TP 8
  9943. Ctrl Shift Btn2
  9944. Makes a variation diagram.
  9945. It enters in the Diagram sub-mode (see below) to allow the user to put stones on 
  9946. the diagram.
  9947. .LP
  9948. .TP 8
  9949. Ctrl Btn1
  9950. Puts a letter (downcase) on the mouse pointed intersection.
  9951. .LP
  9952. .TP 8
  9953. Ctrl Btn2
  9954. Puts a triangle mark on the mouse pointed intersection.
  9955. .LP
  9956. .TP 8
  9957. Ctrl Btn3
  9958. Remove any letter or mark from the mouse pointed intersection.
  9959. .LP
  9960. There are sub-modes of Edit mode that can be Diagram, View or Size.
  9961. Whitin these sub-modes, actions are changed.
  9962. The Diagram sub-mode is signaled by a `point' cursor, while the View and
  9963. Size sub-modes are signalled by the `upper-left-corner' cursor.
  9964. .LP
  9965. .TP 8
  9966. Escape
  9967. .br
  9968. Quit the Diagram, Size or View sub-mode.
  9969. .LP
  9970. .TP 8
  9971. Btn1
  9972. Within Diagram sub-mode : puts a black stone on the mouse pointed intersection.
  9973. .LP
  9974. .TP 8
  9975. Btn2
  9976. Within Diagram sub-mode : puts a white stone on the mouse pointed intersection.
  9977. .LP
  9978. .TP 8
  9979. Btn3
  9980. Within Diagram sub-mode : removes any stone from the mouse pointed intersection.
  9981. .LP
  9982. .TP 8
  9983. Btn1 Press
  9984. Within View or Size sub-mode : start draging a rectangle to select the view
  9985. or the size.
  9986. .LP
  9987. .TP 8
  9988. Btn1 Motion
  9989. Within View or Size sub-mode : drags the rectangle.
  9990. .LP
  9991. .TP 8
  9992. Btn1 Release
  9993. Within View or Size sub-mode : stop draging the rectangle and add a VieW or SiZe 
  9994. property to the current node.
  9995. .SH GAME TREE
  9996. Game trees that can be made are slightly different from Smart-Go format.
  9997. I wanted them to be closer to a `real' game. 
  9998. .LP
  9999. Node are either of type Diagram (they have AddBlack, AddWhite or AddEmpty property)
  10000. or of type Move (they have Black or White property).
  10001. Only a Diagram can have the PLayer property (default is PLayer[B]), which
  10002. can be set only if the diagram does not have a successor.
  10003. A file is a collection of Event nodes, which are of type Diagram.
  10004. A node can have one or more successors (in which case, successors are variations).
  10005. If a node has only one successor, that successor can only be of type Move.
  10006. If a node is of type Move, the color of any successor can only be the opposite
  10007. of its color.
  10008. If a node is of type Diagram, the color of any successor is the same as the PLayer
  10009. property of the diagram.
  10010. .LP
  10011. However, I noticed that most of the avaible game record doesn't match these restrictions.
  10012. \fIxgoban\fP can read such unrestricted files but not edit them and create new 
  10013. unrestricted nodes.
  10014. Thus I added a \-versatile option that turns off strong verification for accepted colors
  10015. of nodes.
  10016. When you specify \-versatile option, you can change the PLayer property even at Move nodes
  10017. or at any node that already have a successor.
  10018. .SH RESOURCES
  10019. Resources can be set via xrdb or in the .Xdefault file. 
  10020. Default resources are as follow :
  10021. .sp
  10022. .nf
  10023. .ta .5i
  10024.     XGoban*size : 19
  10025.     XGoban*handicap : 0
  10026.     XGoban*path : "."
  10027.     XGoban*pointSize : 26
  10028.     XGoban*autonum : True
  10029.     XGoban*beep : True
  10030.     XGoban*versatile : False
  10031. .fi
  10032. .LP
  10033. You can change the board color if you want. Remember that the board background
  10034. shouldn't be black : thus, on a black and white display the only valid background 
  10035. is white.
  10036. .sp
  10037. .nf
  10038. .ta .5i
  10039.     XGoban*goban.background : tan1
  10040.     XGoban*goban.foreground : black
  10041. .fi
  10042. .LP
  10043. But everything else can be black on a white background if you like it :
  10044. .sp
  10045. .nf
  10046. .ta .5i
  10047.     XGoban*background  : black
  10048.     XGoban*foreground  : white
  10049.     XGoban*borderColor : white
  10050. .fi
  10051. .LP
  10052. You can also control the geometry of windows :
  10053. .sp
  10054. .nf
  10055. .ta .5i
  10056.     XGoban.geometry         : 500x500+30+30
  10057.     XGoban.comment.geometry : 500x200+30+580
  10058. .fi
  10059. .LP
  10060. You can change the translation table for the goban Widget (see xgoban.c for the
  10061. default translation table). You must be carefull by doing this because of multiple
  10062. modes. Some action work only in a specified mode, and you can bind them to the same
  10063. event if they don't work in the same mode. But don't bind two actions working in the
  10064. same mode with the same event ... you may have trouble.
  10065. A good way to change the translation table is just to change the left part (name of
  10066. events) and to leave the right part (action) as it is.
  10067. To change the translation table see a doc on X Toolkit and modify your .Xdefaults
  10068. accordly.
  10069. .SH EXAMPLES
  10070. .PD 0
  10071. .TP 5
  10072. To read and edit the file 001_001.s :
  10073. .B xgoban 001_001.s
  10074. .TP 5
  10075. To play black against gnugo with 5 handicap stones :
  10076. .B xgoban -handicap 5 -white gnugo 
  10077. .TP 5
  10078. To play white against wally :
  10079. .B xgoban -black wally 
  10080. .TP 5
  10081. To make wally play against gnugo :
  10082. .B xgoban -black wally -white gnugo
  10083. .PD
  10084. .SH BUGS
  10085. .LP
  10086. When read, a file is supposed to be syntacticaly correct.
  10087. This is normally the case, when you didn't create this file by hand ...
  10088. .LP
  10089. File names are limited to 512 bytes.
  10090. .LP
  10091. \-pointSize option doesn't work with smaller size than 19x19.
  10092. The board size is calculated as if it were a 19x19 board, and 
  10093. then the board size is changed whitin the same square.
  10094. .LP
  10095. Resign is not supported in Play mode, and you can't use the counting
  10096. features of gnugo or wally.
  10097. .LP
  10098. Once you edit a file, you can't start editing another one without quiting
  10099. \fIxgoban\fP. You can also delete all top nodes but beware from erasing you
  10100. previous file with the save command.
  10101. .SH SEE ALSO
  10102. \fImgt\fP from Greg Hale.
  10103. .br
  10104. \fImailgo\fP from Adrian Mariano.
  10105. .LP
  10106. \fImgt\fP, \fImailgo\fP and game records 
  10107. are available at milton.u.washington.edu.
  10108. .SH AUTHORS
  10109. Antoine Dumesnil de Maricourt (dumesnil@etca.fr)
  10110. SHAR_EOF
  10111. fi # end of overwriting check
  10112. if test -f 'xgoban.ad'
  10113. then
  10114.     echo shar: will not over-write existing file "'xgoban.ad'"
  10115. else
  10116. cat << \SHAR_EOF > 'xgoban.ad'
  10117. ! On a black and white terminal, goban.background must be white and 
  10118. ! goban.foreground must be black ...
  10119.  
  10120. XGoban*goban.background : tan1
  10121. XGoban*goban.foreground : black
  10122.  
  10123. ! Everything else can be white on a black foreground
  10124.  
  10125. XGoban*background  : black
  10126. XGoban*foreground  : white
  10127. XGoban*borderColor : white
  10128.  
  10129. ! Position of the windows ...
  10130.  
  10131. XGoban.geometry         : 500x500+30+30
  10132. XGoban.comment.geometry : 500x200+30+580
  10133.  
  10134. ! Default path and other options
  10135. ! These options are overwriten by command line options
  10136.  
  10137. XGoban.path : /users1/dumesnil/Go/games/mgt:/usr/local/games/go/files/mgt:.
  10138.  
  10139. XGoban.autonum   : True
  10140. XGoban.beep      : True
  10141. XGoban.versatile : False
  10142.  
  10143.  
  10144.  
  10145.  
  10146.  
  10147.  
  10148. SHAR_EOF
  10149. fi # end of overwriting check
  10150. if test -f 'README'
  10151. then
  10152.     echo shar: will not over-write existing file "'README'"
  10153. else
  10154. cat << \SHAR_EOF > 'README'
  10155. Here are source files for a X11 go files editor
  10156.  
  10157. The program has been tested under X11R5 on a sun4 (sparc) and under X11R4 
  10158. on a sun3 (68020)
  10159.  
  10160. DISTRIBUTION :
  10161. --------------
  10162.  
  10163. You should find the following files :
  10164.  
  10165.  + CHANGE.Goban
  10166.  + Goban.c
  10167.  + Goban.doc
  10168.  + Goban.h
  10169.  + GobanP.h
  10170.  + Imakefile
  10171.  + README
  10172.  + action.c
  10173.  + blackstone.bm
  10174.  + dialog.c
  10175.  + display.c
  10176.  + event.c
  10177.  + game.c
  10178.  + go.c
  10179.  + go.h
  10180.  + graystone.bm
  10181.  + icon.bm
  10182.  + mailgo.6
  10183.  + misc.c
  10184.  + play.c
  10185.  + sg.c
  10186.  + stonemask.bm
  10187.  + whitestone.bm
  10188.  + xgoban.6
  10189.  + xgoban.ad
  10190.  + xgoban.c
  10191.  + xgoban.doc
  10192.  + xgoban.h
  10193.  + xgoban.man
  10194.  + xmailgo*
  10195.  
  10196. BUILDING XGOBAN :
  10197. -----------------
  10198.  
  10199. Just type :
  10200.  
  10201. >  xmkmf
  10202. >  make depend
  10203. >  make
  10204.  
  10205. If you want to install it with other X11 binary files, just do :
  10206.  
  10207. > make install
  10208. > make install.man
  10209.  
  10210. To run it :
  10211.  
  10212. > xgoban
  10213.  
  10214. xgoban.ad is an example of configuration file. You can change it and add
  10215. it into your .Xdefaults file.
  10216.  
  10217. GOBAN WIDGET :
  10218. --------------
  10219.  
  10220. You can use the Goban widget for itself. Files related to it are : 
  10221.  
  10222.   +  Goban.c
  10223.   +  Goban.doc
  10224.   +  Goban.h
  10225.   +  GobanP.h
  10226.   +  blackstone.bm
  10227.   +  graystone.bm
  10228.   +  stonemask.bm
  10229.   +  whitestone.bm
  10230.  
  10231. For more description of the Goban widget see Goban.doc, and for xgoban
  10232. see the manual pages (or xgoban.doc).
  10233.  
  10234. WARNING :
  10235. ---------
  10236. If you get warning at compile time about types that don't match prototype
  10237. description, you should ignore them. The program will (probably) work ...
  10238. (this can appear mainly with XtAppAddInput; see below)
  10239.  
  10240. You may have trouble to use wally or gnugo with xgoban. You need to add
  10241. `fflush (stdout);' after the printf statements in gnugo and wally source
  10242. files (line 144 in genmove.c for gnugo and line 1683 in wally.c for wally).
  10243. You also can get an updated version (with fflush statement inside) for wally
  10244. on anonymous ftp from milton.u.washington.edu (128.95.136.1).
  10245.  
  10246. If it still doesn't work, maybe your OS doesn't support XtAppAddInput
  10247. with pipe, or has trouble with streams : I can't do anything for
  10248. you, but if you have a solution I will patch xgoban to use it.
  10249.  
  10250. MAILGO :
  10251. --------
  10252.  
  10253. I included the mailgo script from Adrian Mariano in the distribution.
  10254. It is renamed into xmailgo and the only difference is the default program that
  10255. xmailgo try to run : xgoban of course. (you can use mailgo and set your 
  10256. environment variable MAILGO to xgoban to do the same job).
  10257. It is a suggestion of Adrian Mariano.
  10258.  
  10259. THANKS :
  10260. --------
  10261.  
  10262. I thank Adrian Mariano for the usefull remarks he made.
  10263.  
  10264. BUGS :
  10265. ------
  10266.  
  10267. Bug descriptions, use reports, comments or suggestions are welcome.
  10268. Send them to :  
  10269.             dumesnil@etca.fr
  10270. SHAR_EOF
  10271. fi # end of overwriting check
  10272. if test -f 'CHANGE.Goban'
  10273. then
  10274.     echo shar: will not over-write existing file "'CHANGE.Goban'"
  10275. else
  10276. cat << \SHAR_EOF > 'CHANGE.Goban'
  10277. Changes to Goban Widget 
  10278.  
  10279. April 1 1992 : 
  10280. --------------
  10281.   + first version
  10282.  
  10283. June 5 1992  :
  10284. --------------
  10285.   + bugs corrected
  10286.   + backgroundPixmap resource added 
  10287.  
  10288. July 6 1992  :
  10289. --------------
  10290.  
  10291.   + whiteStoneBackground, whiteStoneForground, whiteStoneBorder,
  10292.     blackStoneBackground, blackStoneForground, blackStoneBorder resources added
  10293.     
  10294. SHAR_EOF
  10295. fi # end of overwriting check
  10296. if test -f 'Imakefile'
  10297. then
  10298.     echo shar: will not over-write existing file "'Imakefile'"
  10299. else
  10300. cat << \SHAR_EOF > 'Imakefile'
  10301.         MANSUFFIX = 6
  10302.   LOCAL_LIBRARIES = XawClientLibs
  10303.  
  10304.              SRCS = Goban.c read.c sg.c play.c dialog.c xgoban.c action.c \
  10305.                     misc.c display.c game.c event.c write.c node.c
  10306.              OBJS = Goban.o read.o sg.o play.o dialog.o xgoban.o action.o \
  10307.                     misc.o display.o game.o event.o write.o node.o
  10308.  
  10309. ComplexProgramTarget (xgoban)
  10310. SHAR_EOF
  10311. fi # end of overwriting check
  10312. if test -f 'xmailgo'
  10313. then
  10314.     echo shar: will not over-write existing file "'xmailgo'"
  10315. else
  10316. cat << \SHAR_EOF > 'xmailgo'
  10317.  
  10318. #!/bin/sh
  10319. #
  10320. #  mailgo 1.57    E-mail go game management program by Adrian Mariano
  10321. #     6/5/92      I place it on the public domain.  Please send improvements
  10322. #                 to me at adrian@u.washington.edu.
  10323. #  Syntax: mailgo [-r] filename
  10324. #          mailgo -n [filename]
  10325. #          mailgo -c 
  10326. #  Filename should contain a mailgo go game
  10327. #  
  10328. #  -r resends the file to the opponent
  10329. #  -n start a new game, using data in filename to get address
  10330. #  -c removes temporary files left when abnormally terminated
  10331. #
  10332. #  Invokes the game processor in the environment variable MAILGO, or attempts
  10333. #  to run xgoban from the inherited path if MAILGO is not set.
  10334. #
  10335. #  System V Unix users should change the assignment to the MAILER variable
  10336. #  from 'mail' to 'mailx' or 'elm' or some other compatible mailer.
  10337. #
  10338.  
  10339. MAILER=mail
  10340.  
  10341.  
  10342. if [ $# -eq 0 ]
  10343. then
  10344.   echo ' '
  10345.   echo 'Syntax: mailgo [-r] filename'
  10346.   echo '        mailgo -n [filename]'
  10347.   echo '        mailgo -c '
  10348.   echo ' '
  10349.   echo 'Mailgo is a program to manage email go games.'
  10350.   echo 'Filename should contain a mailgo go game'
  10351.   echo '  '
  10352.   echo '  -r resends the file to the opponent'
  10353.   echo '  -n start a new game, using data in filename to get address'
  10354.   echo '  -c removes temporary files left when abnormally terminated'
  10355.   echo ' '
  10356.   exit
  10357. fi
  10358. case $1 in
  10359.   -c) if [ $# -ne 1 ]
  10360.        then
  10361.          echo Wrong number of parameters
  10362.          exit
  10363.        else
  10364.          rm -f MailGo* MailFile* MailOut*
  10365.          exit
  10366.        fi;;
  10367.   -r) if [ $# != 2 ]
  10368.        then
  10369.          echo Wrong number of parameters
  10370.          exit
  10371.        fi
  10372.        if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1
  10373.        then         
  10374.          name=`sed -n '2,5s/TO: //p' $2`
  10375.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  10376.          echo Remailing response to $name, $hisfile
  10377.          $MAILER -s "Remailed Go Game: $hisfile" $name < $2
  10378.          exit
  10379.        else
  10380.          echo Invalid input file $2
  10381.          exit
  10382.        fi;;
  10383.   -n) if [ $# -gt 2 ]
  10384.        then
  10385.          echo Wrong number of parameters
  10386.          exit
  10387.        fi
  10388.        if [ $# -eq 2 ]
  10389.        then
  10390.          if [ ! -s $2 ]
  10391.          then
  10392.            echo File $2 not found.
  10393.            exit
  10394.          fi
  10395.          opponent=`sed -n '2,5s/TO: //p' $2`
  10396.          echo Opponent address: $opponent
  10397.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  10398.          echo His game file: $hisfile
  10399.          me=`sed -n '2,5s/FROM: //p' $2`
  10400.          echo Your address: $me
  10401.          myfile=`sed -n '2,5s/FROMFILE: //p' $2`
  10402.          echo Your game file: $myfile
  10403.        else
  10404.          echo -n "Opponent address: "
  10405.          read opponent
  10406.          echo -n "Opponent game filename: "
  10407.          read hisfile
  10408.          echo -n "Your address: "
  10409.          read me
  10410.          echo -n "Your game filename: "
  10411.          read myfile
  10412.        fi
  10413.        echo -n "Black player name: "
  10414.        read bpname
  10415.        echo -n "             rank: "
  10416.        read bprank
  10417.        echo -n "White player name: "
  10418.        read wpname
  10419.        echo -n "             rank: "
  10420.        read wprank
  10421.        echo -n "Handicap: "
  10422.        read handicap
  10423.        echo -n "Komi: "
  10424.        read komi
  10425.        echo -n "Game record format (Long/Short/Extrashort): "
  10426.        read format
  10427.        case $format in
  10428.          L | l) format='L' ;;
  10429.          E | e) format='E' ;;
  10430.          *)     format='S' ;;
  10431.        esac
  10432.        started=`date|awk '{print $3, $2, $6}'`
  10433.        if grep "W\[\]" $myfile >/dev/null 2>&1  
  10434.        then
  10435.          echo -n "File $myfile contains game possibly in progress.  Clobber (y/N)? "
  10436.          read res
  10437.          case $res in
  10438.            Y | y) ;;
  10439.            *)  echo -n "Your game filename: "
  10440.                read myfile;;
  10441.          esac
  10442.        fi
  10443.        cat <<END_END >$myfile
  10444. ---GoGaMeStArT---
  10445. FROM: $me
  10446. FROMFILE: $myfile
  10447. TO: $opponent
  10448. TOFILE: $hisfile
  10449. NEWGAME
  10450. FORMAT: $format
  10451. END_END
  10452.        cat <<END_END > MailGo$$
  10453. (
  10454. ;
  10455. GaMe[1]
  10456. VieW[]
  10457. SiZe[19]
  10458. Comment[ Black: $bpname, $bprank
  10459.  White: $wpname, $wprank
  10460.  Handicap: $handicap
  10461.  Komi: $komi
  10462.  Started: $started
  10463. ]
  10464. PlayerBlack[$bpname]
  10465. BlackRanking[$bprank]
  10466. PlayerWhite[$wpname]
  10467. WhiteRanking[$wprank]
  10468. KoMi[$komi]
  10469. DaTe[$started]
  10470. END_END
  10471.        case $handicap in
  10472.          2) echo "AB[dp][pd]" >> MailGo$$ ;;
  10473.          3) echo "AB[dp][pd][pp]" >> MailGo$$ ;;
  10474.          4) echo "AB[dd][dp][pd][pp]" >> MailGo$$ ;;
  10475.          5) echo "AB[dd][dp][jj][pd][pp]" >> MailGo$$ ;;
  10476.          6) echo "AB[dd][dj][dp][pd][pj][pp]" >> MailGo$$ ;;
  10477.          7) echo "AB[dd][dj][dp][jj][pd][pj][pp]" >> MailGo$$ ;;
  10478.          8) echo "AB[dd][dj][dp][jd][jp][pd][pj][pp]" >> MailGo$$ ;;
  10479.          9) echo "AB[dd][dj][dp][jd][jj][jp][pd][pj][pp]" >> MailGo$$ ;;
  10480.        esac
  10481.        if [ 0$handicap -ge 2 -a $handicap -le 9 ]
  10482.        then
  10483.            echo "PL[W]HA[$handicap]" >> MailGo$$ ;
  10484.        fi
  10485.        echo ")" >> MailGo$$
  10486.  
  10487.        case $format in
  10488.          L) sflag='';;
  10489.          *) sflag=-s;;
  10490.        esac
  10491.        if ${MAILGO-xgoban} $sflag -m MailOut$$ MailGo$$
  10492.        then
  10493.          if [ -s MailOut$$ ]
  10494.          then
  10495.            cat MailOut$$ >>$myfile
  10496.          else
  10497.           cat MailGo$$ >>$myfile
  10498.          fi
  10499.        else
  10500.          echo -n "No move made, or xgoban error. Send anyway (y/N)? "
  10501.          read res
  10502.          case $res in
  10503.            Y | y) cat MailGo$$ >>$myfile;;
  10504.            *) echo   NOT mailing new game.
  10505.               rm -f MailGo$$ MailOut$$
  10506.               exit;;
  10507.          esac
  10508.        fi
  10509.        rm -f MailOut$$ MailGo$$
  10510.        echo Mailing new game to $opponent, $hisfile
  10511.        echo >> $myfile
  10512.        echo "---GoGaMeEnD---" >> $myfile
  10513.        $MAILER -s "New Go Game: $hisfile" $opponent <$myfile
  10514.        exit
  10515.        ;;
  10516. esac
  10517. if [ $# -ne 1 ]
  10518. then
  10519.   echo Wrong number of parameters
  10520.   exit
  10521. fi
  10522. if [ ! -s $1 ]
  10523. then
  10524.   echo File $1 not found
  10525.   exit
  10526. fi
  10527. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  10528. p
  10529. }' $1 > MailGo$$
  10530. if [ ! -s MailGo$$ ]
  10531. then
  10532.   echo Invalid input file $1
  10533.   exit
  10534. fi
  10535. if sed -n 6,7p MailGo$$ | grep FORMAT > /dev/null 2>&1
  10536. then
  10537.   format=`sed -n '6,7s/FORMAT: //p' MailGo$$`
  10538.   if [ ! \( $format = 'L' -o $format = 'E' \) ] 
  10539.   then
  10540.     format='S'
  10541.   fi
  10542. else
  10543.   format='L'
  10544. fi
  10545. case $format in
  10546.   L) sflag='';;
  10547.   *) sflag='-s';;
  10548.  
  10549. #  E) sflag='-s';;
  10550. #  S) sflag='-s'
  10551. #     sed -n  -e 'H' -e '$g' -e '$s/\n;/;/g' -e '$s/^\n//' -e '$p' <MailGo$$ >MailGoX$$
  10552. #     mv -f MailGoX$$ MailGo$$ ;;
  10553.  
  10554. esac
  10555. if ${MAILGO-xgoban} $sflag -m MailOut$$ MailGo$$
  10556. then
  10557.   echo >> MailOut$$
  10558.   echo ---GoGaMeStArT--- > MailFile$$
  10559.   sed -n '1,/(/s/FROM/TO/p' MailGo$$ >> MailFile$$
  10560.   sed -n '1,/(/s/TO/FROM/p' MailGo$$ >> MailFile$$
  10561.   echo FORMAT: $format >> MailFile$$
  10562.   if [ $format = 'S' ]
  10563.   then
  10564.     sed 's/\(;[BC]\[\)/\
  10565. \1/g' MailOut$$ >>MailFile$$
  10566.   else
  10567.     cat MailOut$$ >> MailFile$$
  10568.   fi
  10569.   echo "---GoGaMeEnD---" >> MailFile$$
  10570.   name=`sed -n '2,5s/FROM: //p' MailGo$$`
  10571.   fileout=`sed -n '2,5s/TOFILE: //p' MailGo$$`
  10572.   tofile=`sed -n '2,5s/FROMFILE: //p' MailGo$$`
  10573.   if sed -n 6p MailGo$$ | grep NEW > /dev/null 2>&1 && [ -s $fileout ]
  10574.   then
  10575.     echo -n "File $fileout exists.  Clobber (y/N)? "
  10576.     read res
  10577.     case $res in
  10578.       Y | y) rm -f $fileout ;;
  10579.       *) echo -n "Output filename: "
  10580.          read newfileout
  10581.          sed "2,5s/FROMFILE: $fileout/FROMFILE: $newfileout/" MailFile$$>Mfil$$
  10582.          mv Mfil$$ MailFile$$
  10583.          fileout=$newfileout ;;
  10584.     esac
  10585.   fi
  10586.   echo Mailing response to $name, $tofile
  10587.   $MAILER -s "Go Game: $tofile" $name < MailFile$$ 
  10588.   rm -f MailGo$$ MailOut$$ $1
  10589.   if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || [ ! -s $fileout ]
  10590.   then
  10591.     mv MailFile$$ $fileout
  10592.   else
  10593.     echo Save file $fileout doesn\'t look like a mailgo file.  
  10594.     echo "Overwrite it anyway (y/N)?"
  10595.     read res
  10596.     case $res in
  10597.       y | Y) mv -f MailFile$$ $fileout;;
  10598.       *)     echo Game record left in MailFile$$;;
  10599.     esac
  10600.   fi
  10601. else
  10602.   echo No move made, or xgoban error.  NOT mailing response.
  10603.   rm -f MailGo$$ MailOut$$
  10604. fi
  10605. SHAR_EOF
  10606. chmod +x 'xmailgo'
  10607. fi # end of overwriting check
  10608. if test -f 'mailgo.6'
  10609. then
  10610.     echo shar: will not over-write existing file "'mailgo.6'"
  10611. else
  10612. cat << \SHAR_EOF > 'mailgo.6'
  10613. .TH MAILGO 6  "5 April 1991"
  10614. .SH NAME
  10615. mailgo - shell script for using mgt to automate email go games
  10616. .SH SYNOPSIS
  10617. .B mailgo [\-r] [\-n] [\-c] [filename]
  10618. .SH DESCRIPTION
  10619. .B mailgo
  10620. helps manage email games by processing Smart-Go game records received by
  10621. mail, invoking mgt, and automatically sending your next move back.
  10622. .LP
  10623. Invoking 
  10624. .B mailgo 
  10625. with no flags instructs the program to search the specified file for a
  10626. go game, ignoring mail headers or other such garbage.  
  10627. .B mailgo 
  10628. will invoke the game processor specified in the environment variable
  10629. MAILGO or of this variable is undefined, will attempt to run 
  10630. .B mgt
  10631. from the inherited path.
  10632. .LP
  10633. If your opponent loses your move, you can resend the game with the \-r
  10634. switch.
  10635. .LP
  10636. To start a new game, use the \-n switch.  Without a file, you will be 
  10637. prompted for your address, your opponent's address, and the filename for
  10638. both your and your opponent's local game record.  The game processor will
  10639. then be invoked for you to make the first move.  If a filename is specified,
  10640. the address and filename data is taken from that file.
  10641. .LP
  10642. The \-c flag causes the program to delete any extraneous files it might have
  10643. created during a previous run which was abnormally terminated.
  10644. .SH FILE FORMAT
  10645. .LP
  10646. .sp
  10647. .if
  10648.  Leading garbage ignored
  10649.  
  10650.  ---GoGaMeStArT---
  10651.  TO: opponent@hissite
  10652.  TOFILE: his_game_record
  10653.  FROM: me@mysite
  10654.  FROMFILE: my_game_record
  10655.  FORMAT: format_code
  10656.  (
  10657.  Smart\-Go game data
  10658.  )
  10659.  ---GoGaMeEnD---
  10660.  
  10661.  Trailing garbage ignored
  10662. .fi
  10663. .LP
  10664. The game data file contains a leading tag to indicate the start of 
  10665. the data.  It contains both addresses, as should be used to mail the
  10666. game files, and it contains the files to store the games in.  In the
  10667. example above, you are playing opponent@hissite, and the game is being
  10668. stored in my_game_record.
  10669. .LP
  10670. The file format used can be either long, short, or extrashort indicated by L, 
  10671. S, and E respectively.  The long format uses the full size Smart-Go file 
  10672. saved with no options from mgt.  The extrashort format uses mgt with the \-s 
  10673. option to save short format files.  This format may cause problems for some
  10674. mailers, however, because the lines will grow longer than 512 bytes.
  10675. The short format is similar to the extrashort format but has extra newlines
  10676. inserted.  The short format is the default when selecting format from
  10677. the prompt, but the long format is the default if a file contains no FORMAT
  10678. line.
  10679. When 
  10680. .B mailgo
  10681. is used normally, the file specified on the command line is removed at
  10682. successful completion, and the new game is saved to the file specified in
  10683. the received game record.  If the destination file does not look like
  10684. a mailgo file, 
  10685. .B mailgo
  10686. will query for confirmation.
  10687. .SH FILES
  10688. mgt
  10689. .LP
  10690. Smart-Go.def, the Smart\-Go format definition.
  10691. .sp
  10692. .SH BUGS
  10693. .LP
  10694. If you attempt to start a new game, but are not the first player to make a 
  10695. real move, then you will have to convince mgt that you have changed the game 
  10696. record.  Do this by pressing z twice on a blank spot to set and remove a black 
  10697. stone.
  10698. .fi
  10699. .sp
  10700. .SH AUTHOR
  10701. Adrian Mariano (adrian@u.washington.edu)
  10702. SHAR_EOF
  10703. fi # end of overwriting check
  10704. #    End of shell archive
  10705. exit 0
  10706.