home *** CD-ROM | disk | FTP | other *** search
/ Freelog 45 / Freelog045.iso / Palm / Chesscli / chesscli.c next >
C/C++ Source or Header  |  2000-11-03  |  22KB  |  943 lines

  1. /***************************************************************************
  2.  
  3. Palm Chess Client
  4. Copyright (C) 1999,2000 David Barr (davidbarr@iname.com)
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or (at
  9. your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20. ****************************************************************************/
  21.  
  22. #define BOARDTOP   0   /* where on the screen to draw the board */
  23. #define USERFONTID 129 /* the fontid of the font used for messages */
  24. #define FONTHEIGHT 8   /* the height of the font used for message */
  25.  
  26. /* Main code for chesscli */
  27.  
  28. #include <PalmOS.h>
  29. #include <sys_socket.h>
  30.  
  31. #include "chesscliRsc.h"
  32.  
  33. Err errno;
  34.  
  35. WinHandle offImage=NULL;
  36. int squaresize=12; /* the size of the bitmaps in pixels */
  37. char currentline[256]; /* the text we just read from the server */
  38. char currentboard[256]; /* the last currentline that began with <12> */
  39. char initstr[256]; /* initialization commands to send to the server */
  40. int sock = -1; /* the socket number of our connection to the server */
  41. int MvTmWh=-1; /* last clock time that white moved */
  42. int MvTmBl=-1; /* last clock time that black moved */
  43. int BlToMv=-1; /* whether or not it is black's turn to move */
  44. UInt32 MvTmLast=-1; /* last system time that either side moved */
  45. int clientflip=0; /* whether or not the board is flipped on the client */
  46. int serverflip=0; /* whether or not the board is flipped on the server */
  47. /* string used to decode style 12 */
  48. static char piecelabels[] = "-PNBRQKpnbrqk";
  49. #define NSAVELINES 16
  50. char savelines[NSAVELINES][81];
  51. BitmapPtr bitmapP[7*2*2];
  52. char ReceiveBuffer[256];
  53. UInt16 currentFormId = -1;
  54.  
  55. void
  56. putstr(char *s) {
  57.   int wintop, nlines, i;
  58.   RectangleType r, v;
  59.   FormPtr frm;
  60.  
  61.   frm = FrmGetActiveForm();
  62.   
  63.   if(frm &&
  64.      frm->formId == currentFormId &&
  65.      frm->formId == BoardForm) {
  66.     nlines = (160-squaresize*8)/FONTHEIGHT;
  67.   } else {
  68.     nlines = NSAVELINES;
  69.   }
  70.  
  71.  
  72.   wintop=160-FONTHEIGHT*nlines;
  73.   
  74.   r.topLeft.x = 0;
  75.   r.topLeft.y = wintop;
  76.   r.extent.x = 160;
  77.   r.extent.y = nlines*FONTHEIGHT;
  78.  
  79.   v.topLeft.x = 0;
  80.   v.topLeft.y = wintop+(nlines-1)*FONTHEIGHT;
  81.   v.extent.x = 160;
  82.   v.extent.y = FONTHEIGHT;
  83.   
  84.   if(frm &&
  85.      frm->formId == currentFormId &&
  86.      (frm->formId == BoardForm ||
  87.       frm->formId == MessagesForm)) {
  88.     WinScrollRectangle(&r, winUp, FONTHEIGHT, &v);
  89.     WinEraseRectangle(&v, 1);
  90.     FntSetFont(USERFONTID);
  91.     WinDrawChars(s, StrLen(s), 0, wintop+(nlines-1)*FONTHEIGHT);
  92.   }
  93.   for(i=0; i<(NSAVELINES-1); i++) {
  94.     StrCopy(savelines[i], savelines[i+1]);
  95.   }
  96.   if(StrLen(s) <= 40) {
  97.     StrCopy(savelines[i], s);
  98.   } else {
  99.     StrNCopy(savelines[i], s, 40);
  100.     savelines[i][80] = '\0';
  101.     putstr(s+40);
  102.   }
  103. }
  104.  
  105. int
  106. CheckForNetwork( void ) {
  107.   Err err;
  108.   UInt16 ifErrs;
  109.   //    Word settingSize = sizeof( DWord );
  110.   //    DWord TraceNetSettings;
  111.  
  112.   if ( ( err = SysLibFind( "Net.lib", &AppNetRefnum ) ) ) {
  113.     putstr("Net.lib not found");
  114.     return 1;
  115.   }
  116.  
  117.   err = NetLibOpen( AppNetRefnum, &ifErrs );
  118.   if ( err == netErrAlreadyOpen ) {
  119.     return 0;
  120.   }
  121.  
  122.   if ( err || ifErrs ) {
  123.     putstr("NetLibOpen failed");
  124.     NetLibClose( AppNetRefnum, false );
  125.     return 2;
  126.   }
  127.  
  128.   return 0;
  129. }
  130.  
  131. struct NetSettings_s {
  132.   char host[80];
  133.   char port[80];
  134.   char user[80];
  135.   char pass[80];
  136. };
  137.  
  138. typedef struct NetSettings_s NetSettings_t;
  139. NetSettings_t NetSettings;
  140.  
  141. static DmOpenRef ccDB;
  142.  
  143. static Err
  144. OpenDatabase(void) {
  145.   UInt16        index = 0;
  146.   MemHandle     RecHandle;
  147.   MemPtr        RecPointer;
  148.   Err           err;
  149.  
  150.   /* Create database, if it doesn't exist, and save default settings status. */
  151.   if (!(ccDB = DmOpenDatabaseByTypeCreator('Data', 'CHCL', dmModeReadWrite))) {
  152.     if ((err = DmCreateDatabase(0, "ChessClientDB", 'CHCL', 'Data', false)))
  153.       return err;
  154.     ccDB = DmOpenDatabaseByTypeCreator('Data', 'CHCL', dmModeReadWrite);
  155.  
  156.     RecHandle = DmNewRecord(ccDB, &index, sizeof(NetSettings_t));
  157.     DmWrite(MemHandleLock(RecHandle), 0, &NetSettings, sizeof(NetSettings_t));
  158.     MemHandleUnlock(RecHandle);
  159.     DmReleaseRecord(ccDB, index, true);
  160.   }
  161.  
  162.   // Load a saved game status.
  163.   RecHandle = DmGetRecord(ccDB, 0);
  164.   RecPointer = MemHandleLock(RecHandle);
  165.   MemMove(&NetSettings, RecPointer, sizeof(NetSettings_t));
  166.   MemHandleUnlock(RecHandle);
  167.   DmReleaseRecord(ccDB, 0, true);
  168.  
  169.   return 0;
  170. }
  171.  
  172. /*
  173.  * Save game status information.
  174.  */
  175. static void
  176. SaveStatus() {
  177.   MemPtr p = MemHandleLock(DmGetRecord(ccDB, 0));
  178.   //game.seconds = TimGetSeconds() - GameStartedAt;
  179.   DmWrite(p, 0, &NetSettings, sizeof(NetSettings_t));
  180.   MemPtrUnlock(p);
  181.   DmReleaseRecord(ccDB, 0, true);
  182. }
  183.  
  184. void
  185. handlePenDown(int x, int y) {
  186.   static int prevr=-1, prevc=-1;
  187.   int r, c;
  188.   char move[32];
  189.   int flip;
  190.  
  191.   flip = clientflip ^ serverflip;
  192.   c = x/squaresize;
  193.   r = 7-(y-BOARDTOP)/squaresize;
  194.   if(flip) {
  195.     c = 7-c;
  196.     r = 7-r;
  197.   }
  198.   StrPrintF(move, "square = %c%d", "abcdefgh"[c], r+1);
  199.   //putstr(move);
  200.   if(c>=0&&c<=7&&r>=0&&r<=7) {
  201.     if(prevr != -1) {
  202.       StrPrintF(move, "%c%d-%c%d\n", "abcdefgh"[prevc], prevr+1,
  203.         "abcdefgh"[c], r+1);
  204.       write(sock, move, StrLen(move));
  205.       prevr=-1;
  206.       prevc=-1;
  207.     } else {
  208.       prevr = r;
  209.       prevc = c;
  210.     }
  211.   } else {
  212.     prevr=-1;
  213.     prevc=-1;
  214.   }
  215. }
  216.  
  217. static FieldPtr
  218. SetFieldTextFromHandle(FormPtr frm, UInt16 fieldID, MemHandle txtH) {
  219.   MemHandle oldTxtH;
  220.   FieldPtr fldP;
  221.   UInt16 objIdx;
  222.  
  223.   objIdx = FrmGetObjectIndex(frm, fieldID);
  224.   fldP = FrmGetObjectPtr(frm, objIdx);
  225.   oldTxtH = FldGetTextHandle(fldP);
  226.   FldSetTextHandle(fldP, txtH);
  227.   FldDrawField(fldP);
  228.   if(oldTxtH) {
  229.     MemHandleFree(oldTxtH);
  230.   }
  231.   return fldP;
  232. }
  233.  
  234. static FieldPtr
  235. SetFieldTextFromStr(FormPtr frm, UInt16 fieldID, char *strP) {
  236.   MemHandle txtH;
  237.   FieldPtr fldP;
  238.  
  239.   txtH = MemHandleNew(StrLen(strP) + 1);
  240.   if(!txtH) {
  241.     return NULL;
  242.   }
  243.   StrCopy(MemHandleLock(txtH), strP);
  244.   fldP = SetFieldTextFromHandle(frm, fieldID, txtH);
  245.   MemHandleUnlock(txtH);
  246.   return fldP;
  247. }
  248.  
  249. static void
  250. updateClocks() {
  251.   char TmWhSt[16], TmBlSt[16];
  252.   UInt32 CurrTm = TimGetSeconds();
  253.   int TmWh = MvTmWh, TmBl = MvTmBl;
  254.   FormPtr frm = FrmGetActiveForm();
  255.   int flip,min, sec, hr;
  256.  
  257.   flip = clientflip ^ serverflip;
  258.   
  259.   if(!frm ||
  260.      frm->formId != currentFormId ||
  261.      frm->formId != BoardForm) {
  262.     return;
  263.   }
  264.   if(MvTmLast == -1) {
  265.     return;
  266.   }
  267.   if(BlToMv) {
  268.     TmBl -= (CurrTm - MvTmLast);
  269.   } else {
  270.     TmWh -= (CurrTm - MvTmLast);
  271.   }
  272.  
  273.   sec=TmWh%60;
  274.   min=(TmWh/60)%60;
  275.   hr =(TmWh/(60*60));
  276.   if(hr) {
  277.     StrPrintF(TmWhSt, "%d:%02d", hr, min);
  278.   } else {
  279.     StrPrintF(TmWhSt, "%d:%02d", min, sec);
  280.   }
  281.  
  282.   sec=TmBl%60;
  283.   min=(TmBl/60)%60;
  284.   hr =(TmBl/(60*60));
  285.   if(hr) {
  286.     StrPrintF(TmBlSt, "%d:%02d", hr, min);
  287.   } else {
  288.     StrPrintF(TmBlSt, "%d:%02d", min, sec);
  289.   }
  290.   WinDrawChars(TmWhSt, StrLen(TmWhSt), 145, flip ? -1 : 7);
  291.   WinDrawChars(TmBlSt, StrLen(TmBlSt), 145, flip ? 7 : -1);
  292. }
  293.  
  294. void
  295. updateBoard(int newdata) {
  296.   char tmpstr[256];
  297.   char *fields[48], *whitename, *blackname;
  298.   int i, nfields=0, cll, j, k, labellen, row, col;
  299.   int flip;
  300.   RectangleType r;
  301.  
  302.   FormPtr frm;
  303.  
  304.   if(newdata) {
  305.     MvTmLast = TimGetSeconds();
  306.     StrCopy(currentboard, currentline);
  307.   }
  308.  
  309.   frm = FrmGetActiveForm();
  310.   
  311.   if(!frm ||
  312.      frm->formId != currentFormId ||
  313.      frm->formId != BoardForm) {
  314.     return;
  315.   }
  316.  
  317.   StrCopy(tmpstr, currentline);
  318.   cll = StrLen(tmpstr);
  319.   for(i=0; i<cll; i++) {
  320.     if(tmpstr[i] == ' ') {
  321.       fields[nfields++] = &tmpstr[i+1];
  322.       tmpstr[i] = 0;
  323.     }
  324.   }
  325.  
  326.   whitename = fields[16];
  327.   blackname = fields[17];
  328.   MvTmWh = atoi(fields[23]);
  329.   MvTmBl = atoi(fields[24]);
  330.   serverflip = atoi(fields[29]);
  331.  
  332.   flip = clientflip ^ serverflip;
  333.  
  334.   BlToMv = (fields[8][0] == 'B'); /* see who's turn it is */
  335.  
  336. /*    SetFieldTextFromStr(frm, UpPlayerLbl, flip ? whitename : blackname); */
  337. /*    SetFieldTextFromStr(frm, DownPlayerLbl, flip ? blackname : whitename); */
  338.   updateClocks();
  339.  
  340.   labellen = StrLen(piecelabels);
  341.   for(i=0; i<8; i++) {
  342.     row = i;
  343.     if(flip) {
  344.       row = 7-row;
  345.     }
  346.     for(j=0; j<8; j++) {
  347.       col = j;
  348.       if(flip) {
  349.     col = 7-col;
  350.       }
  351.       for(k=0; k<labellen; k++) {
  352.     if(fields[i][j] == piecelabels[k]) {
  353.       break;
  354.     }
  355.       } /* end for k */
  356.       if((i+j)%2) {
  357.     //bmpno++;
  358.       }
  359.       //saveno = (pieceside*7+piecetype)*2+background;
  360.       r.topLeft.x=0;
  361.       r.topLeft.y=0;
  362.       if(k>=7) {
  363.     r.topLeft.y += (squaresize*2);
  364.     k-=6;
  365.       }
  366.       r.topLeft.y += (((i+j+k+1)%2)*squaresize);
  367.       r.topLeft.x=k*squaresize;
  368.       r.extent.x=squaresize;
  369.       r.extent.y=squaresize;
  370.       WinCopyRectangle(offImage, WinGetActiveWindow(), &r,
  371.                col*squaresize, row*squaresize+BOARDTOP, winPaint);
  372.  
  373.       //WinDrawBitmap (bitmapP[k*2+((i+j)%2)], col*SQUARESIZE,
  374.       //row*SQUARESIZE+BOARDTOP);
  375.     } /* end for j */
  376.   } /* end for i */
  377. } /* end updateBoard */
  378.  
  379. void
  380. loadbitmap(int size, int bmpno) {
  381.   WinHandle tmpHandle, tmpHandle2;
  382.   Err err;
  383.   MemHandle bitmapHandle;
  384.   int oldsize;
  385.   RectangleType r;
  386.  
  387.   oldsize=squaresize;
  388.   squaresize=size;
  389.  
  390.   if(offImage) {
  391.     WinDeleteWindow(offImage, false);
  392.   }
  393.   
  394.   tmpHandle2 = WinGetDrawWindow();
  395.   offImage=WinCreateOffscreenWindow(squaresize*7, squaresize*4,
  396.                     screenFormat, &err);
  397.   tmpHandle = WinSetDrawWindow(offImage);
  398.   bitmapHandle = DmGetResource('Tbmp',bmpno);
  399.   WinDrawBitmap(MemHandleLock(bitmapHandle),0,0);
  400.   MemHandleUnlock(bitmapHandle);
  401.   WinSetDrawWindow(tmpHandle2);
  402.  
  403.   if(StrLen(currentboard)) {
  404.     StrCopy(currentline, currentboard);
  405.   } else {
  406.     StrCopy(currentline,
  407.         "<12> rnbqkbnr pppppppp -------- -------- -------- -------- "
  408.         "PPPPPPPP RNBQKBNR W -1 0 0 1 1 0 7 White Black 1 2 12 39 39 "
  409.         "119 122 2 null (0:06) null 0");
  410.   }
  411.  
  412.   if(currentFormId == BoardForm) {
  413.     r.topLeft.x=0;
  414.     r.topLeft.y=0;
  415.     r.extent.x=oldsize*8;
  416.     r.extent.y=oldsize*8;
  417.     WinEraseRectangle(&r, 1);
  418.   }
  419.   updateBoard(0);
  420. }
  421.  
  422. static Boolean
  423. BoardFormHandleEvent (EventPtr e) {
  424.   Boolean handled = false;
  425.   FormPtr frm;
  426.   int wintop, i, lines;
  427.     
  428.   switch (e->eType) {
  429.   case frmOpenEvent:
  430.     frm = FrmGetActiveForm();
  431.     FrmDrawForm(frm);
  432.     currentFormId=frm->formId;
  433.     if(StrLen(currentboard)) {
  434.       StrCopy(currentline, currentboard);
  435.     } else {
  436.       StrCopy(currentline,
  437.           "<12> rnbqkbnr pppppppp -------- -------- -------- -------- "
  438.           "PPPPPPPP RNBQKBNR W -1 0 0 1 1 0 7 White Black 1 2 12 39 39 "
  439.           "119 122 2 null (0:06) null 0");
  440.     }
  441.     updateBoard(0);
  442.     lines = (160-squaresize*8)/FONTHEIGHT;
  443.     wintop=160-FONTHEIGHT*lines;
  444.     FntSetFont(USERFONTID);
  445.     for(i=0; i<lines; i++) {
  446.       WinDrawChars(savelines[NSAVELINES-lines+i],
  447.            StrLen(savelines[NSAVELINES-lines+i]), 0,
  448.            wintop+i*FONTHEIGHT);
  449.     }
  450.     handled = true;
  451.     break;
  452.  
  453.   case menuEvent:
  454.     MenuEraseStatus ((MenuBarPtr) MenuGetActiveMenu());
  455.  
  456.     switch(e->data.menu.itemID) {
  457.     case HelpMenuAbout:
  458.       FrmPopupForm(AboutForm);
  459.       break;
  460.     case OptMenu12:
  461.       loadbitmap(12, PieceBmp12);
  462.       break;
  463.     case OptMenu16:
  464.       loadbitmap(16, PieceBmp16);
  465.       break;
  466.     case OptMenu18:
  467.       loadbitmap(18, PieceBmp18);
  468.       break;
  469.     }
  470.  
  471.     handled = true;
  472.     break;
  473.  
  474.   case ctlSelectEvent:
  475.     switch(e->data.ctlSelect.controlID) {
  476.     case ToMessagesBtn:
  477.       currentFormId = -1;
  478.       FrmGotoForm(MessagesForm);
  479.       break;
  480.     case ToLoginBtn:
  481.       currentFormId = -1;
  482.       FrmGotoForm(LoginForm);
  483.       break;
  484.     }
  485.     break;
  486.  
  487.   case nilEvent:
  488.     break;
  489.  
  490.   case penDownEvent:
  491.     handlePenDown(e->screenX, e->screenY);
  492.     break;
  493.  
  494.   case penUpEvent:
  495.     break;
  496.  
  497.   case penMoveEvent:
  498.     break;
  499.  
  500.   case ctlEnterEvent:
  501.     break;
  502.  
  503.   default:
  504.     //StrPrintF(debugstr, "main form event type = %d", e->eType);
  505.     //putstr(debugstr);  /* 0 1 2 7 9 */
  506.     break;
  507.   }
  508.  
  509.   return handled;
  510. }
  511.  
  512. static struct in_addr *
  513. atoaddr(char *address) {
  514.   struct hostent *host;
  515.   static struct in_addr saddr;
  516.  
  517.   /* First try it as aaa.bbb.ccc.ddd. */
  518.   saddr.s_addr = inet_addr(address);
  519.   if (saddr.s_addr != -1) {
  520.     return &saddr;
  521.   }
  522.   host = gethostbyname(address);
  523.   if (host != NULL) {
  524.     return (struct in_addr *) *host->h_addr_list;
  525.   }
  526.   return NULL;
  527. }
  528.  
  529. static Boolean
  530. LoginFormHandleEvent (EventPtr e) {
  531.   Boolean handled = false;
  532.   static FormPtr frm;
  533.   char *serverPtr, *portPtr, *userPtr, *passPtr, nullStr[1];
  534.   struct sockaddr_in address;
  535.   struct in_addr *addr;
  536.     
  537.   switch (e->eType) {
  538.   case frmOpenEvent:
  539.     frm = FrmGetActiveForm();
  540.     FrmDrawForm(frm);
  541.     currentFormId = frm->formId;
  542.     SetFieldTextFromStr(frm, ServerFld, NetSettings.host);
  543.     SetFieldTextFromStr(frm, PortFld, NetSettings.port);
  544.     SetFieldTextFromStr(frm, UserFld, NetSettings.user);
  545.     SetFieldTextFromStr(frm, PassFld, NetSettings.pass);
  546.     handled = true;
  547.     break;
  548.  
  549.   case menuEvent:
  550.     MenuEraseStatus(NULL);
  551.  
  552.     switch(e->data.menu.itemID) {
  553.     }
  554.  
  555.     handled = true;
  556.     break;
  557.  
  558.   case ctlSelectEvent:
  559.     switch(e->data.ctlSelect.controlID) {
  560.     case ConnectBtn:
  561.       StrCopy(nullStr, "");
  562.       serverPtr = FldGetTextPtr(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, ServerFld)));
  563.       portPtr   = FldGetTextPtr(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, PortFld)));
  564.       userPtr   = FldGetTextPtr(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, UserFld)));
  565.       passPtr   = FldGetTextPtr(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, PassFld)));
  566.       if(!serverPtr) { serverPtr = nullStr; }
  567.       if(!portPtr)   { portPtr = nullStr; }
  568.       if(!userPtr)   { userPtr = nullStr; }
  569.       if(!passPtr)   { passPtr = nullStr; }
  570.       StrCopy(NetSettings.host, serverPtr);
  571.       StrCopy(NetSettings.port, portPtr);
  572.       StrCopy(NetSettings.user, userPtr);
  573.       StrCopy(NetSettings.pass, passPtr);
  574.       
  575.       sock = socket(AF_INET, SOCK_STREAM, 0);
  576.       memset((char *) &address, 0, sizeof(address));
  577.       addr = atoaddr(serverPtr);
  578.       address.sin_family = AF_INET;
  579.       address.sin_port = atoi(portPtr);
  580.       address.sin_addr.s_addr = addr->s_addr;
  581.       connect(sock, (struct sockaddr *) &address, sizeof(address));
  582.       StrCopy(currentline, "");
  583.       StrPrintF(initstr, "%s\n%s\nset style 12\n", userPtr, passPtr);
  584.       currentFormId = -1;
  585.       FrmGotoForm(BoardForm);
  586.     }
  587.     break;
  588.  
  589.   case nilEvent:
  590.     break;
  591.  
  592.   case penDownEvent:
  593.     break;
  594.  
  595.   case penUpEvent:
  596.     break;
  597.  
  598.   case ctlEnterEvent:
  599.     break;
  600.  
  601.   case keyDownEvent:
  602.     break;
  603.  
  604.   default:
  605.     break;
  606.   }
  607.  
  608.   return handled;
  609. }
  610.  
  611. static Boolean
  612. MessagesFormHandleEvent (EventPtr e) {
  613.   Boolean handled = false;
  614.   FormPtr frm;
  615.   int wintop, i;
  616.     
  617.   switch (e->eType) {
  618.   case frmOpenEvent:
  619.     frm = FrmGetActiveForm();
  620.     FrmDrawForm(frm);
  621.     currentFormId=frm->formId;
  622.     wintop=160-FONTHEIGHT*NSAVELINES;
  623.     FntSetFont(USERFONTID);
  624.     for(i=0; i<NSAVELINES; i++) {
  625.       WinDrawChars(savelines[i], StrLen(savelines[i]), 0,
  626.            wintop+(i)*FONTHEIGHT);
  627.     }
  628.     handled = true;
  629.     break;
  630.  
  631.   case menuEvent:
  632.     MenuEraseStatus(NULL);
  633.  
  634.     switch(e->data.menu.itemID) {
  635.     }
  636.  
  637.     handled = true;
  638.     break;
  639.  
  640.   case ctlSelectEvent:
  641.     switch(e->data.ctlSelect.controlID) {
  642.     case ToBoardBtn:
  643.       currentFormId = -1;
  644.       FrmGotoForm(BoardForm);
  645.     }
  646.     break;
  647.  
  648.   case nilEvent:
  649.     break;
  650.  
  651.   case penDownEvent:
  652.     break;
  653.  
  654.   case penUpEvent:
  655.     break;
  656.  
  657.   case ctlEnterEvent:
  658.     break;
  659.  
  660.   case keyDownEvent:
  661.     if (e->data.keyDown.chr == '\n') {
  662.       UInt16 focus;
  663.       FormPtr frm;
  664.       FieldPtr fld;
  665.     
  666.       frm = FrmGetActiveForm ();
  667.       focus = FrmGetFocus (frm);
  668.       fld = FrmGetObjectPtr(frm, focus);
  669.     
  670.       StrPrintF(currentline, "%s\n", FldGetTextPtr(fld));
  671.      
  672.       write(sock, currentline, StrLen(currentline));
  673.       handled = true;
  674.     }
  675.     break;
  676.  
  677.   default:
  678.     //StrPrintF(debugstr, "main form event type = %d", e->eType);
  679.     //putstr(debugstr);  /* 0 1 2 7 9 */
  680.     break;
  681.   }
  682.  
  683.   return handled;
  684. }
  685.  
  686. static Boolean
  687. AboutFormHandleEvent (EventPtr e) {
  688.   Boolean handled = false;
  689.   FormPtr frm;
  690.   //  int wintop, i;
  691.     
  692.   switch (e->eType) {
  693.   case frmOpenEvent:
  694.     frm = FrmGetActiveForm();
  695.     FrmDrawForm(frm);
  696.     currentFormId = frm->formId;
  697.     handled = true;
  698.     break;
  699.   case ctlSelectEvent:
  700.     if (e->data.ctlSelect.controlID == FormAboutButton) {
  701.       FrmReturnToForm(0);
  702.       handled = true; 
  703.       break;
  704.     }
  705.     break;
  706.   default:
  707.     break;
  708.   }
  709.  
  710.   return handled;
  711. }
  712.  
  713. void
  714. mydebug(int lineno) {
  715.   // do nothing
  716. }
  717.  
  718. static Boolean
  719. ApplicationHandleLine() {
  720.   int i;
  721.   
  722.   //StrCopy(debugstr, currentline);
  723.   //mydebug(__LINE__);
  724.   for(i=0; i<5; i++) {
  725.     if("<12> "[i] != currentline[i]) {
  726.       break;
  727.     }
  728.   }
  729.   if(i==5) {
  730.     updateBoard(1);
  731.   } else {
  732.     putstr(currentline);
  733.   }
  734.   return true;
  735. }
  736.  
  737. static Boolean
  738. ApplicationHandleData() {
  739.   Err i;
  740.   int cll, j;
  741.   static int sentinitstr=0;
  742.  
  743.   if(!sentinitstr) {
  744.     write(sock, initstr, StrLen(initstr));
  745.     sentinitstr=1;
  746.   }
  747.  
  748.   //printf("trying ReceiveData...\n");
  749.   cll = StrLen(currentline);
  750.   if(cll == 255) {
  751.     StrCopy(currentline, "");
  752.     cll = 0;
  753.   }
  754.   i = read(sock, ReceiveBuffer, sizeof(ReceiveBuffer));
  755.   if(!i) {
  756.     //StrCopy(debugstr, "remote side closed connection\n");
  757.     //mydebug(__LINE__);
  758.     close(sock);
  759.     sock = -1;
  760.   } else if(i == -1) {
  761.     StrPrintF(ReceiveBuffer, "NetLibReceive error = 0x%04x", errno);
  762.     putstr(ReceiveBuffer);
  763.     i=0;
  764.   }
  765.   for(j=0; j<i; j++) {
  766.     if(ReceiveBuffer[j] == '\n' || ReceiveBuffer[j] == '\r') {
  767.       if(cll) {
  768.     ApplicationHandleLine();
  769.     StrCopy(currentline, "");
  770.     cll = 0;
  771.       }
  772.       continue;
  773.     }
  774.     currentline[cll++] = ReceiveBuffer[j];
  775.     currentline[cll] = 0;
  776.   }
  777.   return true;
  778. }
  779.   
  780.  
  781. static Boolean
  782. ApplicationHandleEvent(EventPtr e) {
  783.   FormPtr frm;
  784.   UInt16    formId;
  785.   Boolean handled = false;
  786.  
  787.   if (e->eType == frmLoadEvent) {
  788.     formId = e->data.frmLoad.formID;
  789.     frm = FrmInitForm(formId);
  790.     FrmSetActiveForm(frm);
  791.     switch(formId) {
  792.     case BoardForm:
  793.       FrmSetEventHandler(frm, BoardFormHandleEvent);
  794.       break;
  795.     case MessagesForm:
  796.       FrmSetEventHandler(frm, MessagesFormHandleEvent);
  797.       break;
  798.     case LoginForm:
  799.       FrmSetEventHandler(frm, LoginFormHandleEvent);
  800.       break;
  801.     case AboutForm:
  802.       FrmSetEventHandler(frm, AboutFormHandleEvent);
  803.       break;
  804.     }
  805.     handled = true;
  806.     
  807.     //printf("all done\n");
  808.   }
  809.  
  810.   return handled;
  811. }
  812.  
  813. /* Get preferences, open (or create) app database */
  814. static UInt16
  815. StartApplication(void) {
  816.   MemHandle fontHandle;
  817.   FontType *fontPtr;
  818.   int i;
  819.   char tmpstr[64];
  820.  
  821.   loadbitmap(12, PieceBmp12);
  822.  
  823.   for(i=0; i<NSAVELINES; i++) {
  824.     savelines[i][0] = '\0';
  825.   }
  826.  
  827.   putstr("trying CheckForNetwork...");
  828.   if((i=CheckForNetwork())) {
  829.     StrPrintF(tmpstr, "checkfornetwork failed (%d)", i);
  830.     putstr(tmpstr);
  831.   }
  832.   
  833.   // 'Font' and 0x3000 are resource type and ID, defined by you in
  834.   // resource description
  835.   fontHandle=DmGetResource('Font',0x3000); // minico 9
  836.   fontPtr=MemHandleLock(fontHandle);
  837.   // user defined fonts start from 129
  838.   FntDefineFont(USERFONTID,fontPtr);
  839.  
  840.   OpenDatabase();
  841.  
  842.   currentFormId = -1;
  843.   FrmGotoForm(LoginForm);
  844.   return 0;
  845. }
  846.  
  847. /* Save preferences, close forms, close app database */
  848. static void
  849. StopApplication(void) {
  850.   MemHandle fontHandle;
  851.  
  852.   FrmSaveAllForms();
  853.   FrmCloseAllForms();
  854.  
  855.   // unlock our font handle
  856.   fontHandle=DmGetResource('Font',0x3000);
  857.   MemHandleUnlock(fontHandle);
  858.  
  859.   // unlock the piece bitmaps
  860.   if(offImage) {
  861.     WinDeleteWindow(offImage, false);
  862.   }
  863.  
  864.   if(sock != -1) {
  865.     close(sock);
  866.   }
  867.  
  868.   NetLibClose(AppNetRefnum, false);
  869.   SaveStatus();
  870. }
  871.  
  872. /* The main event loop */
  873. static void
  874. EventLoop(void) {
  875.   UInt16 err;
  876.   EventType e;
  877.   NetFDSetType readFDs,writeFDs,exceptFDs, setsize=1;
  878.  
  879.   StrCopy(currentboard, "");
  880.   
  881.   for(;;) {
  882.     netFDZero(&readFDs);
  883.     setsize = 1;
  884.     netFDSet(sysFileDescStdIn, &readFDs);
  885.     setsize = sysFileDescStdIn+1;
  886.     if(sock != (UInt16)-1) {
  887.       netFDSet(sock, &readFDs);
  888.       if(sock >= setsize) {
  889.     setsize = sock+1;
  890.       }
  891.       NetLibSelect(AppNetRefnum, setsize, &readFDs, &writeFDs, &exceptFDs,
  892.            sysTicksPerSecond, &err);
  893.       if(netFDIsSet(sock, &readFDs)) {
  894.     ApplicationHandleData();
  895.       }
  896.       /*        if(!netFDIsSet(sysFileDescStdIn, &readFDs)) { */
  897.       /*      continue; */
  898.       /*        } */
  899.     }
  900.  
  901.     //EvtGetEvent(&e, evtWaitForever);
  902.     EvtGetEvent(&e, 0);
  903.     
  904.     //printf("event = %d\n", e.eType);
  905.     if (SysHandleEvent (&e)) {
  906.       continue;
  907.     }
  908.     if (MenuHandleEvent (NULL, &e, &err)) {
  909.       continue;
  910.     }
  911.     if (ApplicationHandleEvent (&e)) {
  912.       continue;
  913.     }
  914.     
  915.     FrmDispatchEvent (&e);
  916.     
  917.     if(e.eType == appStopEvent) {
  918.       return;
  919.     }
  920.     
  921.     updateClocks();
  922.   }
  923. }
  924.  
  925. UInt32
  926. PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags) {
  927.   UInt16 err;
  928.  
  929.   if (cmd == sysAppLaunchCmdNormalLaunch) {
  930.     err = StartApplication();
  931.     if (err) {
  932.       return err;
  933.     }
  934.  
  935.     EventLoop();
  936.     StopApplication();
  937.   } else {
  938.     return sysErrParamErr;
  939.   }
  940.  
  941.   return 0;
  942. }
  943.