home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xwidget2.sh < prev   
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  75.5 KB  |  2,374 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    Goban.c
  7. #    Goban.doc
  8. #    Goban.h
  9. #    GobanP.h
  10. #    Imakefile
  11. #    README
  12. #    blackstone.bm
  13. #    graystone.bm
  14. #    gw.ad
  15. #    gw.c
  16. #    stonemask.bm
  17. #    whitestone.bm
  18. # This archive created: Wed Aug 12 10:16:09 1992
  19. export PATH; PATH=/bin:/usr/bin:$PATH
  20. if test -f 'Goban.c'
  21. then
  22.     echo shar: "will not over-write existing file 'Goban.c'"
  23. else
  24. cat << \SHAR_EOF > 'Goban.c'
  25. /****************************************************************************************************************
  26.  *
  27.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  28.  *
  29.  *  This program is distributed in the hope that it will be useful.
  30.  *  Use and copying of this software and preparation of derivative works
  31.  *  based upon this software are permitted, so long as the following
  32.  *  conditions are met:
  33.  *       o credit to the authors is acknowledged following current
  34.  *         academic behaviour
  35.  *       o no fees or compensation are charged for use, copies, or
  36.  *         access to this software
  37.  *       o this copyright notice is included intact.
  38.  *  This software is made available AS IS, and no warranty is made about 
  39.  *  the software or its performance. 
  40.  * 
  41.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  42.  *  Send them to    dumesnil@etca.fr   or to:
  43.  *       
  44.  *       Antoine de Maricourt
  45.  *       ETCA CREA-SP
  46.  *       16 bis, avenue Prieur de la Cote d'Or
  47.  *       94114 Arcueil Cedex
  48.  *       France
  49.  */
  50.  
  51. #include <X11/IntrinsicP.h>
  52. #include <X11/StringDefs.h>
  53. #include <X11/Xlib.h>
  54. #include <X11/cursorfont.h>
  55.  
  56. #include "GobanP.h"
  57.  
  58. #include "whitestone.bm"
  59. #include "blackstone.bm"
  60. #include "graystone.bm"
  61. #include "stonemask.bm"
  62.  
  63. #define offset(field) XtOffset (GobanWidget, goban.field)
  64.  
  65. static XtResource resources[] = {
  66.   { XtNautoRedisplay     , XtCAutoRedisplay     , XtRBoolean   , sizeof (Boolean)      ,
  67.       offset (auto_redisplay)     , XtRImmediate     , (caddr_t) TRUE         },
  68.   { XtNviewBottom        , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  69.       offset (bottom)             , XtRImmediate     , (caddr_t) 1            },
  70.   { XtNcursor            , XtCCursor            , XtRInt       , sizeof (int)          ,
  71.       offset (cursor)             , XtRImmediate     , (caddr_t) GbCGrayStone },
  72.   { XtNfont              , XtCFont              , XtRFontStruct, sizeof (XFontStruct *),
  73.       offset (font)               , XtRString        , "fixed"                },
  74.   { XtNforeground        , XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  75.       offset (foreground)         , XtRString   , XtDefaultForeground    },
  76.   { XtNgameSize          , XtCSize              , XtRDimension , sizeof (Dimension)    ,
  77.       offset (game_size)          , XtRImmediate, (caddr_t) 19           },
  78.   { XtNviewLeft          , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  79.       offset (left)               , XtRImmediate, (caddr_t) 1            },
  80.   { XtNdisplayCoordinates, XtCDisplayCoordinates, XtRBoolean   , sizeof (Boolean)      ,
  81.       offset (display_coordinates), XtRImmediate, (caddr_t) TRUE         },
  82.   { XtNpointSize         , XtCSize              , XtRDimension , sizeof (Dimension)    ,
  83.       offset (point_size)         , XtRImmediate     , (caddr_t) 26           },
  84.   { XtNviewRight         , XtCPosition          , XtRPosition  , sizeof (Position)     ,
  85.       offset (right)              , XtRImmediate     , (caddr_t) 19           },
  86.   { XtNviewTop           , XtCPosition          , XtRPosition  , sizeof (Position)     , 
  87.       offset (top)                , XtRImmediate     , (caddr_t) 19           },
  88.   { XtNwhiteStoneForeground, XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  89.       offset (white_fg)           , XtRString   , "black"    },
  90.   { XtNwhiteStoneBackground, XtCBackground        , XtRPixel     , sizeof (Pixel)        ,
  91.       offset (white_bg)           , XtRString   , "white"    },
  92.   { XtNwhiteStoneBorder    , XtCBorderColor       , XtRPixel     , sizeof (Pixel)        ,
  93.       offset (white_bd)           , XtRString   , "black"    },
  94.   { XtNblackStoneForeground, XtCForeground        , XtRPixel     , sizeof (Pixel)        ,
  95.       offset (black_fg)           , XtRString   , "white"    },
  96.   { XtNblackStoneBackground, XtCBackground        , XtRPixel     , sizeof (Pixel)        ,
  97.       offset (black_bg)           , XtRString   , "black"    },
  98.   { XtNblackStoneBorder    , XtCBorderColor       , XtRPixel     , sizeof (Pixel)        ,
  99.       offset (black_bd)           , XtRString   , "black"    },
  100. };
  101.  
  102. static void    ClassInitialize ();
  103. static void    Initialize      ();
  104. static void    Redisplay       ();
  105. static void    Realize         ();
  106. static void    Destroy         ();
  107. static void    Resize          ();
  108. static void    DrawPoint       ();
  109. static Boolean SetValues       ();
  110.  
  111. GobanClassRec gobanClassRec = {
  112.   { /* core fields */
  113.     /* superclass        */    (WidgetClass) &widgetClassRec,
  114.     /* class_name        */    "Goban",
  115.     /* widget_size        */    sizeof (GobanRec),
  116.     /* class_initialize        */    ClassInitialize,
  117.     /* class_part_initialize    */    NULL,
  118.     /* class_inited        */    FALSE,
  119.     /* initialize        */    Initialize,
  120.     /* initialize_hook        */    NULL,
  121.     /* realize            */    Realize,
  122.     /* actions            */    NULL,
  123.     /* num_actions        */    0,
  124.     /* resources        */    resources,
  125.     /* num_resources        */    XtNumber (resources),
  126.     /* xrm_class        */    NULLQUARK,
  127.     /* compress_motion        */    TRUE,
  128.     /* compress_exposure    */    TRUE,
  129.     /* compress_enterleave    */    TRUE,
  130.     /* visible_interest        */    FALSE,
  131.     /* destroy            */    Destroy,
  132.     /* resize            */    Resize,
  133.     /* expose            */    Redisplay,
  134.     /* set_values        */    SetValues,
  135.     /* set_values_hook        */    NULL,
  136.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  137.     /* get_values_hook        */    NULL,
  138.     /* accept_focus        */    NULL,
  139.     /* version            */    XtVersion,
  140.     /* callback_private        */    NULL,
  141.     /* tm_table            */    NULL,
  142.     /* query_geometry        */    XtInheritQueryGeometry,
  143.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  144.     /* extension        */    NULL
  145.   }
  146. };
  147.  
  148. WidgetClass gobanWidgetClass = (WidgetClass) &gobanClassRec;
  149.  
  150. /****************************************************************************************************************
  151.  */
  152.  
  153. void GbRedisplayBoard (w)
  154. Widget w;
  155. {
  156.   GobanWidget gw      = (GobanWidget) w;
  157.   Dimension   width   = w->core.width;
  158.   Dimension   height  = w->core.height;
  159.  
  160.   if (XtIsRealized (w))
  161.     XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, 0, 0, width, height, 0, 0);
  162. }
  163.  
  164. /****************************************************************************************************************
  165.  */
  166.  
  167. void GbClearBoard (w)
  168. Widget w;
  169. {
  170.   GobanWidget gw        = (GobanWidget) w;
  171.   Boolean     redisplay = gw->goban.auto_redisplay;
  172.   Position    x;
  173.   Position    y;
  174.  
  175.   gw->goban.auto_redisplay = FALSE;
  176.  
  177.   for (x = 1; x <= gw->goban.game_size; x++)
  178.     for (y = 1; y <= gw->goban.game_size; y++)
  179.       GbSetPoint (w, x, y, GbEmptyPoint);
  180.  
  181.   gw->goban.auto_redisplay = redisplay;
  182.  
  183.   if (redisplay == TRUE)
  184.     GbRedisplayBoard (w);
  185. }
  186.  
  187. /****************************************************************************************************************
  188.  */
  189.  
  190. void GbClearMarks (w)
  191. Widget w;
  192. {
  193.   GobanWidget gw        = (GobanWidget) w;
  194.   Boolean     redisplay = gw->goban.auto_redisplay;
  195.   Position    x;
  196.   Position    y;
  197.  
  198.   gw->goban.auto_redisplay = FALSE;
  199.  
  200.   for (x = 1; x <= gw->goban.game_size; x++)
  201.     for (y = 1; y <= gw->goban.game_size; y++) {
  202.  
  203.       gw->goban.points[x][y].mark1 = 0;
  204.       gw->goban.points[x][y].mark2 = 0;
  205.       gw->goban.points[x][y].num   = 0;
  206.     
  207.       if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
  208.     if (gw->goban.points[x][y].free == 1)
  209.       DrawPoint (w, x, y, GbEmptyPoint);
  210.     else
  211.       if (gw->goban.points[x][y].black == 1)
  212.         DrawPoint (w, x, y, GbBlackStone);
  213.       else
  214.         DrawPoint (w, x, y, GbWhiteStone);
  215.     }
  216.  
  217.   gw->goban.auto_redisplay = redisplay;
  218.  
  219.   if (redisplay == TRUE)
  220.     GbRedisplayBoard (w);
  221. }
  222.  
  223. /****************************************************************************************************************
  224.  */
  225.  
  226. /* ARGSUSED */
  227.  
  228. void GbSetPoint (w, x, y, color)
  229. Widget       w;
  230. Position     x;
  231. Position     y;
  232. GbPointState color;
  233. {
  234.   GobanWidget gw = (GobanWidget) w;
  235.  
  236.   if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  237.     switch (color) {
  238.  
  239.     case GbBlackStone :
  240.       gw->goban.points[x][y].free  = 0;
  241.       gw->goban.points[x][y].black = 1;
  242.       break;
  243.  
  244.     case GbWhiteStone :
  245.       gw->goban.points[x][y].free  = 0;
  246.       gw->goban.points[x][y].black = 0;
  247.       break;
  248.  
  249.     case GbEmptyPoint :
  250.       gw->goban.points[x][y].free  = 1;
  251.       break;
  252.     }
  253.     
  254.     gw->goban.points[x][y].num   = 0;
  255.     gw->goban.points[x][y].mark1 = 0;
  256.     gw->goban.points[x][y].mark2 = 0;
  257.  
  258.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
  259.       DrawPoint (w, x, y, color);
  260.   }
  261. }
  262.  
  263. /****************************************************************************************************************
  264.  */
  265.  
  266. /* ARGSUSED */
  267.  
  268. Boolean GbGetPositionFromStone (w, x, y)
  269. GobanWidget   w;
  270. Position     *x;
  271. Position     *y;
  272. {
  273.   if (*x >= w->goban.left && *y >= w->goban.bottom && *x <= w->goban.right && *y <= w->goban.top) {
  274.     
  275.     *x = ((w->goban.x_offset + w->goban.point_size * *x) * 2 + w->goban.point_size) / 2;
  276.     *y = ((w->goban.y_offset - w->goban.point_size * *y) * 2 + w->goban.point_size) / 2;
  277.     
  278.     return TRUE;
  279.   }
  280.   
  281.   else 
  282.     return FALSE;
  283. }
  284.  
  285. /****************************************************************************************************************
  286.  */
  287.  
  288. /* ARGSUSED */
  289.  
  290. Boolean GbGetStoneFromPosition (w, x, y)
  291. Widget     w;
  292. Position  *x;
  293. Position  *y;
  294. {
  295.   GobanWidget gw         = (GobanWidget) w;
  296.   Dimension   point_size = gw->goban.point_size;
  297.   Position    xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  298.   Position    ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  299.   Position    xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  300.   Position    ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  301.  
  302.   if (*x > xmin && *x < xmax && *y > ymin && *y < ymax) {
  303.  
  304.     *x = (*x - gw->goban.x_offset - 1) / point_size;
  305.     *y = (gw->goban.y_offset - *y + point_size + 1) / point_size;
  306.  
  307.     return TRUE;
  308.   }
  309.  
  310.   return FALSE;
  311. }
  312.  
  313. /****************************************************************************************************************
  314.  */
  315.  
  316. void GbSetNum (w, x, y, num)
  317. Widget      w;
  318. Position    x;
  319. Position    y;
  320. int         num;
  321. {
  322.   GobanWidget  gw      = (GobanWidget) w;
  323.   Display     *display = XtDisplay (w);
  324.   GC           draw_gc;
  325.   GC           undraw_gc;
  326.   XCharStruct  extent;
  327.   XExposeEvent event;
  328.   int          ascent;
  329.   int          descent;
  330.   int          direction;
  331.   int          X;
  332.   int          Y;
  333.   char         s[3];
  334.   int          len = 0;
  335.  
  336.   if (num >= 0 && num <= 999 && x >= 1 && y >= 1  && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  337.     
  338.     gw->goban.points[x][y].num   = num;
  339.     gw->goban.points[x][y].mark1 = 0;
  340.     gw->goban.points[x][y].mark2 = 0;
  341.     
  342.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
  343.       
  344.       if (gw->goban.points[x][y].free == 0) {
  345.     
  346.     if (num == 0) {
  347.       if (gw->goban.points[x][y].black == 1)
  348.         DrawPoint (w, x, y, GbBlackStone);
  349.       else
  350.         DrawPoint (w, x, y, GbWhiteStone);
  351.     }
  352.     
  353.     else {
  354.       if (gw->goban.points[x][y].black == 1) {
  355.         draw_gc   = gw->goban.black_fg_gc;
  356.         undraw_gc = gw->goban.black_bg_gc;
  357.       } else {
  358.         draw_gc   = gw->goban.white_fg_gc;
  359.         undraw_gc = gw->goban.white_bg_gc;
  360.       }
  361.       
  362.       X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
  363.       Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
  364.       
  365.       if (num > 99)
  366.         s[len++] = '0' + (num % 1000) / 100;
  367.       if (num > 9)
  368.         s[len++] = '0' + (num % 100) / 10;
  369.       s[len++] = '0' + num % 10;
  370.       
  371.       XQueryTextExtents (display, XGContextFromGC (draw_gc),
  372.                  s, len, &direction, &ascent, &descent, &extent);
  373.       
  374.       if (extent.width + extent.descent + extent.ascent < gw->goban.point_size - 1) {
  375.         XFillArc (display, gw->goban.picture, undraw_gc, 
  376.               (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  377.               (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  378.               0, 360 * 64);
  379.         XDrawString (display, gw->goban.picture, draw_gc,
  380.              (X - extent.width) / 2 - extent.lbearing + 1, 
  381.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  382.       }
  383.     
  384.       if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  385.         event.x      = (X - gw->goban.point_size) / 2;
  386.         event.y      = (Y - gw->goban.point_size) / 2;
  387.         event.width  = gw->goban.point_size;
  388.         event.height = gw->goban.point_size;
  389.         
  390.         Redisplay (w, &event, (Region) NULL);
  391.       }
  392.     }
  393.       }
  394.     }
  395.   }
  396. }
  397.  
  398. /****************************************************************************************************************
  399.  */
  400.  
  401. void GbSetMark (w, x, y, c1, c2)
  402. Widget        w;
  403. Position      x;
  404. Position      y;
  405. unsigned char c1;
  406. unsigned char c2;
  407. {
  408.   GobanWidget  gw      = (GobanWidget) w;
  409.   Display     *display = XtDisplay (w);
  410.   int          len     = 0;
  411.   XCharStruct  extent;
  412.   XExposeEvent event;
  413.   int          ascent;
  414.   int          descent;
  415.   int          direction;
  416.   int          X;
  417.   int          Y;
  418.   int          radius;
  419.   char         s[2];
  420.   XSegment     segment[4];
  421.   GC           mark_gc;
  422.   GC           erase_gc;
  423.   
  424.   if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
  425.    
  426.     if (c1 != 0 || c2 != 0)
  427.       GbSetMark (w, x, y, 0, 0);
  428.      
  429.     gw->goban.points[x][y].mark1 = c1;
  430.     gw->goban.points[x][y].mark2 = c2;
  431.     gw->goban.points[x][y].num   = 0;
  432.  
  433.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
  434.       
  435.       if (c1 == 0 && c2 == 0) {
  436.     if (gw->goban.points[x][y].free == 0)
  437.       if (gw->goban.points[x][y].black == 1)
  438.         DrawPoint (w, x, y, GbBlackStone);
  439.       else
  440.         DrawPoint (w, x, y, GbWhiteStone);
  441.     else
  442.       DrawPoint (w, x, y, GbEmptyPoint);
  443.       }
  444.       
  445.       else {
  446.     X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
  447.     Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
  448.               
  449.     if (gw->goban.points[x][y].free == 0)
  450.       if (gw->goban.points[x][y].black == 1) {
  451.         mark_gc  = gw->goban.black_fg_gc;
  452.         erase_gc = gw->goban.black_bg_gc;
  453.       }
  454.       else {
  455.         mark_gc  = gw->goban.white_fg_gc;
  456.         erase_gc = gw->goban.white_bg_gc;
  457.       }
  458.  
  459.     else {
  460.       mark_gc  = gw->goban.foreground_gc;
  461.       erase_gc = gw->goban.background_gc;
  462.     }
  463.     
  464.     if (c1 == 0) {
  465.       radius = 10 * gw->goban.point_size / 15;
  466.       
  467.       if (gw->goban.points[x][y].free == 0)
  468.           XFillArc (display, gw->goban.picture, erase_gc, 
  469.             (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  470.             (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  471.             0, 360 * 64);
  472.       else
  473.         XFillArc (display, gw->goban.picture, erase_gc,
  474.               (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  475.               (unsigned int) radius, (unsigned int) radius, 
  476.               0, 360 * 64);
  477.  
  478.       switch (c2) {
  479.         
  480.       case GbMTriangleMark :
  481.         radius -= 4;
  482.  
  483.         segment[0].x1 = (short) X / 2;
  484.         segment[0].x2 = (short) (X / 2 + (86 * radius + 100) / 200);
  485.         segment[0].y1 = (short) (Y / 2 - (radius - 1) / 2);
  486.         segment[0].y2 = (short) (Y / 2 + (radius + 4) / 4);
  487.         
  488.         segment[1].x1 = (short) segment[0].x2;
  489.         segment[1].x2 = (short) (X / 2 - (86 * radius + 100) / 200);
  490.         segment[1].y1 = (short) segment[0].y2;
  491.         segment[1].y2 = (short) (Y / 2 + (radius + 4) / 4);
  492.         
  493.         segment[2].x1 = (short) segment[1].x2;
  494.         segment[2].x2 = (short) segment[0].x1;
  495.         segment[2].y1 = (short) segment[1].y2;
  496.         segment[2].y2 = (short) segment[0].y1;
  497.  
  498.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 3);
  499.         break;
  500.  
  501.       case GbMSquareMark  :
  502.         radius = 10 * radius / 14 - 2;
  503.         
  504.         XDrawRectangle (display, gw->goban.picture, mark_gc, 
  505.                 (X - radius) / 2, (Y - radius) / 2, 
  506.                 (unsigned int) radius, (unsigned int) radius);
  507.         break;
  508.     
  509.       case GbMDCrossMark  :
  510.         radius = 10 * radius / 14 - 2;
  511.  
  512.         segment[0].x1 = (short) (X - radius) / 2;
  513.         segment[0].x2 = (short) segment[0].x1    + radius;
  514.         segment[0].y1 = (short) (Y - radius) / 2;
  515.         segment[0].y2 = (short) segment[0].y1    + radius;
  516.  
  517.         segment[1].x1 = (short) (X - radius) / 2 + radius;
  518.         segment[1].x2 = (short) segment[1].x1    - radius;
  519.         segment[1].y1 = (short) (Y - radius) / 2;
  520.         segment[1].y2 = (short) segment[1].y1    + radius;
  521.         
  522.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  523.         break;
  524.         
  525.       case GbMVCrossMark  :
  526.         radius -= 4;
  527.  
  528.         segment[0].x1 = (short) X / 2;
  529.         segment[0].x2 = (short) segment[0].x1;
  530.         segment[0].y1 = (short) (Y - radius) / 2;
  531.         segment[0].y2 = (short) segment[0].y1 + radius;
  532.  
  533.         segment[1].x1 = (short) (X - radius) / 2;
  534.         segment[1].x2 = (short) segment[1].x1 + radius;
  535.         segment[1].y1 = (short) Y / 2;
  536.         segment[1].y2 = (short) segment[1].y1;
  537.         
  538.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  539.         break;
  540.  
  541.       case GbMDiamondMark :
  542.         radius -= 4;
  543.  
  544.         segment[0].x1 = (short) X / 2;
  545.         segment[0].x2 = (short) segment[0].x1 + radius / 2;
  546.         segment[0].y1 = (short) (Y - radius) / 2;
  547.         segment[0].y2 = (short) segment[0].y1 + radius / 2;
  548.  
  549.         segment[1].x1 = (short) segment[0].x2;
  550.         segment[1].x2 = (short) segment[0].x1;
  551.         segment[1].y1 = (short) segment[0].y2;
  552.         segment[1].y2 = (short) segment[1].y1 + radius / 2;
  553.         
  554.         segment[2].x1 = (short) segment[1].x2;
  555.         segment[2].x2 = (short) segment[2].x1 - radius / 2;
  556.         segment[2].y1 = (short) segment[1].y2;
  557.         segment[2].y2 = (short) segment[1].y1;
  558.         
  559.         segment[3].x1 = (short) segment[2].x2;
  560.         segment[3].x2 = (short) segment[0].x1;
  561.         segment[3].y1 = (short) segment[2].y2;
  562.         segment[3].y2 = (short) segment[0].y1;
  563.         
  564.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 4);
  565.         break;
  566.       }
  567.     }
  568.     
  569.     else {
  570.       s[len++] = c1;
  571.       if (c2 != 0)
  572.         s[len++] = c2;
  573.       
  574.       XQueryTextExtents (display, XGContextFromGC (mark_gc), s, len, &direction, &ascent, &descent, &extent);
  575.       
  576.       radius = extent.width + extent.descent + extent.ascent;
  577.       
  578.       if (radius < gw->goban.point_size - 1) {
  579.         if (gw->goban.points[x][y].free == 0)
  580.           XFillArc (display, gw->goban.picture, erase_gc, 
  581.             (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  582.             (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  583.             0, 360 * 64);
  584.         else
  585.           XFillArc (display, gw->goban.picture, erase_gc,
  586.             (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  587.             (unsigned int) radius, (unsigned int) radius, 
  588.             0, 360 * 64);
  589.         
  590.         XDrawString (display, gw->goban.picture, mark_gc,
  591.              (X - extent.width) / 2 - extent.lbearing + 1, 
  592.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  593.       }
  594.     }
  595.       
  596.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  597.       event.x      = (X - gw->goban.point_size) / 2;
  598.       event.y      = (Y - gw->goban.point_size) / 2;
  599.       event.width  = gw->goban.point_size;
  600.       event.height = gw->goban.point_size;
  601.       
  602.       Redisplay (w, &event, (Region) NULL);
  603.     }
  604.       }
  605.     }
  606.   }
  607. }
  608.  
  609. /****************************************************************************************************************
  610.  */
  611.  
  612. /* ARGSUSED */
  613.  
  614. static void Redisplay (w, event, region)
  615. Widget        w;
  616. XExposeEvent *event;
  617. Region        region;
  618. {
  619.   GobanWidget gw     = (GobanWidget) w;
  620.   Position    x      = event->x;
  621.   Position    y      = event->y;
  622.   Dimension   width  = event->width;
  623.   Dimension   height = event->height;
  624.  
  625.   XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, x, y, width, height, x, y);
  626. }
  627.  
  628. /****************************************************************************************************************
  629.  */
  630.  
  631. /* ARGSUSED */
  632.  
  633. static void CvtStringToCursor (args, num_args, fromVal, toVal)
  634. XrmValuePtr   args;        /* unused */
  635. Cardinal     *num_args;    /* unused */
  636. XrmValuePtr   fromVal;
  637. XrmValuePtr   toVal;
  638. {
  639.   static int       cursor;
  640.   static XrmQuark  QWhiteStone;
  641.   static XrmQuark  QBlackStone;
  642.   static XrmQuark  QGrayStone;
  643.   XrmQuark         quark;
  644.   char             lowerName[256];
  645.   static Boolean   inited = FALSE;
  646.     
  647.   if (inited == FALSE) {
  648.     QWhiteStone  = XrmStringToQuark (XtEgbWhiteStone);
  649.     QBlackStone  = XrmStringToQuark (XtEgbBlackStone);
  650.     QGrayStone   = XrmStringToQuark (XtEgbGrayStone);
  651.     inited       = TRUE;
  652.   }
  653.  
  654.   XmuCopyISOLatin1Lowered  (lowerName, (String) fromVal->addr);
  655.   quark = XrmStringToQuark (lowerName);
  656.  
  657.   if (quark == QWhiteStone)
  658.     cursor = GbCWhiteStone;
  659.   else if (quark == QBlackStone)       
  660.     cursor = GbCBlackStone;
  661.   else if (quark == QGrayStone)         
  662.     cursor = GbCGrayStone;
  663.   else {
  664.     toVal->size = 0;
  665.     toVal->addr = NULL;
  666.     return;
  667.   }
  668.  
  669.   toVal->size = sizeof (cursor);
  670.   toVal->addr = (caddr_t) &cursor;
  671. }
  672.  
  673. /****************************************************************************************************************
  674.  */
  675.  
  676. static void ClassInitialize()
  677. {
  678.   XtAddConverter (XtRString, XtRInt, (XtConverter) CvtStringToCursor, NULL, 0);
  679. }
  680.  
  681. /****************************************************************************************************************
  682.  */
  683.  
  684. static void InitializePixmap (w)
  685. Widget w;
  686. {
  687.   GobanWidget  gw      = (GobanWidget) w;
  688.   Display     *display = XtDisplay (w);
  689.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  690.   Dimension    width   = w->core.width;
  691.   Dimension    height  = w->core.height;
  692.  
  693.   gw->goban.board   = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  694.   gw->goban.picture = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  695. }
  696.  
  697. /****************************************************************************************************************
  698.  */
  699.  
  700. static void InitializeGC (w)
  701. Widget w;
  702. {
  703.   GobanWidget  gw      = (GobanWidget) w;
  704.   Display     *display = XtDisplay (w);
  705.   XtGCMask     mask    = GCForeground | GCBackground | GCFont;
  706.   XGCValues    values;
  707.  
  708.   values.font             = gw->goban.font->fid;
  709.   values.background       = w->core.background_pixel;
  710.  
  711.   values.foreground       = gw->goban.white_fg;
  712.   gw->goban.white_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  713.   values.foreground       = gw->goban.white_bg;
  714.   gw->goban.white_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  715.   values.foreground       = gw->goban.white_bd;
  716.   gw->goban.white_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  717.  
  718.   values.foreground       = gw->goban.black_fg;
  719.   gw->goban.black_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  720.   values.foreground       = gw->goban.black_bg;
  721.   gw->goban.black_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  722.   values.foreground       = gw->goban.black_bd;
  723.   gw->goban.black_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  724.  
  725.   values.foreground       = gw->goban.foreground;
  726.   gw->goban.foreground_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  727.  
  728.   if (gw->core.background_pixmap != XtUnspecifiedPixmap) {
  729.     values.tile           = gw->core.background_pixmap;
  730.     values.fill_style     = FillTiled;
  731.     mask                 |= GCTile | GCFillStyle;
  732.   }
  733.  
  734.   values.foreground       = w->core.background_pixel;
  735.   values.background       = gw->goban.foreground;
  736.   gw->goban.background_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  737.  
  738.   gw->goban.copy_gc       = XCreateGC  (display, gw->goban.picture, (XtGCMask) 0, (XGCValues *) NULL);
  739. }
  740.  
  741. /****************************************************************************************************************
  742.  */ 
  743. static void InitializeCursor (w)
  744. Widget w;
  745. {
  746.   GobanWidget  gw      = (GobanWidget) w;
  747.   Display     *display = XtDisplay (w);
  748.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  749.   Pixel        black   = BlackPixel (display, DefaultScreen (display));
  750.   Pixel        white   = WhitePixel (display, DefaultScreen (display));
  751.  
  752.   static XColor black_color = { 0,    0,     0,     0  };  /* black */
  753.   static XColor white_color = { 0, 65535, 65535, 65535 };  /* white */
  754.  
  755.   /* Some teminals invert the mask with BlackPixel and WhitePixel     */
  756.   /* should use black and white instead of 1 and 0 but depth is 1 ... */
  757.   /* will probably have trouble with some special colormaps           */
  758.  
  759.   gw->goban.white_stone = XCreatePixmapFromBitmapData
  760.     (display, window, whitestone_bits, whitestone_width, whitestone_height, 1, 0, 1);
  761.   gw->goban.black_stone = XCreatePixmapFromBitmapData
  762.     (display, window, blackstone_bits, blackstone_width, blackstone_height, 1, 0, 1);
  763.   gw->goban.gray_stone  = XCreatePixmapFromBitmapData
  764.     (display, window, graystone_bits , graystone_width , graystone_height , 1, 0, 1);
  765.   gw->goban.mouse_mask  = XCreatePixmapFromBitmapData
  766.     (display, window, stonemask_bits , stonemask_width , stonemask_height , 1, 0, 1);
  767.  
  768.   gw->goban.white_cursor = 
  769.     XCreatePixmapCursor (display, gw->goban.white_stone, gw->goban.mouse_mask, 
  770.              &black_color, &white_color, whitestone_x_hot, whitestone_y_hot);
  771.   gw->goban.black_cursor = 
  772.     XCreatePixmapCursor (display, gw->goban.black_stone, gw->goban.mouse_mask, 
  773.              &black_color, &white_color, blackstone_x_hot, blackstone_y_hot);
  774.   gw->goban.gray_cursor  = 
  775.     XCreatePixmapCursor (display, gw->goban.gray_stone, gw->goban.mouse_mask,  
  776.              &black_color, &white_color, graystone_x_hot , graystone_y_hot );
  777.  
  778.   gw->goban.font_cursor  = XCreateFontCursor (display, XC_question_arrow);
  779. }
  780.   
  781. /****************************************************************************************************************
  782.  */
  783.  
  784. static void DestroyPixmap (w)
  785. Widget w;
  786. {
  787.   GobanWidget  gw      = (GobanWidget) w;
  788.   Display     *display = XtDisplay (w);
  789.  
  790.   XFreePixmap (display, gw->goban.picture);
  791.   XFreePixmap (display, gw->goban.board  );
  792. }
  793.  
  794. /****************************************************************************************************************
  795.  */
  796.  
  797. static void DestroyGC (w)
  798. Widget w;
  799. {
  800.   GobanWidget  gw      = (GobanWidget) w;
  801.   Display     *display = XtDisplay (w);
  802.  
  803.   XFreeGC (display, gw->goban.black_fg_gc  );
  804.   XFreeGC (display, gw->goban.black_bg_gc  );
  805.   XFreeGC (display, gw->goban.black_bd_gc  );
  806.   XFreeGC (display, gw->goban.white_fg_gc  );
  807.   XFreeGC (display, gw->goban.white_bg_gc  );
  808.   XFreeGC (display, gw->goban.white_bd_gc  );
  809.   XFreeGC (display, gw->goban.foreground_gc);
  810.   XFreeGC (display, gw->goban.background_gc);
  811.   XFreeGC (display, gw->goban.copy_gc      );
  812. }
  813.  
  814. /****************************************************************************************************************
  815.  */
  816.  
  817. static void Destroy (w)
  818. Widget w;
  819. {
  820.   GobanWidget  gw      = (GobanWidget) w;
  821.   Display     *display = XtDisplay (w);
  822.  
  823.   DestroyPixmap (w);
  824.   DestroyGC     (w);
  825.  
  826.   XFreePixmap (display, gw->goban.white_stone  );
  827.   XFreePixmap (display, gw->goban.black_stone  );
  828.   XFreePixmap (display, gw->goban.gray_stone   );
  829.   XFreePixmap (display, gw->goban.mouse_mask   );
  830.  
  831.   XFreeCursor (display, gw->goban.white_cursor );
  832.   XFreeCursor (display, gw->goban.black_cursor );
  833.   XFreeCursor (display, gw->goban.gray_cursor  );
  834.   XFreeCursor (display, gw->goban.font_cursor  );
  835. }
  836.  
  837. /****************************************************************************************************************
  838.  */
  839.  
  840. static void Realize (w, valuemaskp, attr)
  841. Widget                w;
  842. XtValueMask          *valuemaskp;
  843. XSetWindowAttributes *attr;
  844. {
  845.   GobanWidget  gw      = (GobanWidget) w;
  846.   
  847.   *valuemaskp |= CWCursor;
  848.  
  849.   switch (gw->goban.cursor) {
  850.   case GbCGrayStone  : attr->cursor = gw->goban.gray_cursor ; break;
  851.   case GbCBlackStone : attr->cursor = gw->goban.black_cursor; break;
  852.   case GbCWhiteStone : attr->cursor = gw->goban.white_cursor; break;
  853.   default            : attr->cursor = gw->goban.font_cursor ; break;
  854.   }
  855.   
  856.   XtCreateWindow (w, InputOutput, (Visual *) CopyFromParent, *valuemaskp, attr);
  857. }
  858.  
  859. /****************************************************************************************************************
  860.  */
  861.  
  862. static char *stars[18] = {
  863.   "",                /*  2  */  
  864.   "",                /*  3  */  
  865.   "",                /*  4  */  
  866.   "",                /*  5  */  
  867.   "",                /*  6  */  
  868.   "",                /*  7  */  
  869.   "cccffcff",            /*  8  */    
  870.   "cccgeegcgg",            /*  9  */  
  871.   "ccchhchh",            /* 10  */  
  872.   "cccfcifcfffiicifii",        /* 11  */  
  873.   "dddiidii",            /* 12  */  
  874.   "dddjggjdjj",            /* 13  */  
  875.   "dddkkdkk",            /* 14  */  
  876.   "dddhdlhdhhhlldlhll",        /* 15  */  
  877.   "dddmmdmm",            /* 16  */  
  878.   "dddidnidiiinndninn",        /* 17  */  
  879.   "dddoodoo",            /* 18  */  
  880.   "dddjdpjdjjjppdpjpp",        /* 19  */  
  881. };
  882.  
  883. static void DrawBoard (w)
  884. Widget w;
  885. {
  886.   GobanWidget  gw         = (GobanWidget) w;
  887.   Display     *display    = XtDisplay (w);
  888.   XSegment     segment[44];
  889.   int          segc;
  890.   Position     game_size  = (Position) gw->goban.game_size;
  891.   Position     point_size = (Position) gw->goban.point_size;
  892.   Position     star_size  = 4;
  893.   Position     xbase      = gw->goban.x_offset + point_size / 2;
  894.   Position     ybase      = gw->goban.y_offset - point_size / 2;
  895.   Position     xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  896.   Position     ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  897.   Position     xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  898.   Position     ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  899.   char        *star;
  900.   int          x;
  901.   int          y;
  902.  
  903.   XFillRectangle (display, gw->goban.board, gw->goban.background_gc, 0, 0, w->core.width, w->core.height);
  904.  
  905.   if (point_size > 0) {
  906.     segc = 0;
  907.     for (y = gw->goban.bottom - 1; y < gw->goban.top; y++, segc++) {
  908.       segment[segc].x1 = (short) Max ((int) xbase + point_size , xmin);
  909.       segment[segc].x2 = (short) Min ((int) xbase + point_size * game_size, xmax);
  910.       segment[segc].y1 = (short) (ybase - point_size * y);
  911.       segment[segc].y2 = (short) (ybase - point_size * y);
  912.     }
  913.     
  914.     for (x = gw->goban.left; x <= gw->goban.right; x++, segc++) {
  915.       segment[segc].x1 = (short) (xbase + point_size * x);
  916.       segment[segc].x2 = (short) (xbase + point_size * x);
  917.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1), ymin);
  918.       segment[segc].y2 = (short) Min (ybase, ymax);
  919.     }
  920.     
  921.     if (gw->goban.top == gw->goban.game_size) {
  922.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  923.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  924.       segment[segc].y1 = (short) (ybase - point_size * (game_size - 1) - 1);
  925.       segment[segc].y2 = (short) (ybase - point_size * (game_size - 1) - 1);
  926.       segc++;
  927.     }
  928.     
  929.     if (gw->goban.bottom == 1) {
  930.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  931.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  932.       segment[segc].y1 = (short) (ybase + 1);
  933.       segment[segc].y2 = (short) (ybase + 1);
  934.       segc++;
  935.     }
  936.     
  937.     if (gw->goban.left == 1) {
  938.       segment[segc].x1 = (short) (xbase + point_size - 1);
  939.       segment[segc].x2 = (short) (xbase + point_size - 1);
  940.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin); 
  941.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  942.       segc++;
  943.     }
  944.     
  945.     if (gw->goban.right == gw->goban.game_size) {
  946.       segment[segc].x1 = (short) (xbase + point_size * game_size + 1);
  947.       segment[segc].x2 = (short) (xbase + point_size * game_size + 1);
  948.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin);
  949.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  950.       segc++;
  951.     }
  952.     
  953.     XDrawSegments (display, gw->goban.board, gw->goban.foreground_gc, segment, segc);
  954.     
  955.     if (point_size > 8) {
  956.       star_size = (point_size > 10) ? 4 : 2;
  957.       star      = stars[game_size - 2];
  958.       
  959.       while (*star != '\0') {
  960.     x = *star++ - 'a' + 1;
  961.     y = *star++ - 'a' + 1;
  962.     
  963.     if (x >= gw->goban.left && x <= gw->goban.right && y >= gw->goban.bottom && y <= gw->goban.top) {
  964.       x = gw->goban.x_offset + (point_size * (2 * x + 1)) / 2;
  965.       y = gw->goban.y_offset - (point_size * (2 * y - 1)) / 2;
  966.       
  967.       XDrawArc (display, gw->goban.board, gw->goban.foreground_gc, 
  968.             (int) x - star_size / 2, (int) y - star_size / 2, 
  969.             (unsigned int) star_size, (unsigned int) star_size, 
  970.             0, 64 * 360);
  971.       XFillArc (display, gw->goban.board, gw->goban.foreground_gc, 
  972.             (int) x - star_size / 2, (int) y - star_size / 2, 
  973.             (unsigned int) star_size, (unsigned int) star_size, 
  974.             0, 64 * 360);
  975.     }
  976.       }
  977.     }
  978.   }
  979.  
  980.   XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, 0, 0, 
  981.          w->core.width, w->core.height, 0, 0);
  982. }
  983.  
  984. /****************************************************************************************************************
  985.  */
  986.  
  987. static void DrawCoordinates (w)
  988. Widget w;
  989. {
  990.   GobanWidget  gw         = (GobanWidget) w;
  991.   Display     *display    = XtDisplay (w);
  992.   XCharStruct  extent;
  993.   int          point_size = gw->goban.point_size;
  994.   char         s[2];
  995.   int          len;
  996.   int          ascent;
  997.   int          descent;
  998.   int          direction;
  999.   int          xbase;
  1000.   int          ybase;
  1001.   int          x;
  1002.   int          y;
  1003.   unsigned int width;
  1004.   unsigned int height;
  1005.  
  1006.   s[0] = s[1] = '8';
  1007.   XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1008.              s, 2, &direction, &ascent, &descent, &extent);
  1009.  
  1010.   if ((point_size > extent.width + 2) && (point_size > extent.ascent + extent.descent + 2)) {
  1011.     xbase = 2 * gw->goban.x_offset + point_size;
  1012.     ybase = 2 * gw->goban.y_offset - point_size;
  1013.  
  1014.     if (gw->goban.display_coordinates == TRUE) {
  1015.     
  1016.       for (x = gw->goban.left; x <= gw->goban.right; x++) {
  1017.     s[0] = 'A' - 1 + ((x > 8) ? (x + 1) : x);
  1018.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1019.                s, 1, &direction, &ascent, &descent, &extent);
  1020.  
  1021.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1022.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1023.              (ybase + extent.ascent - extent.descent) / 2 - point_size * gw->goban.top + 1, s, 1);
  1024.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1025.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1026.              (ybase + extent.ascent - extent.descent) / 2 - point_size * (gw->goban.bottom - 2) + 1, s, 1);
  1027.       }
  1028.     }
  1029.  
  1030.     x      = gw->goban.x_offset + point_size * gw->goban.left;
  1031.     y      = gw->goban.y_offset - point_size * (gw->goban.top + 1);
  1032.     width  = point_size * (gw->goban.right - gw->goban.left + 1);
  1033.     height = point_size;
  1034.     
  1035.     if (gw->goban.display_coordinates == FALSE)
  1036.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1037.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1038.  
  1039.     y      = gw->goban.y_offset - point_size * (gw->goban.bottom - 1);
  1040.  
  1041.     if (gw->goban.display_coordinates == FALSE)
  1042.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1043.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1044.     
  1045.     ybase += 2 * point_size;
  1046.  
  1047.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1048.       if (gw->goban.display_coordinates == TRUE) {
  1049.     len = 0;
  1050.     if (y > 9)
  1051.       s[len++] = '1';
  1052.     s[len++] = '0' + y % 10;
  1053.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1054.                s, len, &direction, &ascent, &descent, &extent);
  1055.  
  1056.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1057.              (xbase - extent.width) / 2 + point_size * (gw->goban.left  - 1) - extent.lbearing + 1, 
  1058.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1059.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1060.              (xbase - extent.width) / 2 + point_size * (gw->goban.right + 1) - extent.lbearing + 1, 
  1061.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1062.       }
  1063.     }
  1064.  
  1065.     x      = gw->goban.x_offset + point_size * (gw->goban.left  - 1);
  1066.     y      = gw->goban.y_offset - point_size * gw->goban.top;
  1067.     width  = point_size;
  1068.     height = point_size * (gw->goban.top - gw->goban.bottom + 1);;
  1069.     
  1070.     if (gw->goban.display_coordinates == FALSE)
  1071.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1072.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1073.  
  1074.     x      = gw->goban.x_offset + point_size * (gw->goban.right + 1);
  1075.     
  1076.     if (gw->goban.display_coordinates == FALSE)
  1077.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1078.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1079.   }
  1080.  
  1081. }
  1082.  
  1083. /****************************************************************************************************************
  1084.  */
  1085.  
  1086. static void InitializeSize (w)
  1087. Widget w;
  1088. {  
  1089.   GobanWidget  gw        = (GobanWidget) w;
  1090.   Position     bottom    = Min (gw->goban.bottom, gw->goban.top  );
  1091.   Position     left      = Min (gw->goban.left  , gw->goban.right);
  1092.   Position     top       = Max (gw->goban.bottom, gw->goban.top  );
  1093.   Position     right     = Max (gw->goban.left  , gw->goban.right);
  1094.   Dimension    game_size = gw->goban.game_size;
  1095.   Dimension    width;
  1096.   Dimension    height;
  1097.  
  1098.   game_size = (game_size > 1      && game_size <  20       ) ? game_size : 19;
  1099.   bottom    = (bottom    > 0      && bottom    <  game_size) ? bottom    : 1;
  1100.   left      = (left      > 0      && left      <  game_size) ? left      : 1;
  1101.   top       = (top       > bottom && top       <= game_size) ? top       : game_size;
  1102.   right     = (right     > left   && right     <= game_size) ? right     : game_size;
  1103.  
  1104.   width     = right - left   + 3;
  1105.   height    = top   - bottom + 3;
  1106.  
  1107.   if ((w->core.height == 0) && (w->core.width == 0)) {
  1108.     w->core.width  = gw->goban.point_size * width ;
  1109.     w->core.height = gw->goban.point_size * height;
  1110.   } 
  1111.  
  1112.   else 
  1113.     gw->goban.point_size = Min (w->core.width / width, w->core.height / height);
  1114.  
  1115.   gw->goban.game_size = game_size;
  1116.   gw->goban.bottom    = bottom;
  1117.   gw->goban.left      = left;
  1118.   gw->goban.top       = top;
  1119.   gw->goban.right     = right;
  1120.   gw->goban.x_offset  = (int) (w->core.width  - gw->goban.point_size * (width  + 2 * left - 2)) / 2;
  1121.   gw->goban.y_offset  = (int) (w->core.height - gw->goban.point_size * (height - 2 * top  - 2)) / 2;
  1122. }
  1123.  
  1124. /****************************************************************************************************************
  1125.  */
  1126.  
  1127. /* ARGSUSED */
  1128.  
  1129. static void Initialize (request, new)
  1130. Widget request;
  1131. Widget new;
  1132. {
  1133.   InitializeSize   (new);
  1134.   InitializePixmap (new);
  1135.   InitializeGC     (new);
  1136.   InitializeCursor (new);
  1137.   DrawBoard        (new);
  1138.   DrawCoordinates  (new);
  1139.   GbClearBoard     (new);
  1140. }
  1141.  
  1142. /****************************************************************************************************************
  1143.  */
  1144.  
  1145. static void DrawPoint (w, x, y, color)
  1146. Widget      w;
  1147. int         x;
  1148. int         y;
  1149. GbPointState color;
  1150. {
  1151.   GobanWidget   gw      = (GobanWidget) w;
  1152.   Display      *display = XtDisplay (w);
  1153.   unsigned int  size    = (unsigned int) gw->goban.point_size - 2;
  1154.   XExposeEvent  event;
  1155.   int           X;
  1156.   int           Y;
  1157.  
  1158.   if (size > 1) {
  1159.     X = gw->goban.x_offset + gw->goban.point_size * x + 1;
  1160.     Y = gw->goban.y_offset - gw->goban.point_size * y + 1;
  1161.     
  1162.     switch (color)
  1163.       {
  1164.       case GbBlackStone :
  1165.     XFillArc (display, gw->goban.picture, gw->goban.black_bg_gc, X, Y, size, size, 0, 360 * 64);
  1166.     XDrawArc (display, gw->goban.picture, gw->goban.black_bd_gc, X, Y, size, size, 0, 360 * 64);
  1167.     XDrawArc (display, gw->goban.picture, gw->goban.black_fg_gc, X + (int) size / 6, Y + (int) size / 6, 
  1168.           (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1169.     break;
  1170.       case GbWhiteStone :
  1171.     XFillArc (display, gw->goban.picture, gw->goban.white_bg_gc, X, Y, size, size, 0, 360 * 64);
  1172.     XDrawArc (display, gw->goban.picture, gw->goban.white_bd_gc, X, Y, size, size, 0, 360 * 64);
  1173.     XDrawArc (display, gw->goban.picture, gw->goban.white_fg_gc, X + (int) size / 6, Y + (int) size / 6, 
  1174.           (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1175.     break;
  1176.       case GbEmptyPoint :
  1177.     XCopyArea (XtDisplay (w), gw->goban.board, gw->goban.picture, gw->goban.copy_gc,
  1178.            X, Y, gw->goban.point_size, gw->goban.point_size, X, Y); 
  1179.     break;
  1180.       }
  1181.     
  1182.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  1183.       event.x      = X - 1;
  1184.       event.y      = Y - 1;
  1185.       event.width  = gw->goban.point_size;
  1186.       event.height = gw->goban.point_size;
  1187.  
  1188.       Redisplay (w, &event, (Region) NULL);
  1189.     }
  1190.   }
  1191. }
  1192.  
  1193. /****************************************************************************************************************
  1194.  */
  1195.  
  1196. static void RedrawStones (w)
  1197. Widget w;
  1198. {
  1199.   GobanWidget  gw         = (GobanWidget) w;
  1200.   Boolean      redisplay  = gw->goban.auto_redisplay;
  1201.   Position     x;
  1202.   Position     y;
  1203.  
  1204.   gw->goban.auto_redisplay = FALSE;
  1205.  
  1206.   for (x = gw->goban.left; x <= gw->goban.right; x++)
  1207.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1208.       if (gw->goban.points[x][y].free == 0) {
  1209.     if (gw->goban.points[x][y].black == 1)
  1210.       DrawPoint (w, x, y, GbBlackStone);
  1211.     else
  1212.       DrawPoint (w, x, y, GbWhiteStone);
  1213.     if (gw->goban.points[x][y].num > 0)
  1214.       GbSetNum (w, x, y, (int) gw->goban.points[x][y].num);
  1215.       }
  1216.  
  1217.       if (gw->goban.points[x][y].mark1 != 0 || gw->goban.points[x][y].mark2 != 0)
  1218.     GbSetMark (w, x, y, gw->goban.points[x][y].mark1, gw->goban.points[x][y].mark2);
  1219.     }
  1220.  
  1221.   gw->goban.auto_redisplay = redisplay;
  1222.  
  1223.   if (redisplay == TRUE)
  1224.     GbRedisplayBoard (w);
  1225. }
  1226.  
  1227. /****************************************************************************************************************
  1228.  */
  1229.  
  1230. static void Resize (w)
  1231. Widget w;
  1232. {
  1233.   DestroyPixmap    (w);
  1234.   DestroyGC        (w);
  1235.   InitializeSize   (w);
  1236.   InitializePixmap (w);
  1237.   InitializeGC     (w);
  1238.   DrawBoard        (w);
  1239.   DrawCoordinates  (w);
  1240.   RedrawStones     (w);
  1241. }
  1242.  
  1243. /****************************************************************************************************************
  1244.  */
  1245.  
  1246. /* ARGSUSED */
  1247.  
  1248. static Boolean SetValues (current, request, new)
  1249. Widget current;
  1250. Widget request;
  1251. Widget new;
  1252. {
  1253.   GobanWidget gnew      = (GobanWidget) new;
  1254.   GobanWidget gcurrent  = (GobanWidget) current;
  1255.   Boolean     redisplay = FALSE;
  1256.  
  1257.   if (gnew->goban.point_size != gcurrent->goban.point_size)
  1258.     gnew->goban.point_size = gcurrent->goban.point_size;
  1259.  
  1260.   if (XtIsRealized (new)) {
  1261.     if (gnew->goban.cursor != gcurrent->goban.cursor) {
  1262.  
  1263.       switch (gnew->goban.cursor) {
  1264.  
  1265.       case GbCGrayStone  : 
  1266.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.gray_cursor);
  1267.     break;
  1268.       case GbCBlackStone : 
  1269.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.black_cursor);
  1270.     break;
  1271.       case GbCWhiteStone : 
  1272.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.white_cursor);
  1273.     break;
  1274.       default :
  1275.     XFreeCursor (XtDisplay (new), gnew->goban.font_cursor );
  1276.     gnew->goban.font_cursor = XCreateFontCursor (XtDisplay (new), (unsigned int) gnew->goban.cursor);
  1277.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.font_cursor);
  1278.       }
  1279.     }
  1280.   }
  1281.  
  1282.   if (gnew->goban.game_size != gcurrent->goban.game_size) 
  1283.     if (gnew->goban.game_size > 1 && gnew->goban.game_size < 20) {
  1284.  
  1285.       gnew->goban.bottom = 1;
  1286.       gnew->goban.left   = 1;
  1287.       gnew->goban.top    = gnew->goban.game_size;
  1288.       gnew->goban.right  = gnew->goban.game_size;
  1289.       
  1290.       InitializeSize   (new);
  1291.       DrawBoard        (new);
  1292.       DrawCoordinates  (new);
  1293.       GbClearBoard     (new);
  1294.       
  1295.       redisplay = TRUE;
  1296.     }
  1297.     else
  1298.       gnew->goban.game_size = gcurrent->goban.game_size;
  1299.  
  1300.   else if (gnew->goban.top    != gcurrent->goban.top   ||
  1301.        gnew->goban.left   != gcurrent->goban.left  ||
  1302.        gnew->goban.right  != gcurrent->goban.right ||
  1303.        gnew->goban.bottom != gcurrent->goban.bottom) {
  1304.  
  1305.     InitializeSize  (new);
  1306.     DrawBoard       (new);
  1307.     DrawCoordinates (new);
  1308.     RedrawStones    (new);
  1309.  
  1310.     redisplay = TRUE;
  1311.   }
  1312.  
  1313.   else if (new->core.background_pixel != current->core.background_pixel || 
  1314.            gnew->goban.foreground     != gcurrent->goban.foreground     ||
  1315.            gnew->goban.white_fg       != gcurrent->goban.white_fg       ||
  1316.            gnew->goban.white_bg       != gcurrent->goban.white_bg       ||
  1317.            gnew->goban.white_bd       != gcurrent->goban.white_bd       ||
  1318.            gnew->goban.black_fg       != gcurrent->goban.black_fg       ||
  1319.            gnew->goban.black_bg       != gcurrent->goban.black_bg       ||
  1320.            gnew->goban.black_bd       != gcurrent->goban.black_bd       ) {
  1321.  
  1322.     DestroyGC        (new);
  1323.     InitializeGC     (new);
  1324.     DrawBoard        (new);
  1325.     DrawCoordinates  (new);
  1326.     RedrawStones     (new);
  1327.  
  1328.     redisplay = TRUE;
  1329.   }
  1330.  
  1331.   if (gnew->goban.display_coordinates != gcurrent->goban.display_coordinates) {
  1332.     DrawCoordinates (new);
  1333.  
  1334.     redisplay = TRUE;
  1335.   }
  1336.  
  1337.   return (gnew->goban.auto_redisplay == True) ? redisplay : False;
  1338. }
  1339.  
  1340. /****************************************************************************************************************
  1341.  */
  1342. SHAR_EOF
  1343. fi
  1344. if test -f 'Goban.doc'
  1345. then
  1346.     echo shar: "will not over-write existing file 'Goban.doc'"
  1347. else
  1348. cat << \SHAR_EOF > 'Goban.doc'
  1349. Goban Widget 
  1350. ------------
  1351.  
  1352.  The Goban widget displays a full or partial go board within a rectangular area and 
  1353.  allows an application to put or remove stones on it. The application can also draw 
  1354.  numbers on stones, and marks (consisting of a one or two characters string) on stones 
  1355.  or empty points. It has no knowledge of the game and thus doesn't remove dead stones 
  1356.  if any (it is the application's responsability).
  1357.  
  1358.  For every position specification, the coordinate system uses an x axis going from left
  1359.  to right, and an y axis going from bottom to top.
  1360.  
  1361. Resources
  1362. ---------
  1363.  
  1364.  Name             Class        RepType        Default Value
  1365.  ----             -----        -------        -------------
  1366.  autoRedisplay       AutoRedisplay      Boolean         True
  1367.  background         Background        Pixel        XtDefaultBackground
  1368.  border             BorderColor    Pixel        XtDefaultForeground
  1369.  borderWidth         BorderWidth    Dimension    1
  1370.  cursor              Cursor             Integer         GbGrayCursor
  1371.  destroyCallback     Callback        Pointer        NULL
  1372.  font                Font               XFontStruct*    fixed
  1373.  foreground          Foreground         Pixel           XtDefaultForeground
  1374.  gameSize            Size               Dimension       19
  1375.  height             Height        Dimension    computed at create
  1376.  mappedWhenManaged   MappedWhenManaged    Boolean        True
  1377.  displayCoordinates  DisplayCoordinates    Boolean        True
  1378.  pointSize           Size               Dimension       24
  1379.  sensitive         Sensitive        Boolean        True
  1380.  viewBottom          Position           Position        1
  1381.  viewLeft            Position           Position        1
  1382.  viewRight           Position           Position        <gameSize>
  1383.  viewTop             Position           Position        <gameSize>
  1384.  width             Width        Dimension    computed at create
  1385.  x             Position        Position    0
  1386.  y             Position        Position    0
  1387.  
  1388.  
  1389.  autoRedisplay          If this resource is True, then all changes on the widget (put or remove
  1390.               stones, put numbers or marks) will be immediatly flushed to the screen.
  1391.               This can be set to False in conjonction with GbRedisplay in order to 
  1392.               improve the speed when displaying a position.
  1393.  
  1394.  background          As usual.
  1395.  border              As usual.
  1396.  borderWidth          As usual.
  1397.  
  1398.  
  1399.  cursor              The cursor that will be displayed : should be GbCGrayStone, GbCWhiteStone
  1400.               or GbCBlackStone or a valid cursorFont ID.
  1401.  
  1402.  destroyCallback      As usual.
  1403.  
  1404.  font              The font that will be used to put numbers and marks on the board and to
  1405.               display the coordinate marks.
  1406.  
  1407.  foreground          As usual.
  1408.  
  1409.  gameSize          The board size : board is always square and its size must range between
  1410.               2 and 19.
  1411.  
  1412.  height              As usual.
  1413.  
  1414.  mappedWhenManaged    As usual.
  1415.  
  1416.  displayCoordinates   If this resource is True, then the coordinate marks will be displayed 
  1417.               around the board.
  1418.  
  1419.  pointSize          The distance in pixels between points.
  1420.      
  1421.  sensitive          As usual.
  1422.  
  1423.  viewBottom           The bottom of the partial goban that is viewed. Must range between 1 and
  1424.               gameSize - 1.
  1425.  
  1426.  viewLeft          The left of the partial goban that is viewed. Must range between 1 and
  1427.               gameSize - 1.
  1428.  
  1429.  viewRight          The right of the partial goban that is viewed. Must range between 
  1430.               viewLeft + 1 and gameSize.
  1431.  
  1432.  viewTop          The top of the partial goban that is viewed. Must range between
  1433.               viewBottom + 1 and gameSize.
  1434.  
  1435.  width              As usual.
  1436.  x              As usual.
  1437.  y              As usual.
  1438.  
  1439.  
  1440. Procedures provided for application
  1441. -----------------------------------  
  1442.  
  1443. void GbRedisplayBoard (w)
  1444. GobanWidget w;
  1445.  
  1446.  Redisplay the entire board <w> on the screen.
  1447.  
  1448. void GbClearBoard (w)
  1449. GobanWidget w;
  1450.  
  1451.  Remove all stones of the board <w> and call GbRedisplayBoard.
  1452.  
  1453.  
  1454. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone, } GbPointState;
  1455.  
  1456. void GbSetPoint (w, x, y, color)     
  1457. GobanWidget  w;
  1458. Position     x;
  1459. Position     y; 
  1460. GbPointState color;
  1461.  
  1462.  Put a stone of color <color> at location <x><y> on the board <w>.
  1463.  If color is GbEmptyPoint, then the stone (if any) is removed from location <x><y>.
  1464.  All marks on this point are removed.
  1465.  If autoRedisplay if set to False the change will not be visible on the screen until
  1466.  the application calls GbRedisplay.
  1467.  
  1468.  
  1469. void GbSetNum (w, x, y, num)
  1470. GobanWidget  w;
  1471. Position     x;
  1472. Position     y;
  1473. unsigned int num;
  1474.  
  1475.  Draw the number <num> on the stone at location <x><y> on the board <w>.
  1476.  <num> must range between 0 and 999 and no number is displayed if there is no stone
  1477.  at this location.
  1478.  If <num> is equal to 0, all previous num (if any) is removed from stone.
  1479.  When the representation of <num> is to bigger than the stone size (according to font size) 
  1480.  no number is displayed.
  1481.  
  1482.  
  1483. void GbSetMark (w, x, y, mark1, mark2)
  1484. GobanWidget   w;
  1485. Position      x;
  1486. Position      y;
  1487. unsigned char mark1;
  1488. unsigned char mark2;
  1489.  
  1490.  Draw the two characters mark at location <x><y> on the board <w>.
  1491.  <x><y> may be an empty point.
  1492.  If <mark1> and <mark2> are equal to 0, the previous mark (if any) is removed from point.
  1493.  If <mark2> is equal to 0, only one character will be displayed.
  1494.  If <mark1> is equal to 0, <mark2> can be one of GbMSquareMark, GbMTriangleMark, GbMVCrossMark, 
  1495.  GbMDCrossMark or GbMDiamondMark. In this case, geometric marks are drawn.
  1496.  When the representation of the mark is to bigger than the stone size (according to font size) 
  1497.  no mark is displayed.
  1498.  GbRemoveMark(w,x,y) is defined as a macro call for GbSetMark(w,x,y,0,0).
  1499.  
  1500.  
  1501. Boolean GbGetStoneFromPosition (w, x, y)
  1502. GobanWidget   w;
  1503. Position     *x;
  1504. Position     *y;
  1505.  
  1506.  Provide a way to know on what point occurs a mouse event.
  1507.  If the event occurs on a valid point on the board, GbGetStoneFromEvent returns TRUE,
  1508.  and <x> <y> variables are set to the coordinates of that point.
  1509.  If not, GbGetStoneFromEvent returns FALSE and <event> is unchanged.
  1510.  
  1511.  
  1512. Boolean GbGetPositionFromStone (w, x, y)
  1513. GobanWidget   w;
  1514. Position     *x;
  1515. Position     *y;
  1516.  
  1517.  Provide a way to know what are the coordinates (in pixel) for the center of a given 
  1518.  point. It works as GbGetStoneFromPosition.
  1519.  Those functions are not reverse of each other ...
  1520.  
  1521. SHAR_EOF
  1522. fi
  1523. if test -f 'Goban.h'
  1524. then
  1525.     echo shar: "will not over-write existing file 'Goban.h'"
  1526. else
  1527. cat << \SHAR_EOF > 'Goban.h'
  1528. /****************************************************************************************************************
  1529.  *
  1530.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1531.  *
  1532.  *  This program is distributed in the hope that it will be useful.
  1533.  *  Use and copying of this software and preparation of derivative works
  1534.  *  based upon this software are permitted, so long as the following
  1535.  *  conditions are met:
  1536.  *       o credit to the authors is acknowledged following current
  1537.  *         academic behaviour
  1538.  *       o no fees or compensation are charged for use, copies, or
  1539.  *         access to this software
  1540.  *       o this copyright notice is included intact.
  1541.  *  This software is made available AS IS, and no warranty is made about 
  1542.  *  the software or its performance. 
  1543.  * 
  1544.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1545.  *  Send them to    dumesnil@etca.fr   or to:
  1546.  *       
  1547.  *       Antoine de Maricourt
  1548.  *       ETCA CREA-SP
  1549.  *       16 bis, avenue Prieur de la Cote d'Or
  1550.  *       94114 Arcueil Cedex
  1551.  *       France
  1552.  */
  1553.  
  1554. #ifndef _Goban_h
  1555. #define _Goban_h
  1556.  
  1557. /* Resources:
  1558.  
  1559.  Name               Class          RepType        Default Value
  1560.  ----               -----          -------        -------------
  1561.  autoRedisplay         AutoRedisplay      Boolean         True
  1562.  background           Background      Pixel          XtDefaultBackground
  1563.  blackStoneBackground  Background      Pixel          black
  1564.  blackStoneBorder      BorderColor      Pixel          black
  1565.  blackStoneForeground  Foreground      Pixel          white
  1566.  border               BorderColor      Pixel          XtDefaultForeground
  1567.  borderWidth           BorderWidth      Dimension      1
  1568.  cursor                Cursor             Integer         GbGrayCursor
  1569.  destroyCallback       Callback          Pointer      NULL
  1570.  displayCoordinates    DisplayCoordinates Boolean      True
  1571.  font                  Font               XFontStruct*    fixed
  1572.  foreground            Foreground         Pixel           XtDefaultForeground
  1573.  gameSize              Size               Dimension       19
  1574.  height               Height          Dimension      computed at create
  1575.  mappedWhenManaged     MappedWhenManaged  Boolean      True
  1576.  pointSize             Size               Dimension       24
  1577.  sensitive           Sensitive      Boolean      True
  1578.  viewBottom            Position           Position        computed at create
  1579.  viewLeft              Position           Position        computed at create
  1580.  viewRight             Position           Position        computed at create
  1581.  viewTop               Position           Position        computed at create
  1582.  whiteStoneBackground  Background      Pixel          white
  1583.  whiteStoneBorder      BorderColor      Pixel          black
  1584.  whiteStoneForeground  Foreground      Pixel          black
  1585.  width               Width          Dimension      computed at create
  1586.  x               Position          Position      0
  1587.  y               Position          Position      0
  1588. */
  1589.  
  1590. /* define any special resource names here that are not in <X11/StringDefs.h> */
  1591.  
  1592. #define XtNautoRedisplay         "autoRedisplay"
  1593. #define XtNviewBottom            "viewBottom"
  1594.  
  1595. #ifndef XtNcursor
  1596. #define XtNcursor                "cursor"
  1597. #endif
  1598.  
  1599. #define XtNgameSize              "gameSize"
  1600. #define XtNviewLeft              "viewLeft"
  1601. #define XtNdisplayCoordinates    "displayCoordinates"
  1602. #define XtNpointSize             "pointSize"
  1603. #define XtNviewRight             "viewRight"
  1604. #define XtNviewTop               "viewTop"
  1605. #define XtNblackStoneBorder      "blackStoneBorder"
  1606. #define XtNblackStoneForeground  "blackStoneForeground"
  1607. #define XtNblackStoneBackground  "blackStoneBackground"
  1608. #define XtNwhiteStoneBorder      "whiteStoneBorder"
  1609. #define XtNwhiteStoneForeground  "whiteStoneForeground"
  1610. #define XtNwhiteStoneBackground  "whiteStoneBackground"
  1611.  
  1612. #define XtCAutoRedisplay         "AutoRedisplay"
  1613. #define XtCDisplayCoordinates    "DisplayCoordinates"
  1614. #define XtCSize                  "Size"
  1615.  
  1616. #define XtEgbWhiteStone          "white"
  1617. #define XtEgbBlackStone          "black"
  1618. #define XtEgbGrayStone           "gray"
  1619.  
  1620. /* declare specific GobanWidget class and instance datatypes */
  1621.  
  1622. typedef struct _GobanClassRec*     GobanWidgetClass;
  1623. typedef struct _GobanRec*     GobanWidget;
  1624.  
  1625. /* declare the class constant */
  1626.  
  1627. extern WidgetClass gobanWidgetClass;
  1628.  
  1629. /* cursors */
  1630.  
  1631. #define GbCGrayStone         256
  1632. #define GbCBlackStone        257
  1633. #define GbCWhiteStone        258
  1634.  
  1635. /* special marks */
  1636.  
  1637. #define GbMSquareMark        1
  1638. #define GbMTriangleMark      2
  1639. #define GbMVCrossMark        3
  1640. #define GbMDCrossMark        4
  1641. #define GbMDiamondMark       5
  1642.  
  1643. /* colors */
  1644.  
  1645. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone } GbPointState;
  1646.  
  1647. /* user functions */
  1648.  
  1649. #define GbRemoveMark(w,x,y)  GbSetMark (w, x, y, 0, 0)
  1650.  
  1651. extern void GbRedisplayBoard ( /* Widget w */ );
  1652. extern void GbClearBoard     ( /* Widget w */ );
  1653. extern void GbSetPoint       ( /* Widget w, Position x, Position y, GbPointState color */ );
  1654. extern void GbSetNum         ( /* Widget w, Position x, Position y, int num   */ );
  1655. extern void GbSetMark        ( /* Widget w, Position x, Position y, unsigned char mark1, unsigned char mark2 */ );
  1656.  
  1657. extern Boolean GbGetPositionFromStone ( /* Widget w, Position *x, Position *y */ );
  1658. extern Boolean GbGetStoneFromPosition ( /* Widget w, Position *x, Position *y */ );
  1659.  
  1660. #endif /* _Goban_h */
  1661.  
  1662. SHAR_EOF
  1663. fi
  1664. if test -f 'GobanP.h'
  1665. then
  1666.     echo shar: "will not over-write existing file 'GobanP.h'"
  1667. else
  1668. cat << \SHAR_EOF > 'GobanP.h'
  1669. /****************************************************************************************************************
  1670.  *
  1671.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1672.  *
  1673.  *  This program is distributed in the hope that it will be useful.
  1674.  *  Use and copying of this software and preparation of derivative works
  1675.  *  based upon this software are permitted, so long as the following
  1676.  *  conditions are met:
  1677.  *       o credit to the authors is acknowledged following current
  1678.  *         academic behaviour
  1679.  *       o no fees or compensation are charged for use, copies, or
  1680.  *         access to this software
  1681.  *       o this copyright notice is included intact.
  1682.  *  This software is made available AS IS, and no warranty is made about 
  1683.  *  the software or its performance. 
  1684.  * 
  1685.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1686.  *  Send them to    dumesnil@etca.fr   or to:
  1687.  *       
  1688.  *       Antoine de Maricourt
  1689.  *       ETCA CREA-SP
  1690.  *       16 bis, avenue Prieur de la Cote d'Or
  1691.  *       94114 Arcueil Cedex
  1692.  *       France
  1693.  */
  1694.  
  1695. #ifndef _GobanP_h
  1696. #define _GobanP_h
  1697.  
  1698. #include "Goban.h"
  1699.  
  1700. /* include superclass private header file */
  1701. #include <X11/CoreP.h>
  1702.  
  1703. /* define unique representation types not found in <X11/StringDefs.h> */
  1704.  
  1705. #define XtRGobanResource "GobanResource"
  1706.  
  1707. typedef struct {
  1708.     int empty;
  1709. } GobanClassPart;
  1710.  
  1711. typedef struct _GobanClassRec {
  1712.     CoreClassPart    core_class;
  1713.     GobanClassPart    goban_class;
  1714. } GobanClassRec;
  1715.  
  1716. extern GobanClassRec gobanClassRec;
  1717.  
  1718. typedef struct {
  1719.   unsigned int free  : 1;
  1720.   unsigned int black : 1;
  1721.   unsigned int mark1 : 8;
  1722.   unsigned int mark2 : 8;
  1723.   unsigned int num   : 10;
  1724. } PointState;
  1725.  
  1726. typedef struct {
  1727.     /* resources */
  1728.  
  1729.   Boolean       auto_redisplay;
  1730.   Position      bottom;
  1731.   int           cursor;
  1732.   XFontStruct  *font;
  1733.   Pixel         foreground;
  1734.   Dimension     game_size;
  1735.   Position      left;
  1736.   Boolean       display_coordinates;
  1737.   Dimension     point_size;
  1738.   Position      right;
  1739.   Position      top;
  1740.  
  1741.     /* private state */
  1742.  
  1743.   PointState    points[20][20];
  1744.   Position      x_offset;
  1745.   Position      y_offset;
  1746.  
  1747.   Pixmap        black_stone;
  1748.   Pixmap        board;
  1749.   Pixmap        gray_stone;
  1750.   Pixmap        mouse_mask;
  1751.   Pixmap        picture;
  1752.   Pixmap        white_stone;
  1753.  
  1754.   GC            background_gc;
  1755.   GC            foreground_gc;
  1756.   GC            black_fg_gc;
  1757.   GC            black_bg_gc;
  1758.   GC            black_bd_gc;
  1759.   GC            white_fg_gc;
  1760.   GC            white_bg_gc;
  1761.   GC            white_bd_gc;
  1762.   GC            copy_gc;
  1763.  
  1764.   Cursor        black_cursor;
  1765.   Cursor        gray_cursor;
  1766.   Cursor        white_cursor;
  1767.   Cursor        font_cursor;
  1768.  
  1769.   Pixel         white_bg;
  1770.   Pixel         white_fg;
  1771.   Pixel         white_bd;
  1772.   Pixel         black_bg;
  1773.   Pixel         black_fg;
  1774.   Pixel         black_bd;
  1775. } GobanPart;
  1776.  
  1777. typedef struct _GobanRec {
  1778.     CorePart    core;
  1779.     GobanPart    goban;
  1780. } GobanRec;
  1781.  
  1782. #define Min(x,y)      ((x) > (y) ? (y) : (x))
  1783. #define Max(x,y)      ((x) > (y) ? (x) : (y))
  1784.  
  1785. #endif /* _GobanP_h */
  1786. SHAR_EOF
  1787. fi
  1788. if test -f 'Imakefile'
  1789. then
  1790.     echo shar: "will not over-write existing file 'Imakefile'"
  1791. else
  1792. cat << \SHAR_EOF > 'Imakefile'
  1793.   LOCAL_LIBRARIES = XawClientLibs
  1794.  
  1795.             SRCS1 = Goban.c gw.c
  1796.             OBJS1 = Goban.o gw.o
  1797.  
  1798.          PROGRAMS = gw
  1799.  
  1800. ComplexProgramTarget_1 (gw, $(LOCAL_LIBRARIES), NullParameter)
  1801. SHAR_EOF
  1802. fi
  1803. if test -f 'README'
  1804. then
  1805.     echo shar: "will not over-write existing file 'README'"
  1806. else
  1807. cat << \SHAR_EOF > 'README'
  1808. Here are source files for a goban widget which could be useful for
  1809. go softwares on X ...
  1810.  
  1811. `gw' is a simple program I used to test the widget.
  1812.  
  1813. You should find the following files :
  1814.  
  1815.   +  Goban.c
  1816.   +  Goban.doc
  1817.   +  Goban.h
  1818.   +  GobanP.h
  1819.   +  Imakefile
  1820.   +  README
  1821.   +  blackstone.bm
  1822.   +  graystone.bm
  1823.   +  gw.ad
  1824.   +  gw.c
  1825.   +  stonemask.bm
  1826.   +  whitestone.bm
  1827.  
  1828. Just do :
  1829.  
  1830. >  xmkmf -a
  1831.  
  1832. If your system doesn't like -a option, you probably have an older version
  1833. of X than X11R5. You can do :
  1834.    
  1835.    > xmkmf
  1836.         (or > imake -DUseInstalled -I/usr/lib/X11/config  )
  1837.  
  1838.    > make depend
  1839.  
  1840. instead.
  1841.  
  1842. >  make
  1843.  
  1844. You can ignore the message "warning ./Goban.h:66: XtNcursor redefined" if it
  1845. occurs, and also messages about argument that doesn't match prototype. (since
  1846. my compiler doesn't check prototypes, I may have forgotten some casts)
  1847.  
  1848. >  xrdb gw.ad
  1849. >  gw 
  1850.  
  1851. Don't be afraid if marks or nums don't appear when you test them, if the font
  1852. size make them bigger than a stone, they are not drawn. You can change the
  1853. font in gw.ad : the current one is not very good.
  1854.  
  1855. Bug descriptions, use reports, comments or suggestions are welcome.
  1856. Send them to :  
  1857.             dumesnil@etca.fr
  1858. SHAR_EOF
  1859. fi
  1860. if test -f 'blackstone.bm'
  1861. then
  1862.     echo shar: "will not over-write existing file 'blackstone.bm'"
  1863. else
  1864. cat << \SHAR_EOF > 'blackstone.bm'
  1865. #define blackstone_width 16
  1866. #define blackstone_height 16
  1867. #define blackstone_x_hot 7
  1868. #define blackstone_y_hot 8
  1869. static char blackstone_bits[] = {
  1870.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  1871.    0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0xfe, 0x77, 0xfe, 0x7b,
  1872.    0xfc, 0x3c, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  1873. SHAR_EOF
  1874. fi
  1875. if test -f 'graystone.bm'
  1876. then
  1877.     echo shar: "will not over-write existing file 'graystone.bm'"
  1878. else
  1879. cat << \SHAR_EOF > 'graystone.bm'
  1880. #define graystone_width 16
  1881. #define graystone_height 16
  1882. #define graystone_x_hot 7
  1883. #define graystone_y_hot 8
  1884. static char graystone_bits[] = {
  1885.    0xc0, 0x03, 0xb0, 0x0e, 0x58, 0x15, 0xac, 0x2a, 0x56, 0x55, 0xaa, 0x6a,
  1886.    0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xba, 0x56, 0x5d, 0xaa, 0x6e,
  1887.    0x54, 0x37, 0xa8, 0x1a, 0x70, 0x0d, 0xc0, 0x03};
  1888. SHAR_EOF
  1889. fi
  1890. if test -f 'gw.ad'
  1891. then
  1892.     echo shar: "will not over-write existing file 'gw.ad'"
  1893. else
  1894. cat << \SHAR_EOF > 'gw.ad'
  1895. XGW*goban*autoRedisplay      : true
  1896. XGW*goban*background         : tan1
  1897. XGW*goban*borderWidth        : 2
  1898. XGW*goban*displayCoordinates : false
  1899. XGW*goban*cursor             : black
  1900. XGW*goban*font               : -adobe-new century schoolbook-medium-r-*-*-14-*-*-*-*-*-*-*
  1901. XGW*goban*gameSize           : 13
  1902. XGW*goban*pointSize          : 24
  1903. XGW*goban*viewBottom         : 3
  1904. XGW*goban*viewLeft           : 5
  1905. XGW*goban*viewRight          : 9
  1906. XGW*goban*viewTop            : 12
  1907.  
  1908.  
  1909. XGW*Goban.translations   : #augment \
  1910.                <BtnDown> : inputStone()
  1911.  
  1912. XGW*Command*width        : 150
  1913.  
  1914. XGW*test.label           : Goban
  1915. XGW*sensitive.label      : Sensitive
  1916. XGW*cursor.label         : Cursor
  1917. XGW*size.label           : Change size
  1918. XGW*coordinates.label    : Display coordinates
  1919. XGW*view.label           : Partial view
  1920. XGW*stones.label         : Put stones
  1921. XGW*redisplay.label      : GbRedisplay
  1922. XGW*auto.label           : autoRedipslay
  1923. XGW*nums.label           : Draw nums
  1924. XGW*marks.label          : Draw marks
  1925. XGW*smarks.label         : Draw special marks
  1926. XGW*quit.label           : Quit
  1927.  
  1928. XGW*sensitive.fromVert   : test
  1929. XGW*cursor.fromVert      : sensitive
  1930. XGW*size.fromVert        : cursor
  1931. XGW*coordinates.fromVert : size
  1932. XGW*view.fromVert        : coordinates
  1933. XGW*stones.fromVert      : view
  1934. XGW*redisplay.fromVert   : stones
  1935. XGW*auto.fromVert        : redisplay
  1936. XGW*nums.fromVert        : auto
  1937. XGW*marks.fromVert       : nums
  1938. XGW*smarks.fromVert      : marks
  1939. XGW*quit.fromVert        : smarks
  1940. SHAR_EOF
  1941. fi
  1942. if test -f 'gw.c'
  1943. then
  1944.     echo shar: "will not over-write existing file 'gw.c'"
  1945. else
  1946. cat << \SHAR_EOF > 'gw.c'
  1947. #include <stdio.h>
  1948.  
  1949. #include <X11/Intrinsic.h>
  1950. #include <X11/Shell.h>
  1951. #include <X11/StringDefs.h>
  1952. #include <X11/Xlib.h>
  1953. #include <X11/Xutil.h>
  1954. #include <X11/cursorfont.h>
  1955.  
  1956. #include <X11/Xaw/Command.h>
  1957. #include <X11/Xaw/Form.h>
  1958. #include <X11/Xaw/Box.h>
  1959.  
  1960. #include "Goban.h"
  1961.  
  1962. Widget        toplevel;
  1963. Widget        board;
  1964. Widget        goban;
  1965. Widget        form;
  1966. Widget        test;
  1967. Widget        sensitive;
  1968. Widget        cursor;
  1969. Widget        size;
  1970. Widget        coordinates;
  1971. Widget        view;
  1972. Widget        stones;
  1973. Widget        redisplay;
  1974. Widget        autor;
  1975. Widget        nums;
  1976. Widget        marks;
  1977. Widget        smarks;
  1978. Widget        quit;
  1979.  
  1980. static void InputStone (w, event)
  1981. GobanWidget w;
  1982. XButtonEvent *event;
  1983. {
  1984.   Position x = event->x;
  1985.   Position y = event->y;
  1986.  
  1987.   if (GbGetStoneFromPosition (w, &x, &y) == TRUE) {
  1988.  
  1989.     printf ("Input stone at %c%d\n", 'A' + (x > 8 ? x + 1 : x) - 1, y);
  1990.   }
  1991. }
  1992.  
  1993. static void SetSensitive ()
  1994. {
  1995.   Arg args[1];
  1996.   Boolean sensitive;
  1997.  
  1998.   XtSetArg   (args[0], XtNsensitive, &sensitive);
  1999.   XtGetValues (goban, args, 1);
  2000.   
  2001.   switch (sensitive) {
  2002.   case FALSE : 
  2003.     XtSetArg   (args[0], XtNsensitive, TRUE) ; 
  2004.     printf ("Set sensitive to : TRUE \n");
  2005.     break;
  2006.   case TRUE  : 
  2007.     XtSetArg   (args[0], XtNsensitive, FALSE); 
  2008.     printf ("Set sensitive to : FALSE\n"); 
  2009.     break;
  2010.   }
  2011.  
  2012.   XtSetValues (goban, args, 1);
  2013. }
  2014.  
  2015. static void SetCursor ()
  2016. {
  2017.   Arg args[1];
  2018.   int cursor;
  2019.  
  2020.   XtSetArg   (args[0], XtNcursor, &cursor);
  2021.   XtGetValues (goban, args, 1);
  2022.   
  2023.   switch (cursor) {
  2024.   case GbCGrayStone    : 
  2025.     XtSetArg   (args[0], XtNcursor, GbCBlackStone);
  2026.     printf ("Set cursor to : Black \n"); 
  2027.     break;
  2028.   case GbCBlackStone : 
  2029.     XtSetArg   (args[0], XtNcursor, GbCWhiteStone);
  2030.     printf ("Set cursor to : White \n"); 
  2031.     break;
  2032.   case GbCWhiteStone : 
  2033.     XtSetArg   (args[0], XtNcursor, XC_question_arrow);  
  2034.     printf ("Set cursor to : Question arrow\n"); 
  2035.     break;
  2036.   case XC_question_arrow :
  2037.     XtSetArg   (args[0], XtNcursor, GbCGrayStone);  
  2038.     printf ("Set cursor to : Gray\n"); 
  2039.     break;
  2040.   }
  2041.  
  2042.   XtSetValues (goban, args, 1);
  2043. }
  2044.  
  2045. static void Autor ()
  2046. {
  2047.   Arg     args[1];
  2048.   Boolean autor;
  2049.  
  2050.   XtSetArg    (args[0], XtNautoRedisplay, &autor);
  2051.   XtGetValues (goban, args, 1);
  2052.   
  2053.   switch (autor) {
  2054.   case FALSE : 
  2055.     XtSetArg   (args[0], XtNautoRedisplay, TRUE) ;
  2056.     printf ("Set autoRedisplay to : TRUE \n");
  2057.     break;
  2058.   case TRUE  : 
  2059.     XtSetArg   (args[0], XtNautoRedisplay, FALSE); 
  2060.     printf ("Set autoRedisplay to : FALSE \n");
  2061.     break;
  2062.   }
  2063.  
  2064.   XtSetValues (goban, args, 1);
  2065. }
  2066.  
  2067. static void SetSize ()
  2068. {
  2069.   Arg       args[1];
  2070.   Dimension size;
  2071.  
  2072.   size = ((lrand48 () >> 8) % 18) + 2;
  2073.  
  2074.   printf ("Set size to : %d\n", size);
  2075.  
  2076.   XtSetArg    (args[0], XtNgameSize, size);
  2077.   XtSetValues (goban, args, 1);
  2078. }
  2079.  
  2080. static void SetCoordinates ()
  2081. {
  2082.   Arg     args[1];
  2083.   Boolean coordinates;
  2084.  
  2085.   XtSetArg    (args[0], XtNdisplayCoordinates, &coordinates);
  2086.   XtGetValues (goban, args, 1);
  2087.   
  2088.   switch (coordinates) {
  2089.   case FALSE : 
  2090.     XtSetArg (args[0], XtNdisplayCoordinates, TRUE) ; 
  2091.     printf   ("Set coordinates to : TRUE \n");
  2092.     break;
  2093.   case TRUE  : 
  2094.     XtSetArg (args[0], XtNdisplayCoordinates, FALSE); 
  2095.     printf   ("Set coordinates to : FALSE \n");
  2096.     break;
  2097.   }
  2098.  
  2099.   XtSetValues (goban, args, 1);
  2100. }
  2101.  
  2102. static void SetView ()
  2103. {
  2104.   Arg       args[4];
  2105.   Dimension size;
  2106.   Position  top, left, bottom, right;
  2107.  
  2108.   XtSetArg    (args[0], XtNgameSize, &size);
  2109.   XtGetValues (goban, args, 1);
  2110.  
  2111.   bottom = ((lrand48 () >> 8) % (size + 2));
  2112.   left   = ((lrand48 () >> 8) % (size + 2));
  2113.   top    = ((lrand48 () >> 8) % (size + 2));
  2114.   right  = ((lrand48 () >> 8) % (size + 2));
  2115.  
  2116.   XtSetArg   (args[0], XtNviewTop   , top   );
  2117.   XtSetArg   (args[1], XtNviewLeft  , left  );
  2118.   XtSetArg   (args[2], XtNviewBottom, bottom);
  2119.   XtSetArg   (args[3], XtNviewRight , right );
  2120.  
  2121.   printf ("Set view to : %c%d", 'A' - 1 + ((left > 8) ? left + 1 : left), top);
  2122.   printf (" %c%d\n", 'A' - 1 + ((right > 8) ? right + 1 : right), bottom);
  2123.  
  2124.   XtSetValues (goban, args, 4);
  2125. }
  2126.  
  2127. static void SetNums ()
  2128. {
  2129.   int          i;
  2130.   Position     x, y;
  2131.   Arg          args[4];
  2132.   unsigned int num;
  2133.   Position     top, left, bottom, right;
  2134.  
  2135.   XtSetArg    (args[0], XtNviewTop   , &top   );
  2136.   XtSetArg    (args[1], XtNviewLeft  , &left  );
  2137.   XtSetArg    (args[2], XtNviewBottom, &bottom);
  2138.   XtSetArg    (args[3], XtNviewRight , &right );
  2139.   XtGetValues (goban, args, 4);
  2140.  
  2141.   printf ("Remove num from :");
  2142.   for (i = 0; i < 10; i++) {
  2143.     x = left   + ((lrand48 () >> 8) % (right - left   + 3)) - 1;
  2144.     y = bottom + ((lrand48 () >> 8) % (top   - bottom + 3)) - 1;
  2145.     GbSetNum (goban, x, y, 0);
  2146.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2147.   }
  2148.  
  2149.   printf ("\nPut Num on :");
  2150.   for (i = 0; i < 10; i++) {
  2151.     x   = left   + ((lrand48 () >> 8) % (right - left   + 3)) - 1;
  2152.     y   = bottom + ((lrand48 () >> 8) % (top   - bottom + 3)) - 1;
  2153.     num = ((lrand48 () >> 8) % 300) + 1;
  2154.     GbSetNum (goban, x, y, num);
  2155.     printf (" %c%d (%d)", 'A' - 1 + ((x > 8) ? x + 1 : x), y, num);
  2156.   }
  2157.   printf ("\n");
  2158. }
  2159.  
  2160. static void SetSMarks ()
  2161. {
  2162.   int       i;
  2163.   Position  x, y;
  2164.   Arg       args[4];
  2165.   Dimension size;
  2166.   char      c1, c2;
  2167.   Position  top, left, bottom, right;
  2168.  
  2169.   XtSetArg    (args[0], XtNviewTop   , &top   );
  2170.   XtSetArg    (args[1], XtNviewLeft  , &left  );
  2171.   XtSetArg    (args[2], XtNviewBottom, &bottom);
  2172.   XtSetArg    (args[3], XtNviewRight , &right );
  2173.   XtGetValues (goban, args, 4);
  2174.  
  2175.   printf ("Remove marks from :");
  2176.   for (i = 0; i < 10; i++) {
  2177.     x = left   + ((lrand48 () >> 8) % (right - left   + 1));
  2178.     y = bottom + ((lrand48 () >> 8) % (top   - bottom + 1));
  2179.     GbRemoveMark (goban, x, y);
  2180.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2181.   }
  2182.  
  2183.   printf ("\nPut mark on :");
  2184.   for (i = 0; i < 10; i++) {
  2185.     x = left   + ((lrand48 () >> 8) % (right - left   + 1));
  2186.     y = bottom + ((lrand48 () >> 8) % (top   - bottom + 1));
  2187.     c1 = 'A' + ((lrand48 () >>8) % 26);
  2188.     c2 = 'A' + ((lrand48 () >>8) % 26);
  2189.     if ((lrand48 () % 2) == 1)
  2190.       c2 = 0;
  2191.     GbSetMark (goban, x, y, 0, (i % 5) + 1);
  2192.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2193.   }
  2194.  
  2195.   printf ("\n");
  2196. }
  2197.  
  2198. static void SetMarks ()
  2199. {
  2200.   int       i;
  2201.   Position  x, y;
  2202.   Arg       args[4];
  2203.   Dimension size;
  2204.   char      c1, c2;
  2205.   Position  top, left, bottom, right;
  2206.  
  2207.   XtSetArg    (args[0], XtNviewTop   , &top   );
  2208.   XtSetArg    (args[1], XtNviewLeft  , &left  );
  2209.   XtSetArg    (args[2], XtNviewBottom, &bottom);
  2210.   XtSetArg    (args[3], XtNviewRight , &right );
  2211.   XtGetValues (goban, args, 4);
  2212.  
  2213.   printf ("Remove marks from :");
  2214.   for (i = 0; i < 10; i++) {
  2215.     x = left   + ((lrand48 () >> 8) % (right - left   + 1));
  2216.     y = bottom + ((lrand48 () >> 8) % (top   - bottom + 1));
  2217.     GbRemoveMark (goban, x, y);
  2218.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2219.   }
  2220.  
  2221.   printf ("\nPut mark on :");
  2222.   for (i = 0; i < 10; i++) {
  2223.     x = left   + ((lrand48 () >> 8) % (right - left   + 1));
  2224.     y = bottom + ((lrand48 () >> 8) % (top   - bottom + 1));
  2225.     c1 = 'A' + ((lrand48 () >>8) % 26);
  2226.     c2 = 'A' + ((lrand48 () >>8) % 26);
  2227.     if ((lrand48 () % 2) == 1)
  2228.       c2 = 0;
  2229.     GbSetMark (goban, x, y, c1, c2);
  2230.     printf (" %c%d [%c%c]", 'A' - 1 + ((x > 8) ? x + 1 : x), y, c1, (c2 == 0) ? ' ' : c2);
  2231.   }
  2232.  
  2233.   printf ("\n");
  2234. }
  2235.  
  2236. static void SetStones ()
  2237. {
  2238.   int       i;
  2239.   Position  x, y;
  2240.   Arg       args[4];
  2241.   Dimension size;
  2242.   Position  top, left, bottom, right;
  2243.  
  2244.   XtSetArg    (args[0], XtNviewTop   , &top   );
  2245.   XtSetArg    (args[1], XtNviewLeft  , &left  );
  2246.   XtSetArg    (args[2], XtNviewBottom, &bottom);
  2247.   XtSetArg    (args[3], XtNviewRight , &right );
  2248.   XtGetValues (goban, args, 4);
  2249.  
  2250.   printf ("Remove stones from :");
  2251.   for (i = 0; i < 10; i++) {
  2252.     x = left   + ((lrand48 () >> 8) % (right - left + 3)) - 1;
  2253.     y = bottom + ((lrand48 () >> 8) % (top - bottom + 3)) - 1;
  2254.     GbSetPoint (goban, x, y, GbEmptyPoint);
  2255.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2256.   }
  2257.  
  2258.   printf ("\nPut Black stone on :");
  2259.   for (i = 0; i < 5; i++) {
  2260.     x = left   + ((lrand48 () >> 8) % (right - left + 3)) - 1;
  2261.     y = bottom + ((lrand48 () >> 8) % (top - bottom + 3)) - 1;
  2262.     GbSetPoint (goban, x, y, GbBlackStone);
  2263.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2264.   }
  2265.  
  2266.   printf ("\nPut White stone on :");
  2267.   for (i = 0; i < 5; i++) {
  2268.     x = left   + ((lrand48 () >> 8) % (right - left + 3)) - 1;
  2269.     y = bottom + ((lrand48 () >> 8) % (top - bottom + 3)) - 1;
  2270.     GbSetPoint (goban, x, y, GbWhiteStone);
  2271.     printf (" %c%d", 'A' - 1 + ((x > 8) ? x + 1 : x), y);
  2272.   }
  2273.   printf ("\n");
  2274. }
  2275.   
  2276. static void SetupBoard ()
  2277. {
  2278.   XtPopup (board, XtGrabNone);
  2279. }
  2280.  
  2281. static void Redisplay ()
  2282. {
  2283.   GbRedisplayBoard (goban);
  2284. }
  2285.  
  2286. XtActionsRec actions[] = {
  2287.   { "inputStone"            ,   InputStone             , },
  2288. };
  2289.  
  2290. main (argc, argv)
  2291. int argc;
  2292. char **argv;
  2293. {
  2294.   extern void exit ();
  2295.  
  2296.   XtAppContext   app_context;
  2297.   int xtargc = 0;
  2298.   Arg args[8];
  2299.  
  2300.   toplevel   = XtAppInitialize (&app_context, "XGW", NULL, 0, &argc, argv, NULL, NULL, 0);
  2301.   
  2302.   board = XtCreatePopupShell    ("board"   , topLevelShellWidgetClass, toplevel, NULL, 0);
  2303.   form  = XtCreateManagedWidget ("board"   , formWidgetClass         , toplevel, NULL, 0);
  2304.   goban = XtCreateManagedWidget ("goban"   , gobanWidgetClass        , board   , NULL, 0);
  2305.  
  2306.   test        = XtCreateManagedWidget ("test"       , commandWidgetClass, form, NULL, 0);
  2307.   sensitive   = XtCreateManagedWidget ("sensitive"  , commandWidgetClass, form, NULL, 0);
  2308.   cursor      = XtCreateManagedWidget ("cursor"     , commandWidgetClass, form, NULL, 0);
  2309.   size        = XtCreateManagedWidget ("size"       , commandWidgetClass, form, NULL, 0);
  2310.   coordinates = XtCreateManagedWidget ("coordinates", commandWidgetClass, form, NULL, 0);
  2311.   view        = XtCreateManagedWidget ("view"       , commandWidgetClass, form, NULL, 0);
  2312.   stones      = XtCreateManagedWidget ("stones"     , commandWidgetClass, form, NULL, 0);
  2313.   redisplay   = XtCreateManagedWidget ("redisplay"  , commandWidgetClass, form, NULL, 0);
  2314.   autor       = XtCreateManagedWidget ("auto"       , commandWidgetClass, form, NULL, 0);
  2315.   nums        = XtCreateManagedWidget ("nums"       , commandWidgetClass, form, NULL, 0);
  2316.   marks       = XtCreateManagedWidget ("marks"      , commandWidgetClass, form, NULL, 0);
  2317.   smarks      = XtCreateManagedWidget ("smarks"     , commandWidgetClass, form, NULL, 0);
  2318.   quit        = XtCreateManagedWidget ("quit"       , commandWidgetClass, form, NULL, 0);
  2319.  
  2320.   XtAppAddActions (app_context, actions, XtNumber(actions));
  2321.  
  2322.   XtAddCallback (test       , XtNcallback, SetupBoard    , NULL);
  2323.   XtAddCallback (sensitive  , XtNcallback, SetSensitive  , NULL);
  2324.   XtAddCallback (cursor     , XtNcallback, SetCursor     , NULL);
  2325.   XtAddCallback (size       , XtNcallback, SetSize       , NULL);
  2326.   XtAddCallback (coordinates, XtNcallback, SetCoordinates, NULL);
  2327.   XtAddCallback (view       , XtNcallback, SetView       , NULL); 
  2328.   XtAddCallback (stones     , XtNcallback, SetStones     , NULL); 
  2329.   XtAddCallback (redisplay  , XtNcallback, Redisplay     , NULL); 
  2330.   XtAddCallback (autor      , XtNcallback, Autor         , NULL); 
  2331.   XtAddCallback (nums       , XtNcallback, SetNums       , NULL); 
  2332.   XtAddCallback (marks      , XtNcallback, SetMarks      , NULL); 
  2333.   XtAddCallback (smarks     , XtNcallback, SetSMarks     , NULL); 
  2334.   XtAddCallback (quit       , XtNcallback, exit          , NULL);
  2335.  
  2336.   XtRealizeWidget (toplevel);
  2337.  
  2338.   XtAppMainLoop (app_context);
  2339. }
  2340. SHAR_EOF
  2341. fi
  2342. if test -f 'stonemask.bm'
  2343. then
  2344.     echo shar: "will not over-write existing file 'stonemask.bm'"
  2345. else
  2346. cat << \SHAR_EOF > 'stonemask.bm'
  2347. #define stonemask_width 16
  2348. #define stonemask_height 16
  2349. #define stonemask_x_hot 7
  2350. #define stonemask_y_hot 8
  2351. static char stonemask_bits[] = {
  2352.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  2353.    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x7f,
  2354.    0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  2355. SHAR_EOF
  2356. fi
  2357. if test -f 'whitestone.bm'
  2358. then
  2359.     echo shar: "will not over-write existing file 'whitestone.bm'"
  2360. else
  2361. cat << \SHAR_EOF > 'whitestone.bm'
  2362. #define whitestone_width 16
  2363. #define whitestone_height 16
  2364. #define whitestone_x_hot 7
  2365. #define whitestone_y_hot 8
  2366. static char whitestone_bits[] = {
  2367.    0xc0, 0x03, 0x30, 0x0c, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40,
  2368.    0x01, 0x80, 0x01, 0x80, 0x01, 0x90, 0x01, 0x90, 0x02, 0x48, 0x02, 0x44,
  2369.    0x04, 0x23, 0x08, 0x10, 0x30, 0x0c, 0xc0, 0x03};
  2370. SHAR_EOF
  2371. fi
  2372. exit 0
  2373. #    End of shell archive
  2374.