home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / x / xhearts.zip / XMCLIENT.C < prev   
C/C++ Source or Header  |  1992-01-07  |  44KB  |  1,487 lines

  1. /*****************************************************************
  2. Copyright 1992 by Silicon Graphics Incorporated, Mountain View, CA,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of SGI or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. SGI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. SGI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /*
  26.  * xmclient.c - X11/Motif client interface to hearts
  27.  * 
  28.  * Author:    Mike Yang (mikey@sgi.com)
  29.  *        Silicon Graphics, Inc.
  30.  * Date:    Fri Jan 3 1992
  31.  * Copyright (c) 1992 Mike Yang
  32.  */
  33.  
  34. #include <stdlib.h>
  35. #include <malloc.h>
  36. #include <sys/errno.h>
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. #include <fcntl.h>
  40. #include "misc.h"
  41. #include "defs.h"
  42. #include "local.h"
  43. #include "client.h"
  44. #include "gfx.h"
  45. #ifdef SYSV
  46. #include <sys/termio.h>
  47. #endif
  48. #include <X11/cursorfont.h>
  49. #include <Xm/Form.h>
  50. #include <Xm/Text.h>
  51. #include <Xm/PushB.h>
  52. #include <Xm/LabelG.h>
  53. #include <Xm/DrawingA.h>
  54. #include <Xm/RowColumn.h>
  55. #include <Xm/Frame.h>
  56. #include <Xm/BulletinB.h>
  57.  
  58. #define NUM_TABLES_ROWS    2
  59. #define NUM_TABLES_COLS    4
  60. #define NUM_TABLES    (NUM_TABLES_ROWS*NUM_TABLES_COLS)
  61.  
  62. static int count;
  63. static Arg args[20];
  64.  
  65. typedef struct _CardInfo {
  66.   int rank;
  67.   int suit;
  68.   struct _CardInfo *next;
  69. } CardInfo;
  70.  
  71. typedef struct {
  72.   CardInfo *head;
  73. } SuitInfo;
  74.  
  75. SuitInfo my_hand[MAX_SUIT+1];
  76.  
  77. XtAppContext appContext;
  78. Widget toplevel, form, displayFrame, displayArea, playArea, scoreArea;
  79. Widget messageLabel, messageArea, messageEntry;
  80. Widget commandArea, showButton = NULL, autoButton = NULL;
  81. Widget quitButton, helpButton;
  82. Widget displayLabels, roundLabel, leadLabel, textArea, playLabelArea;
  83. Widget scorePlayer, scoreScore, scoreTotal;
  84. Widget playerLabels[5], scoreLabels[5], totalLabels[5];
  85. Widget playLabels[4];
  86. Widget optionForm, helpDialog = NULL;
  87. Widget gameBox, anotherGame, newGame, moreGames, quitGame, helpGame;
  88. Widget gamesHeader, gamesFrame, gamesRC, gamesMessage;
  89. Boolean showOld, *anotherPtr;
  90. CardInfo playCards[4], lastCards[4];
  91. char playNames[4][256], lastNames[4][256];
  92. XtInputId distId = None, dealerId = None;
  93. Boolean readingCard;
  94. Cursor cardCursor = None;
  95.  
  96. Rank
  97. convertRank(rank)
  98. int rank;
  99. {
  100.   if (rank == 13) {
  101.     return Ace;
  102.   } else {
  103.     return rank;
  104.   }
  105. }
  106.  
  107. Suit
  108. convertSuit(suit)
  109. int suit;
  110. {
  111.   Suit s;
  112.  
  113.   switch (suit) {
  114.   case SPADES:
  115.     s = Spade;
  116.     break;
  117.   case HEARTS:
  118.     s = Heart;
  119.     break;
  120.   case DIAMONDS:
  121.     s = Diamond;
  122.     break;
  123.   case CLUBS:
  124.     s = Club;
  125.     break;
  126.   }
  127.   return s;
  128. }
  129.  
  130. void
  131. showPlayArea(cards, names)
  132. CardInfo *cards;
  133. char names[4][256];
  134. {
  135.   int i;
  136.   XmString xs;
  137.  
  138.   for (i=0; i<4; i++) {
  139.     if (cards[i].rank) {
  140.       paint_card(XtWindow(playArea), i*STACK_WIDTH, 0,
  141.          convertRank(cards[i].rank), convertSuit(cards[i].suit), 0);
  142.     } else {
  143.       XClearArea(XtDisplay(playArea), XtWindow(playArea), i*STACK_WIDTH, 0,
  144.          STACK_WIDTH, 0, False);
  145.     }
  146.     if (cards[i].rank) {
  147.       xs = XmStringCreateSimple(names[i]);
  148.     } else {
  149.       xs = XmStringCreateSimple(" ");
  150.     }
  151.     count = 0;
  152.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  153.     XtSetValues(playLabels[i], args, count);
  154.     XmStringFree(xs);
  155.   }
  156. }
  157.  
  158. void
  159. setShowOld(v)
  160. Boolean v;
  161. {
  162.   if (showOld != v) {
  163.     showOld = v;
  164.     if (showOld) {
  165.       showPlayArea(lastCards, lastNames);
  166.     } else {
  167.       showPlayArea(playCards, playNames);
  168.     }
  169.   }
  170. }
  171.  
  172. void
  173. setReadingCard(v)
  174. Boolean v;
  175. {
  176.   if (readingCard != v) {
  177.     readingCard = v;
  178.     if (cardCursor == None) {
  179.       cardCursor = XCreateFontCursor(XtDisplay(toplevel), XC_hand1);
  180.     }
  181.     if (XtIsRealized(displayArea)) {
  182.       if (readingCard) {
  183.     XDefineCursor(XtDisplay(displayArea), XtWindow(displayArea),
  184.               cardCursor);
  185.       } else {
  186.     XUndefineCursor(XtDisplay(displayArea), XtWindow(displayArea));
  187.       }
  188.       XFlush(XtDisplay(displayArea));
  189.     }
  190.     if (!readingCard && showOld) {
  191.       setShowOld(False);
  192.     }
  193.   }
  194. }
  195.  
  196. /**********************************************************************/
  197.  
  198. void
  199. exposeDisplayArea(w, client_data, call_data)
  200. Widget w;
  201. XtPointer client_data;
  202. XtPointer call_data;
  203. {
  204.   Suit suit;
  205.   static Boolean first = True;
  206.  
  207.   for (suit=CLUBS; suit<=SPADES; suit++) {
  208.     print_cards(suit);
  209.   }
  210.   if (first) {
  211.     XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  212.     first = False;
  213.   }
  214. }
  215.  
  216. void
  217. displaySelect(w, client_data, event)
  218. Widget w;
  219. XtPointer client_data;
  220. XEvent *event;
  221. {
  222.   int suit, card, count;
  223.   CardInfo *ptr, *cardSelected;
  224.   char rch, sch;
  225.   static char rnames[] = " 23456789TJQKA";
  226.  
  227.   cardSelected = NULL;
  228.   if (readingCard &&
  229.       event->type == ButtonPress && event->xbutton.button == Button1) {
  230.     suit = (event->xbutton.x/STACK_WIDTH)+1;
  231.     card = (event->xbutton.y/CARD_DELTA)+1;
  232.     if (event->xbutton.x % STACK_WIDTH > CARD_WIDTH) {
  233.       /* clicked on space between stacks */
  234.     } else if (suit > 4) {
  235.       /* clicked outside stacks */
  236.     } else {
  237.       ptr = my_hand[suit].head;
  238.       count = 0;
  239.       while (count < card && ptr->next) {
  240.     count++;
  241.     ptr = ptr->next;
  242.       }
  243.       if (count == card) {
  244.     cardSelected = ptr;
  245.       } else if (count < card &&
  246.          event->xbutton.y-(count-1)*CARD_DELTA < CARD_HEIGHT) {
  247.     /* clicked on last card */
  248.     cardSelected = ptr;
  249.       } else {
  250.     /* clicked below stack */
  251.       }
  252.       if (!ptr->rank) {
  253.     cardSelected = NULL;
  254.       }
  255.     }
  256.   }
  257.   if (cardSelected) {
  258.     rch = rnames[cardSelected->rank];
  259.     switch (cardSelected->suit) {
  260.     case SPADES:
  261.       sch = 's';
  262.       break;
  263.     case HEARTS:
  264.       sch = 'h';
  265.       break;
  266.     case DIAMONDS:
  267.       sch = 'd';
  268.       break;
  269.     case CLUBS:
  270.       sch = 'c';
  271.       break;
  272.     }
  273.     send_card(rch, sch);
  274.     setReadingCard(False);
  275.     erase_window(TEXT_WINDOW);
  276.   } else {
  277.     XBell(XtDisplay(toplevel), 0);
  278.   }
  279. }
  280.  
  281. void
  282. send_msg(w, client_data, call_data)
  283. Widget w;
  284. XtPointer client_data;
  285. XtPointer call_data;
  286. {
  287.   char *msg;
  288.  
  289.   msg = XmTextGetString(messageEntry);
  290.   XmTextSetString(messageEntry, "");
  291.   send_message(msg);
  292.   XtFree(msg);
  293. }
  294.  
  295. void
  296. show_button(w, client_data, call_data)
  297. Widget w;
  298. XtPointer client_data;
  299. XtPointer call_data;
  300. {
  301.   XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  302.   if (readingCard) {
  303.     setShowOld(!showOld);
  304.   }
  305. }
  306.  
  307. void
  308. auto_play(w, client_data, call_data)
  309. Widget w;
  310. XtPointer client_data;
  311. XtPointer call_data;
  312. {
  313.   XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  314.   if (readingCard) {
  315.     send_auto();
  316.     setReadingCard(False);
  317.     erase_window(TEXT_WINDOW);
  318.   }
  319. }
  320.  
  321. void
  322. quit_game(w, client_data, call_data)
  323. Widget w;
  324. XtPointer client_data;
  325. XtPointer call_data;
  326. {
  327.   wimp_out();
  328. }
  329.  
  330. void
  331. help_me(w, client_data, call_data)
  332. Widget w;
  333. XtPointer client_data;
  334. XtPointer call_data;
  335. {
  336.   Widget text, okButton, label;
  337.   XmString xs;
  338.   char filename[256];
  339.   int fildes;
  340.   struct stat buf;
  341.   char *data;
  342.  
  343.   XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  344.   if (!helpDialog) {
  345.     count = 0;
  346.     XtSetArg(args[count], XmNtitle, "xmhearts help");  count++;
  347.     helpDialog = XmCreateFormDialog(toplevel, "helpDialog", args, count);
  348.  
  349.     xs = XmStringCreateSimple("OK");
  350.     count = 0;
  351.     XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  352.     XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  353.     XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  354.     XtSetArg(args[count], XmNrightOffset, 10);  count++;
  355.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  356.     okButton = XmCreatePushButton(helpDialog, "helpOK", args, count);
  357.     XtManageChild(okButton);
  358.     XmStringFree(xs);
  359.  
  360.     xs = XmStringCreateSimple("Xmhearts, a Motif interface to hearts.  Mike Yang, Silicon Graphics, mikey@sgi.com");
  361.     count = 0;
  362.     XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  363.     XtSetArg(args[count], XmNrightAttachment, XmATTACH_WIDGET);  count++;
  364.     XtSetArg(args[count], XmNrightWidget, okButton);  count++;
  365.     XtSetArg(args[count], XmNtopAttachment,
  366.          XmATTACH_OPPOSITE_WIDGET);  count++;
  367.     XtSetArg(args[count], XmNtopWidget, okButton);  count++;
  368.     XtSetArg(args[count], XmNbottomAttachment,
  369.          XmATTACH_OPPOSITE_WIDGET);  count++;
  370.     XtSetArg(args[count], XmNbottomWidget, okButton);  count++;
  371.     XtSetArg(args[count], XmNalignment, XmALIGNMENT_CENTER);  count++;
  372.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  373.     label = XmCreateLabelGadget(helpDialog, "label", args, count);
  374.     XtManageChild(label);
  375.     XmStringFree(xs);
  376.  
  377.     count = 0;
  378.     XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  379.     XtSetArg(args[count], XmNbottomAttachment, XmATTACH_WIDGET);  count++;
  380.     XtSetArg(args[count], XmNbottomWidget, okButton);  count++;
  381.     XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  382.     XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  383.     XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  384.     XtSetArg(args[count], XmNwordWrap, True);  count++;
  385.     XtSetArg(args[count], XmNscrollHorizontal, False);  count++;
  386.     XtSetArg(args[count], XmNeditable, False);  count++;
  387.     XtSetArg(args[count], XmNblinkRate, 0);  count++;
  388.     XtSetArg(args[count], XmNrows, 24);  count++;
  389.     XtSetArg(args[count], XmNcolumns, 80);  count++;
  390.     XtSetArg(args[count], XmNeditMode, XmMULTI_LINE_EDIT);  count++;
  391.     text = XmCreateScrolledText(helpDialog, "helpText", args, count);
  392.     XtManageChild(text);
  393.  
  394.     sprintf(filename, "%s/%s", HEARTSLIB, INSTRUCT);
  395.     if ((fildes = open(filename, O_RDONLY)) != -1) {
  396.       fstat(fildes, &buf);
  397.       data = (char *) malloc((size_t) buf.st_size+1);
  398.       read(fildes, data, (unsigned) buf.st_size);
  399.       data[buf.st_size] = '\0';
  400.       close(fildes);
  401.       XmTextSetString(text, data);
  402.       free(data);
  403.     } else {
  404.       XmTextSetString(text, "Help file missing.\n");
  405.     }
  406.   }
  407.   XtManageChild(helpDialog);
  408. }
  409.  
  410. void
  411. exposePlayArea(w, client_data, call_data)
  412. Widget w;
  413. XtPointer client_data;
  414. XtPointer call_data;
  415. {
  416.   if (showOld) {
  417.     showPlayArea(lastCards, lastNames);
  418.   } else {
  419.     showPlayArea(playCards, playNames);
  420.   }
  421. }
  422.  
  423. void
  424. another_game(w, client_data, call_data)
  425. Widget w;
  426. XtPointer client_data;
  427. XtPointer call_data;
  428. {
  429.   *anotherPtr = TRUE;
  430.   if (!first_game) {
  431.     joined = TRUE;
  432.   }
  433. }
  434.  
  435. void
  436. new_game(w, client_data, call_data)
  437. Widget w;
  438. XtPointer client_data;
  439. XtPointer call_data;
  440. {
  441.   start_new_game();
  442.   joined = TRUE;
  443. }
  444.  
  445. void
  446. more_games(w, client_data, call_data)
  447. Widget w;
  448. XtPointer client_data;
  449. XtPointer call_data;
  450. {
  451.   if (table_count > NUM_TABLES) {
  452.     if ((cur_screen_table += NUM_TABLES) > table_count) {
  453.       cur_screen_table = 1;
  454.     }
  455.     show_tables(cur_screen_table);
  456.   }
  457. }
  458.  
  459. void
  460. tableSelect(w, client_data, event)
  461. Widget w;
  462. XtPointer client_data;
  463. XEvent *event;
  464. {
  465.   int i;
  466.   Widget *widgets;
  467.   table_ptr cur_ptr;
  468.  
  469.   if (table_count && first_game &&
  470.       event->type == ButtonPress && event->xbutton.button == Button1) {
  471.     cur_ptr = first_table;
  472.     for (i=0; i<table_count; i++) {
  473.       if (cur_ptr->data && !cur_ptr->closed) {
  474.     widgets = (Widget *) cur_ptr->data;
  475.     if (w == widgets[1]) {
  476.       join_game(cur_ptr->table_id);
  477.       joined = TRUE;
  478.       return;
  479.     }
  480.       }
  481.       cur_ptr = cur_ptr->next_table;
  482.     }
  483.   } else if (XtIsSensitive(anotherGame)) {
  484.     another_game(w, NULL, NULL);
  485.   }
  486. }
  487.  
  488. /**********************************************************************/
  489.  
  490. void
  491. dealerInput(client_data, source, id)
  492. XtPointer client_data;
  493. int *source;
  494. XtInputId *id;
  495. {
  496.   fd_type read_fd;
  497.   int nready;
  498.   struct timeval timeout;
  499.  
  500.   timeout.tv_sec = 0;
  501.   timeout.tv_usec = 0;
  502.   fd_init(dealer_socket, &read_fd);
  503.   while (dealerId &&
  504.      (nready = select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
  505.               &timeout)) && nready > 0) {
  506.     do_socket();
  507.   }
  508. }
  509.  
  510. void
  511. distInput(client_data, source, id)
  512. XtPointer client_data;
  513. int *source;
  514. XtInputId *id;
  515. {
  516.   fd_type read_fd;
  517.   int nready;
  518.   struct timeval timeout;
  519.  
  520.   timeout.tv_sec = 0;
  521.   timeout.tv_usec = 0;
  522.   fd_init(dist_socket, &read_fd);
  523.   while (distId &&
  524.      (nready = select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
  525.               &timeout)) && nready > 0) {
  526.     do_dist();
  527.   }
  528. }
  529.  
  530. void
  531. buildScoreLabels(parent, header, array)
  532. Widget parent;
  533. char *header;
  534. Widget *array;
  535. {
  536.   Widget rc;
  537.   XmString xs;
  538.   int each;
  539.  
  540.   xs = XmStringCreateSimple(header);
  541.   count = 0;
  542.   XtSetArg(args[count], XmNorientation, XmVERTICAL);  count++;
  543.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  544.   if (array == playerLabels) {
  545.     XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_BEGINNING);  count++;
  546.   } else {
  547.     XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_END);  count++;
  548.   }
  549.   rc = XmCreateRowColumn(parent, "scoresColumn", args, count);
  550.   XtManageChild(rc);
  551.   count = 0;
  552.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  553.   XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  554.   array[0] = XmCreateLabelGadget(rc, "header", args, count);
  555.   XmStringFree(xs);
  556.   xs = XmStringCreateSimple(" ");
  557.   for (each=1; each<=4; each++) {
  558.     count = 0;
  559.     XtSetArg(args[count], XmNlabelString, xs);  count++; 
  560.     XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  561.     array[each] = XmCreateLabelGadget(rc, "label", args, count);
  562.   }
  563.   XmStringFree(xs);
  564.   XtManageChildren(array, 5);
  565. }
  566.  
  567. void
  568. buildScoreArea(parent)
  569. Widget parent;
  570. {
  571.   Widget rc;
  572.  
  573.   count = 0;
  574.   XtSetArg(args[count], XmNorientation, XmHORIZONTAL);  count++;
  575.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  576.   rc = XmCreateRowColumn(parent, "scoreArea", args, count);
  577.   XtManageChild(rc);
  578.   buildScoreLabels(rc, "Player:      ", playerLabels);
  579.   buildScoreLabels(rc, "Score:", scoreLabels);
  580.   buildScoreLabels(rc, "Total:", totalLabels);
  581. }
  582.  
  583. void
  584. buildCommandArea(parent)
  585. Widget parent;
  586. {
  587.   Widget rc;
  588.   XmString xs;
  589.  
  590.   count = 0;
  591.   XtSetArg(args[count], XmNorientation, XmHORIZONTAL);  count++;
  592.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++; 
  593.   XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_BEGINNING);  count++;
  594.   rc = XmCreateRowColumn(parent, "commandArea", args, count);
  595.   XtManageChild(rc);
  596.   xs = XmStringCreateSimple("Toggle Last");
  597.   count = 0;
  598.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  599.   showButton = XmCreatePushButton(rc, "showButton", args, count);
  600.   XtManageChild(showButton);
  601.   XmStringFree(xs);
  602.   XtAddCallback(showButton, XmNactivateCallback, show_button, NULL);
  603.   xs = XmStringCreateSimple("Auto Play");
  604.   count = 0;
  605.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  606.   autoButton = XmCreatePushButton(rc, "autoButton", args, count);
  607.   XtManageChild(autoButton);
  608.   XtAddCallback(autoButton, XmNactivateCallback, auto_play, NULL);
  609.   XmStringFree(xs);
  610.   xs = XmStringCreateSimple("Quit");
  611.   count = 0;
  612.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  613.   quitButton = XmCreatePushButton(rc, "quitButton", args, count);
  614.   XtManageChild(quitButton);
  615.   XtAddCallback(quitButton, XmNactivateCallback, quit_game, NULL);
  616.   XmStringFree(xs);
  617.   xs = XmStringCreateSimple("Help");
  618.   count = 0;
  619.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  620.   helpButton = XmCreatePushButton(rc, "helpButton", args, count);
  621.   XtManageChild(helpButton);
  622.   XtAddCallback(helpButton, XmNactivateCallback, help_me, NULL);
  623.   XmStringFree(xs);
  624. }
  625.  
  626. void
  627. buildInterface(parent)
  628. Widget parent;
  629. {
  630.   Widget form;
  631.   XmString xs;
  632.  
  633.   count = 0;
  634.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  635.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  636.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  637.   XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  638.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  639.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  640.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  641.   XtSetArg(args[count], XmNrightOffset, 10);  count++;
  642.   form = XmCreateForm(parent, "form", args, count);
  643.   XtManageChild(form);
  644.  
  645.   count = 0;
  646.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  647.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  648.   XtSetArg(args[count], XmNshadowType, XmSHADOW_IN);  count++;
  649.   XtSetArg(args[count], XmNmarginWidth, 10);  count++;
  650.   XtSetArg(args[count], XmNmarginHeight, 10);  count++;
  651.   displayFrame = XmCreateFrame(form, "displayFrame", args, count);
  652.   XtManageChild(displayFrame);
  653.   count = 0;
  654.   XtSetArg(args[count], XmNwidth, 4*STACK_WIDTH-STACK_SPACING+2);  count++;
  655.   XtSetArg(args[count], XmNheight, 12*CARD_DELTA+CARD_HEIGHT+2);  count++;
  656.   XtSetArg(args[count], XmNshadowThickness, 0);  count++;
  657.   displayArea = XmCreateDrawingArea(displayFrame, "displayArea",
  658.                     args, count);
  659.   XtManageChild(displayArea);
  660.   XtAddCallback(displayArea, XmNexposeCallback, exposeDisplayArea, NULL);
  661.   XtAddEventHandler(displayArea, ButtonPressMask, False, displaySelect, NULL);
  662.  
  663.   count = 0;
  664.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  665.   XtSetArg(args[count], XmNtopWidget, displayFrame);  count++;
  666.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  667.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  668. /* adjust for display frame margin */
  669.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  670.   XtSetArg(args[count], XmNrightAttachment,
  671.        XmATTACH_OPPOSITE_WIDGET);  count++;
  672.   XtSetArg(args[count], XmNrightWidget, displayFrame);  count++;
  673.   XtSetArg(args[count], XmNheight, CARD_HEIGHT+2);  count++;
  674.   XtSetArg(args[count], XmNshadowThickness, 0);  count++;
  675.   playArea = XmCreateDrawingArea(form, "playArea", args, count);
  676.   XtManageChild(playArea);
  677.   XtAddCallback(playArea, XmNexposeCallback, exposePlayArea, NULL);
  678.  
  679.   count = 0;
  680.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  681.   XtSetArg(args[count], XmNtopWidget, playArea);  count++;
  682.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  683.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  684. /* adjust for display frame margin */
  685.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  686.   XtSetArg(args[count], XmNrightAttachment,
  687.        XmATTACH_OPPOSITE_WIDGET);  count++;
  688.   XtSetArg(args[count], XmNrightWidget, displayFrame);  count++;
  689.   XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_CENTER);  count++;
  690.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  691.   XtSetArg(args[count], XmNnumColumns, 1);  count++;
  692.   XtSetArg(args[count], XmNorientation, XmHORIZONTAL);  count++;
  693.   XtSetArg(args[count], XmNmarginWidth, 0);  count++;
  694.   XtSetArg(args[count], XmNmarginHeight, 0);  count++;
  695.   XtSetArg(args[count], XmNspacing, STACK_SPACING);  count++;
  696.   playLabelArea = XmCreateRowColumn(form, "playLabelArea", args, count);
  697.   XtManageChild(playLabelArea);
  698.  
  699.   xs = XmStringCreateSimple(" ");
  700.   count = 0;
  701.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  702.   XtSetArg(args[count], XmNwidth, CARD_WIDTH);  count++;
  703.   XtSetArg(args[count], XmNmarginWidth, 0);  count++;
  704.   XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  705.   playLabels[0] = XmCreateLabelGadget(playLabelArea, "playLabel", args, count);
  706.   XtManageChild(playLabels[0]);
  707.   playLabels[1] = XmCreateLabelGadget(playLabelArea, "playLabel", args, count);
  708.   XtManageChild(playLabels[1]);
  709.   playLabels[2] = XmCreateLabelGadget(playLabelArea, "playLabel", args, count);
  710.   XtManageChild(playLabels[2]);
  711.   playLabels[3] = XmCreateLabelGadget(playLabelArea, "playLabel", args, count);
  712.   XtManageChild(playLabels[3]);
  713.   XmStringFree(xs);
  714.  
  715.   count = 0;
  716.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  717.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  718.   scoreArea = XmCreateFrame(form, "scoreArea", args, count);
  719.   XtManageChild(scoreArea);
  720.   buildScoreArea(scoreArea);
  721.  
  722.   count = 0;
  723.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  724.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_WIDGET);  count++;
  725.   XtSetArg(args[count], XmNleftWidget, displayFrame);  count++;
  726.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  727.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_WIDGET);  count++;
  728.   XtSetArg(args[count], XmNrightWidget, scoreArea);  count++;
  729.   XtSetArg(args[count], XmNorientation, XmVERTICAL);  count++;
  730.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  731.   XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_BEGINNING);  count++;
  732.   displayLabels = XmCreateRowColumn(form, "displayLabels", args, count);
  733.   XtManageChild(displayLabels);
  734.  
  735.   xs = XmStringCreateSimple("New hand...");
  736.   count = 0;
  737.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  738.   XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  739.   roundLabel = XmCreateLabelGadget(displayLabels, "roundLabel", args, count);
  740.   XtManageChild(roundLabel);
  741.   XmStringFree(xs);
  742.  
  743.   xs = XmStringCreateSimple("Round: 1");
  744.   count = 0;
  745.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  746.   XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  747.   leadLabel = XmCreateLabelGadget(displayLabels, "leadLabel", args, count);
  748.   XtManageChild(leadLabel);
  749.   XmStringFree(xs);
  750.  
  751.   xs = XmStringCreateSimple(" ");
  752.   count = 0;
  753.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  754.   XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  755.   textArea = XmCreateLabelGadget(displayLabels, "textArea", args, count);
  756.   XtManageChild(textArea);
  757.   XmStringFree(xs);
  758.  
  759.   xs = XmStringCreateSimple("Messages:");
  760.   count = 0;
  761.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  762.   XtSetArg(args[count], XmNtopWidget, scoreArea);  count++;
  763.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  764.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_WIDGET);  count++;
  765.   XtSetArg(args[count], XmNleftWidget, displayFrame);  count++;
  766.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  767.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  768.   XtSetArg(args[count], XmNalignment, XmALIGNMENT_BEGINNING);  count++;
  769.   messageLabel = XmCreateLabelGadget(form, "messageLabel", args, count);
  770.   XtManageChild(messageLabel);
  771.   XmStringFree(xs);
  772.  
  773.   count = 0;
  774.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  775.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  776.   commandArea = XmCreateForm(form, "commandArea", args, count);
  777.   XtManageChild(commandArea);
  778.   buildCommandArea(commandArea);
  779.  
  780.   count = 0;
  781.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_WIDGET);  count++;
  782.   XtSetArg(args[count], XmNbottomWidget, commandArea);  count++;
  783.   XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  784.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_WIDGET);  count++;
  785.   XtSetArg(args[count], XmNleftWidget, displayFrame);  count++;
  786.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  787.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  788.   messageEntry = XmCreateText(form, "messageEntry", args, count);
  789.   XtManageChild(messageEntry);
  790.   XtAddCallback(messageEntry, XmNactivateCallback, send_msg, NULL);
  791.   XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  792.  
  793.   count = 0;
  794.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  795.   XtSetArg(args[count], XmNtopWidget, messageLabel);  count++;
  796.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_WIDGET);  count++;
  797.   XtSetArg(args[count], XmNbottomWidget, messageEntry);  count++;
  798.   XtSetArg(args[count], XmNbottomOffset, 5);  count++;
  799.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_WIDGET);  count++;
  800.   XtSetArg(args[count], XmNleftWidget, displayFrame);  count++;
  801.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  802.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  803.   XtSetArg(args[count], XmNwordWrap, True);  count++;
  804.   XtSetArg(args[count], XmNscrollHorizontal, False);  count++;
  805.   XtSetArg(args[count], XmNeditable, False);  count++; 
  806.   XtSetArg(args[count], XmNblinkRate, 0);  count++;
  807.   XtSetArg(args[count], XmNcolumns, 70);  count++;
  808.   XtSetArg(args[count], XmNeditMode, XmMULTI_LINE_EDIT);  count++;
  809.   messageArea = XmCreateScrolledText(form, "messageArea", args, count);
  810.   XtManageChild(messageArea);
  811. }
  812.  
  813. void
  814. buildOptionInterface(parent)
  815. Widget parent;
  816. {
  817.   Widget header;
  818.   XmString xs;
  819.  
  820.   count = 0;
  821.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  822.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  823.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  824.   XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  825.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  826.   XtSetArg(args[count], XmNleftOffset, 10);  count++;
  827.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  828.   XtSetArg(args[count], XmNrightOffset, 10);  count++;
  829.   optionForm = XmCreateForm(parent, "optionForm", args, count);
  830.   XtManageChild(optionForm);
  831.  
  832.   xs = XmStringCreateSimple("Welcome to the Game of Hearts");
  833.   count = 0;
  834.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_FORM);  count++;
  835.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  836.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  837.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  838.   XtSetArg(args[count], XmNalignment, XmALIGNMENT_CENTER);  count++;
  839.   XtSetArg(args[count], XmNmarginHeight, 20);  count++;
  840.   header = XmCreateLabelGadget(optionForm, "header", args, count);
  841.   XtManageChild(header);
  842.   XmStringFree(xs);
  843.  
  844.   if (MIKEYJ) {
  845.     xs = XmStringCreateSimple("(the Jack of Diamonds scores -10)");
  846.   } else {
  847.     xs = XmStringCreateSimple("");
  848.   }
  849.   count = 0;
  850.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  851.   XtSetArg(args[count], XmNtopWidget, header);  count++;
  852.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  853.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  854.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  855.   XtSetArg(args[count], XmNalignment, XmALIGNMENT_CENTER);  count++;
  856.   gamesMessage = XmCreateLabelGadget(optionForm, "gamesMessage", args, count);
  857.   XtManageChild(gamesMessage);
  858.   XmStringFree(xs);
  859.  
  860.   xs = XmStringCreateSimple("Current Games:");
  861.   count = 0;
  862.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  863.   XtSetArg(args[count], XmNtopWidget, gamesMessage);  count++;
  864.   XtSetArg(args[count], XmNtopOffset, 10);  count++;
  865.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  866.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  867.   XtSetArg(args[count], XmNalignment, XmALIGNMENT_BEGINNING);  count++;
  868.   gamesHeader = XmCreateLabelGadget(optionForm, "gamesHeader", args, count);
  869.   XtManageChild(gamesHeader);
  870.   XmStringFree(xs);
  871.  
  872.   count = 0;
  873.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_FORM);  count++;
  874.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  875.   XtSetArg(args[count], XmNorientation, XmHORIZONTAL);  count++;
  876.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++; 
  877.   XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_BEGINNING);  count++;
  878.   gameBox = XmCreateRowColumn(optionForm, "gameBox", args, count);
  879.   XtManageChild(gameBox);
  880.  
  881.   xs = XmStringCreateSimple("Another Game");
  882.   count = 0;
  883.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  884.   anotherGame = XmCreatePushButton(gameBox, "anotherGame", args, count);
  885.   XtManageChild(anotherGame);
  886.   XtAddCallback(anotherGame, XmNactivateCallback, another_game, NULL);
  887.   
  888.   xs = XmStringCreateSimple("New Game");
  889.   count = 0;
  890.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  891.   newGame = XmCreatePushButton(gameBox, "newGame", args, count);
  892.   XtManageChild(newGame);
  893.   XtAddCallback(newGame, XmNactivateCallback, new_game, NULL);
  894.   
  895.   xs = XmStringCreateSimple("More Games");
  896.   count = 0;
  897.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  898.   moreGames = XmCreatePushButton(gameBox, "moreGames", args, count);
  899.   XtManageChild(moreGames);
  900.   XtAddCallback(moreGames, XmNactivateCallback, more_games, NULL);
  901.   
  902.   xs = XmStringCreateSimple("Quit");
  903.   count = 0;
  904.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  905.   quitGame = XmCreatePushButton(gameBox, "quitGame", args, count);
  906.   XtManageChild(quitGame);
  907.   XtAddCallback(quitGame, XmNactivateCallback, quit_game, NULL);
  908.  
  909.   xs = XmStringCreateSimple("Help");
  910.   count = 0;
  911.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  912.   helpGame = XmCreatePushButton(gameBox, "helpGame", args, count);
  913.   XtManageChild(helpGame);
  914.   XtAddCallback(helpGame, XmNactivateCallback, help_me, NULL);
  915.  
  916.   count = 0;
  917.   XtSetArg(args[count], XmNtopAttachment, XmATTACH_WIDGET);  count++;
  918.   XtSetArg(args[count], XmNtopWidget, gamesHeader);  count++;
  919.   XtSetArg(args[count], XmNbottomAttachment, XmATTACH_WIDGET);  count++;
  920.   XtSetArg(args[count], XmNbottomWidget, gameBox);  count++;
  921.   XtSetArg(args[count], XmNbottomOffset, 10);  count++;
  922.   XtSetArg(args[count], XmNleftAttachment, XmATTACH_FORM);  count++;
  923.   XtSetArg(args[count], XmNrightAttachment, XmATTACH_FORM);  count++;
  924.   XtSetArg(args[count], XmNshadowType, XmSHADOW_IN);  count++;
  925.   gamesFrame = XmCreateFrame(optionForm, "gamesFrame", args, count);
  926.   XtManageChild(gamesFrame);
  927.  
  928.   count = 0;
  929.   XtSetArg(args[count], XmNorientation, XmVERTICAL);  count++;
  930.   XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  931.   XtSetArg(args[count], XmNnumColumns, NUM_TABLES_COLS);  count++;
  932.   XtSetArg(args[count], XmNadjustLast, False);  count++;
  933.   XtSetArg(args[count], XmNmarginWidth, 10);  count++;
  934.   XtSetArg(args[count], XmNmarginHeight, 10);  count++;
  935.   XtSetArg(args[count], XmNspacing, 10);  count++;
  936.   gamesRC = XmCreateRowColumn(gamesFrame, "gamesRC", args, count);
  937.   XtManageChild(gamesRC);
  938. }
  939.  
  940. init(argc_p, argv)
  941. int *argc_p;
  942. char **argv;
  943. {
  944.   char ch, *pager, buffer[128];
  945.   int suit;
  946.   CardInfo *card;
  947.  
  948.   toplevel = XtInitialize(argv[0], "Xmhearts", NULL, 0, argc_p, argv);
  949. #ifdef USE_SCHEMES
  950.   VkLoadScheme(XtDisplay(toplevel), argv[0], "Xmhearts");
  951. #endif
  952.   appContext = XtWidgetToApplicationContext(toplevel);
  953.  
  954.   count = 0;
  955.   form = XmCreateForm(toplevel, "form", args, count);
  956.   XtManageChild(form);
  957.  
  958.   buildInterface(form);
  959.   buildOptionInterface(form);
  960.   gfx_init(XtDisplay(toplevel), XScreenNumberOfScreen(XtScreen(toplevel)));
  961.  
  962.   XtRealizeWidget(toplevel);
  963.  
  964.   for (suit=CLUBS; suit<=SPADES; suit++) {
  965.     card = (CardInfo *) malloc(sizeof(CardInfo));
  966.     card->rank = card->suit = 0;
  967.     card->next = NULL;
  968.     my_hand[suit].head = card;
  969.   }
  970.   playCards[0].rank = 0;
  971.   playCards[1].rank = 0;
  972.   playCards[2].rank = 0;
  973.   playCards[3].rank = 0;
  974.   playNames[0][0] = '\0';
  975.   playNames[1][0] = '\0';
  976.   playNames[2][0] = '\0';
  977.   playNames[3][0] = '\0';
  978.   lastCards[0].rank = 0;
  979.   lastCards[1].rank = 0;
  980.   lastCards[2].rank = 0;
  981.   lastCards[3].rank = 0;
  982.   lastNames[0][0] = '\0';
  983.   lastNames[1][0] = '\0';
  984.   lastNames[2][0] = '\0';
  985.   lastNames[3][0] = '\0';
  986.   setReadingCard(False);
  987. }
  988.  
  989. print_cards(suit)
  990. int suit;
  991. {
  992.   CardInfo *ptr;
  993.   int y;
  994.   Rank r;
  995.   Suit s;
  996.  
  997.   s = convertSuit(suit);
  998.   ptr = my_hand[suit].head;
  999.   y = 0;
  1000.   while (ptr->next) {
  1001.     ptr = ptr->next;
  1002.     r = convertRank(ptr->rank);
  1003.     paint_card(XtWindow(displayArea), (suit-1)*STACK_WIDTH, y, r, s,
  1004.            ptr->next ? CARD_DELTA : 0);
  1005.     y += CARD_DELTA;
  1006.   }
  1007.   if (y) {
  1008.     XClearArea(XtDisplay(displayArea), XtWindow(displayArea),
  1009.            (suit-1)*STACK_WIDTH, y+CARD_HEIGHT-CARD_DELTA+1 /* bw */,
  1010.            STACK_WIDTH, 0, False);
  1011.   } else {
  1012.     XClearArea(XtDisplay(displayArea), XtWindow(displayArea),
  1013.            (suit-1)*STACK_WIDTH, 0,
  1014.            STACK_WIDTH, 0, False);
  1015.   }
  1016. }
  1017.  
  1018. void
  1019. displayMessage(msg)
  1020. char *msg;
  1021. {
  1022.   XmString xs;
  1023.  
  1024.   xs = XmStringCreateSimple(msg);
  1025.   count = 0;
  1026.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1027.   XtSetValues(textArea, args, count);
  1028.   XmStringFree(xs);
  1029. }
  1030.  
  1031. /**********************************************************************/
  1032.  
  1033. enter_card(rank, suit)
  1034. int rank, suit;
  1035. {
  1036.   CardInfo *card, *ptr;
  1037.  
  1038.   card = (CardInfo *) malloc(sizeof(CardInfo));
  1039.   card->rank = rank;
  1040.   card->suit = suit;
  1041.   ptr = my_hand[suit].head;
  1042.   while (ptr->next && ptr->next->rank > rank) {
  1043.     ptr = ptr->next;
  1044.   }
  1045.   card->next = ptr->next;
  1046.   ptr->next = card;
  1047.   print_cards(suit);
  1048. }
  1049.  
  1050. remove_card(rank, suit)
  1051. int rank, suit;
  1052. {
  1053.   CardInfo *card, *ptr;
  1054.  
  1055.   ptr = my_hand[suit].head;
  1056.   while (ptr->next) {
  1057.     if (ptr->next->rank == rank) {
  1058.       card = ptr->next;
  1059.       ptr->next = card->next;
  1060.       free((char *) card);
  1061.       break;
  1062.     } else {
  1063.       ptr = ptr->next;
  1064.     }
  1065.   }
  1066.   print_cards(suit);
  1067. }
  1068.  
  1069. erase_window(window_num)
  1070. int window_num;
  1071. {
  1072.   XmString xs;
  1073.  
  1074.   if (window_num == PLAY_WINDOW) {
  1075. /* if PLAY_WINDOW then save it for showing last */
  1076.     lastCards[0] = playCards[0];
  1077.     lastCards[1] = playCards[1];
  1078.     lastCards[2] = playCards[2];
  1079.     lastCards[3] = playCards[3];
  1080.     strcpy(lastNames[0], playNames[0]);
  1081.     strcpy(lastNames[1], playNames[1]);
  1082.     strcpy(lastNames[2], playNames[2]);
  1083.     strcpy(lastNames[3], playNames[3]);
  1084.     playCards[0].rank = 0;
  1085.     playCards[1].rank = 0;
  1086.     playCards[2].rank = 0;
  1087.     playCards[3].rank = 0;
  1088.     playNames[0][0] = '\0';
  1089.     playNames[1][0] = '\0';
  1090.     playNames[2][0] = '\0';
  1091.     playNames[3][0] = '\0';
  1092.     XClearArea(XtDisplay(playArea), XtWindow(playArea), 0, 0,
  1093.            0, 0, False);
  1094.     xs = XmStringCreateSimple(" ");
  1095.     count = 0;
  1096.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1097.     XtSetValues(playLabels[0], args, count);
  1098.     XtSetValues(playLabels[1], args, count);
  1099.     XtSetValues(playLabels[2], args, count);
  1100.     XtSetValues(playLabels[3], args, count);
  1101.     XmStringFree(xs);
  1102.   } else if (window_num == TEXT_WINDOW) {
  1103.     displayMessage("");
  1104.   }
  1105. }
  1106.  
  1107. read_card()
  1108. {
  1109.   setReadingCard(True);
  1110. }
  1111.  
  1112. play_card(player, rch, sch, msg)
  1113. int player, rch, sch;
  1114. char *msg;
  1115. {
  1116.   XmString xs;
  1117.  
  1118.   playCards[player-1].rank = get_rank(rch);
  1119.   playCards[player-1].suit = get_suit(sch);
  1120.   if (!showOld) {
  1121.     paint_card(XtWindow(playArea), (player-1)*STACK_WIDTH, 0,
  1122.            convertRank(playCards[player-1].rank),
  1123.            convertSuit(playCards[player-1].suit),
  1124.            0);
  1125.   }
  1126.   if (*msg != '\0') {
  1127.     strcpy(playNames[player-1], msg);
  1128.     if (!showOld) {
  1129.       xs = XmStringCreateSimple(msg);
  1130.       count = 0;
  1131.       XtSetArg(args[count], XmNlabelString, xs);  count++;
  1132.       XtSetValues(playLabels[player-1], args, count);
  1133.       XmStringFree(xs);
  1134.     }
  1135.   }
  1136.   XmUpdateDisplay(playArea);
  1137.   sleep(1);
  1138. }
  1139.  
  1140. score_points(player, pts, total_pts, msg)
  1141. int player, pts, total_pts;
  1142. char *msg;
  1143. {
  1144.   char str[256];
  1145.   XmString xs;
  1146.  
  1147.   xs = XmStringCreateSimple(msg);
  1148.   count = 0;
  1149.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1150.   XtSetValues(playerLabels[player], args, count);
  1151.   XmStringFree(xs);
  1152.   sprintf(str, "%d  ", pts);
  1153.   xs = XmStringCreateSimple(str);
  1154.   count = 0;
  1155.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1156.   XtSetValues(scoreLabels[player], args, count);
  1157.   XmStringFree(xs);
  1158.   sprintf(str, "%d  ", total_pts);
  1159.   xs = XmStringCreateSimple(str);
  1160.   count = 0;
  1161.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1162.   XtSetValues(totalLabels[player], args, count);
  1163.   XmStringFree(xs);
  1164. }
  1165.  
  1166. display_message(window_num, msg)
  1167. int window_num;
  1168. char *msg;
  1169. {
  1170.   XmString xs;
  1171.   char *str;
  1172.  
  1173.   if (window_num == MESG_WINDOW || window_num == PLAY_WINDOW) {
  1174.     XmTextInsert(messageArea, XmTextGetLastPosition(messageArea), msg);
  1175.     XmTextInsert(messageArea, XmTextGetLastPosition(messageArea), "\n");
  1176.     {
  1177.       short rows;
  1178.       Position x, y;
  1179.       
  1180.       count = 0;
  1181.       XtSetArg(args[count], XmNrows, &rows);  count++;
  1182.       XtGetValues(messageArea, args, count);
  1183.       if (rows <= 1) {
  1184.     XmTextShowPosition(messageArea, XmTextGetLastPosition(messageArea));
  1185.       } else {
  1186.     while (!XmTextPosToXY(messageArea, XmTextGetLastPosition(messageArea),
  1187.                   &x, &y)) {
  1188.       XmTextScroll(messageArea, 1);
  1189.     }
  1190.       }
  1191.     }
  1192.   } else {
  1193.     xs = XmStringCreateSimple(msg);
  1194.     count = 0;
  1195.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1196.     if (window_num == TEXT_WINDOW) {
  1197.       XtSetValues(textArea, args, count);
  1198.     } else if (window_num == ROUND_WINDOW) {
  1199.       XtSetValues(roundLabel, args, count);
  1200.     } else if (window_num == LEAD_WINDOW) {
  1201.       XtSetValues(leadLabel, args, count);
  1202.     }
  1203.     XmStringFree(xs);
  1204.   }
  1205. }
  1206.  
  1207. game_is_over()
  1208. {
  1209.   XmString xs;
  1210.   Boolean buttonPressed;
  1211.   XEvent event;
  1212.  
  1213.   display_message(MESG_WINDOW,
  1214.           "--------------------------------------------------------");
  1215.   display_message(MESG_WINDOW, "");
  1216.   display_message(MESG_WINDOW, "Click the left mouse button to continue...");
  1217.   XmUpdateDisplay(messageArea);
  1218.  
  1219.   buttonPressed = False;
  1220.   XGrabPointer(XtDisplay(messageArea), XtWindow(messageArea), True,
  1221.            ButtonPressMask, GrabModeAsync, GrabModeAsync,
  1222.            XtWindow(messageArea), None, CurrentTime);
  1223.   while (!buttonPressed) {
  1224.     if (XCheckTypedWindowEvent(XtDisplay(messageArea),
  1225.                    XtWindow(messageArea),
  1226.                    ButtonPress, &event)) {
  1227.       XtDispatchEvent(&event);
  1228.       XUngrabPointer(XtDisplay(messageArea), event.xbutton.time);
  1229.       XSync(XtDisplay(messageArea), False);
  1230.       buttonPressed = True;
  1231.     }
  1232.   }
  1233. }
  1234.  
  1235. start_game()
  1236. {
  1237.   XLowerWindow(XtDisplay(optionForm), XtWindow(optionForm));
  1238.   XmProcessTraversal(messageEntry, XmTRAVERSE_CURRENT);
  1239.   XSync(XtDisplay(optionForm), False);
  1240.   showOld = False;
  1241.  
  1242.   playCards[0].rank = 0;
  1243.   playCards[1].rank = 0;
  1244.   playCards[2].rank = 0;
  1245.   playCards[3].rank = 0;
  1246.   playNames[0][0] = '\0';
  1247.   playNames[1][0] = '\0';
  1248.   playNames[2][0] = '\0';
  1249.   playNames[3][0] = '\0';
  1250.   lastCards[0].rank = 0;
  1251.   lastCards[1].rank = 0;
  1252.   lastCards[2].rank = 0;
  1253.   lastCards[3].rank = 0;
  1254.   lastNames[0][0] = '\0';
  1255.   lastNames[1][0] = '\0';
  1256.   lastNames[2][0] = '\0';
  1257.   lastNames[3][0] = '\0';
  1258.  
  1259.   XmTextSetString(messageArea, "");
  1260. }
  1261.  
  1262. /*
  1263.  * Scan input for redraw screen requests or ':' messages.
  1264.  * Also scan socket for incoming commands.
  1265.  */
  1266. scan()
  1267. {
  1268.   static XEvent event;
  1269.  
  1270.   XtAppNextEvent(appContext, &event);
  1271.   XtDispatchEvent(&event);
  1272. }
  1273.  
  1274. terminate()
  1275. {
  1276.   XtDestroyWidget(toplevel);
  1277. }
  1278.  
  1279. /*
  1280.  * show_table - display table which is position table_pos on screen.
  1281.  */
  1282. show_table(cur_ptr, table_pos)
  1283. table_ptr    cur_ptr;
  1284. int        table_pos;
  1285. {
  1286.   Dimension width, height, marginWidth, marginHeight, spacing;
  1287.   Widget *widgets;
  1288.   XmString xs;
  1289.   char str[256];
  1290.   int each;
  1291.  
  1292.   count = 0;
  1293.   XtSetArg(args[count], XmNwidth, &width);  count++;
  1294.   XtSetArg(args[count], XmNheight, &height);  count++;
  1295.   XtSetArg(args[count], XmNmarginWidth, &marginWidth);  count++;
  1296.   XtSetArg(args[count], XmNmarginHeight, &marginHeight);  count++;
  1297.   XtSetArg(args[count], XmNspacing, &spacing);  count++;
  1298.   XtGetValues(gamesRC, args, count);
  1299.  
  1300.   if (!cur_ptr->data) {
  1301.     widgets = (Widget *) malloc(8*sizeof(Widget));
  1302.     count = 0;
  1303.     XtSetArg(args[count], XmNshadowType, XmSHADOW_OUT);  count++;
  1304.     widgets[0] = XmCreateFrame(gamesRC, "tableFrame", args, count);
  1305.     XtManageChild(widgets[0]);
  1306.     count = 0;
  1307.     XtSetArg(args[count], XmNorientation, XmVERTICAL);  count++;
  1308.     XtSetArg(args[count], XmNpacking, XmPACK_COLUMN);  count++;
  1309.     XtSetArg(args[count], XmNnumColumns, 1);  count++;
  1310.     XtSetArg(args[count], XmNentryAlignment, XmALIGNMENT_CENTER);  count++;
  1311.     XtSetArg(args[count], XmNmarginWidth, 0);  count++;
  1312.     widgets[1] = XmCreateRowColumn(widgets[0], "tableW", args, count);
  1313.     XtAddEventHandler(widgets[1], ButtonPressMask, False, tableSelect, NULL);
  1314.     xs = XmStringCreateSimple(" ");
  1315.     count = 0;
  1316.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1317.     XtSetArg(args[count], XmNrecomputeSize, False);  count++;
  1318.     for (each=0; each<6; each++) {
  1319.       widgets[each+2] = XmCreateLabelGadget(widgets[1], "tableLabel",
  1320.                         args, count);
  1321.     }
  1322.     XmStringFree(xs);
  1323.     XtManageChildren(widgets+2, 6);
  1324.     XtManageChild(widgets[1]);
  1325.     XtManageChild(widgets[0]);
  1326.     cur_ptr->data = (char *) widgets;
  1327.   } else {
  1328.     widgets = (Widget *) cur_ptr->data;
  1329.     XtManageChild(widgets[0]);
  1330.   }
  1331.  
  1332.   sprintf(str, "Table %d", table_pos+1);
  1333.   xs = XmStringCreateSimple(str);
  1334.   count = 0;
  1335.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1336.   XtSetValues(widgets[2], args, count);
  1337.   XmStringFree(xs);
  1338.  
  1339.   if (cur_ptr->closed) {
  1340.     xs = XmStringCreateSimple("<game over>");
  1341.     count = 0;
  1342.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1343.     XtSetValues(widgets[3], args, count);
  1344.     XmStringFree(xs);
  1345.     xs = XmStringCreateSimple(" ");
  1346.     count = 0;
  1347.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1348.     XtSetValues(widgets[4], args, count);
  1349.     XtSetValues(widgets[5], args, count);
  1350.     XtSetValues(widgets[6], args, count);
  1351.     XtSetValues(widgets[7], args, count);
  1352.     XmStringFree(xs);
  1353.   } else {
  1354.     if (!cur_ptr->hand) {
  1355.       sprintf(str, "<starting>");
  1356.     } else {
  1357.       sprintf(str, "Hand: %d  Round: %d", cur_ptr->hand, cur_ptr->round);
  1358.     }
  1359.     xs = XmStringCreateSimple(str);
  1360.     count = 0;
  1361.     XtSetArg(args[count], XmNlabelString, xs);  count++;
  1362.     XtSetValues(widgets[3], args, count);
  1363.     XmStringFree(xs);
  1364.  
  1365.     for (each=0; each<4; each++) {
  1366.       xs = XmStringCreateSimple(cur_ptr->player_name[each]);
  1367.       count = 0;
  1368.       XtSetArg(args[count], XmNlabelString, xs);  count++;
  1369.       XtSetValues(widgets[4+each], args, count);
  1370.       XmStringFree(xs);
  1371.     }
  1372.   }
  1373.  
  1374.   /* Make the row column the right width */
  1375.   count = 0;
  1376.   XtSetArg(args[count], XmNwidth,
  1377.        (width-2*marginWidth-NUM_TABLES_COLS*4-
  1378.         (NUM_TABLES_COLS-1)*spacing)/NUM_TABLES_COLS);  count++;
  1379.   XtSetValues(widgets[2], args, count);
  1380. }
  1381.  
  1382. /*
  1383.  * show_tables - display up to NUM_TABLES tables starting with table # start_id.
  1384.  */
  1385. show_tables(start_id)
  1386. int    start_id;
  1387. {
  1388.   table_ptr cur_ptr;
  1389.   int cur_id, i;
  1390.   char str[256];
  1391.   Widget *widgets;
  1392.   XmString xs;
  1393.   
  1394.   XtSetSensitive(moreGames, (table_count > 8));
  1395.   cur_ptr = first_table;
  1396.   for (i=0; i<table_count; i++) {
  1397.     if (cur_ptr->data) {
  1398.       widgets = (Widget *) cur_ptr->data;
  1399.       XtUnmanageChild(widgets[0]);
  1400.     }
  1401.     cur_ptr = cur_ptr->next_table;
  1402.   }
  1403.   if (table_count) {
  1404.     sprintf(str, "Current Games (page %d of %d):",
  1405.         (start_id + NUM_TABLES-1) / NUM_TABLES,
  1406.         (table_count + NUM_TABLES-1) / NUM_TABLES);
  1407.     xs = XmStringCreateSimple(str);
  1408.   } else {
  1409.     xs = XmStringCreateSimple("Current Games:");
  1410.   }
  1411.   count = 0;
  1412.   XtSetArg(args[count], XmNlabelString, xs);  count++;
  1413.   XtSetValues(gamesHeader, args, count);
  1414.   cur_ptr = first_table;
  1415.   for (cur_id = 1; cur_id < start_id; cur_id++) {
  1416.     cur_ptr = cur_ptr->next_table;
  1417.   }
  1418.   XtUnmanageChild(gamesRC);
  1419.   for (cur_id = 0; (cur_id < NUM_TABLES) && cur_ptr;
  1420.        cur_ptr = cur_ptr->next_table) {
  1421.     show_table(cur_ptr, cur_id++);
  1422.   }
  1423.   XtManageChild(gamesRC);
  1424. }
  1425.  
  1426. option_scan(another)
  1427. char *another;
  1428. {
  1429.   XEvent event;
  1430.  
  1431.   anotherPtr = another;
  1432.   *anotherPtr = FALSE;
  1433.   XtAppNextEvent(appContext, &event);
  1434.   XtDispatchEvent(&event);
  1435. }
  1436.  
  1437. option_init()
  1438. {
  1439.   if (distId) {
  1440.     XtRemoveInput(distId);
  1441.   }
  1442.   distId = XtAppAddInput(appContext, dist_socket,
  1443.              (XtPointer) XtInputReadMask, distInput, NULL);
  1444.   XtSetSensitive(anotherGame, !first_game);
  1445.   XtSetSensitive(newGame, first_game);
  1446.   XRaiseWindow(XtDisplay(optionForm), XtWindow(optionForm));
  1447.   XSync(XtDisplay(optionForm), False);
  1448. }
  1449.  
  1450. init_socket()
  1451. {
  1452.   if (dealerId) {
  1453.     XtRemoveInput(dealerId);
  1454.   }
  1455.   dealerId = XtAppAddInput(appContext, dealer_socket,
  1456.                (XtPointer) XtInputReadMask, dealerInput, NULL);
  1457. }
  1458.  
  1459. close_socket(s)
  1460. int s;
  1461. {
  1462.   if (s == dealer_socket && dealerId) {
  1463.     XtRemoveInput(dealerId);
  1464.     dealerId = None;
  1465.   } else if (s == dist_socket && distId) {
  1466.     XtRemoveInput(distId);
  1467.     distId = None;
  1468.   }
  1469. }
  1470.  
  1471. option_clear()
  1472. {
  1473.   table_ptr cur_ptr;
  1474.   int i;
  1475.   Widget *widgets;
  1476.  
  1477.   cur_ptr = first_table;
  1478.   for (i=0; i<table_count; i++) {
  1479.     if (cur_ptr->data) {
  1480.       widgets = (Widget *) cur_ptr->data;
  1481.       XtDestroyWidget(widgets[0]);
  1482.       cur_ptr->data = NULL;
  1483.     }
  1484.     cur_ptr = cur_ptr->next_table;
  1485.   }
  1486. }
  1487.