home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 092.lha / JayCalc / JayCalc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-21  |  27.7 KB  |  1,088 lines

  1. /************************************************************************
  2. **************************************************************************
  3. **                                                                      **
  4. **  JayCalc.c                                                           **
  5. **  ---------                                                           **
  6. **                                                                      **
  7. **  Auteur : Eric Le Saux                                               **
  8. **                                                                      **
  9. **           Club Amiga Montreal (CAM)                                  **
  10. **           C.P. 195 STATION "N"                                       **
  11. **           Montreal (Quebec)                                          **
  12. **           H2X 3M2, CANADA                                            **
  13. **                                                                      **
  14. **  Date   : 20 decembre 1987                                           **
  15. **                                                                      **
  16. **  Statut : DOMAINE PUBLIC - Distribution non-commerciale seulement    **
  17. **           PUBLIC DOMAIN  - Freely redistributable                    **
  18. **                                                                      **
  19. **************************************************************************
  20.  ************************************************************************/
  21.  
  22. /*** Fichiers d'entetes *************************************************/
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <intuition/intuition.h>
  27. #include <libraries/dos.h>
  28. #include <JayCalc.h>
  29.  
  30. /*** Fonctions et variables externes ************************************/
  31.  
  32. extern struct Library        *OpenLibrary ();
  33. extern struct TextFont        *OpenFont    ();
  34. extern struct Window        *OpenWindow  ();
  35. extern struct IntuiMessage    *GetMsg ();
  36.  
  37. extern int Enable_Abort;
  38.  
  39. /*** Variables globales pour le maintient du systeme ********************/
  40.  
  41. struct IntuitionBase     *IntuitionBase;
  42. struct GfxBase           *GfxBase;
  43.  
  44. struct Window         *Fenetre;
  45.  
  46. struct RastPort        *RP;
  47.  
  48. struct TextAttr      FonteAttr = { (UBYTE *) "topaz.font", 8, 0, 0 };
  49. struct TextFont     *Fonte;
  50.  
  51. /*** Variables globales pour la logique du programme ********************/
  52.  
  53. #define HEX 0
  54. #define DEC 1
  55. UBYTE ModeControle  = HEX;    /* Mode HEXadecimal ou DECimal */
  56.  
  57. UBYTE LFControlByte = 0;    /* Valeur de la byte de ctrl du Blitter */
  58.  
  59. UBYTE RegionsAllumees = 0;    /* Regions du diag. de Venn allumees */
  60.  
  61. UBYTE TempBuff[EQUBUFFLEN];    /* Buffer temporaire */
  62.  
  63. BOOL Parasites = TRUE;        /* Quand l'affichage est corrompu. */
  64.  
  65. BOOL ParErr = FALSE;        /* Erreurs de parentheses ? */
  66.  
  67. BOOL Insertion = FALSE;        /* TRUE : le Keypad insere a BufferPos  */
  68.                             /* FALSE: on ecrit a la fin de la ligne */
  69.  
  70. /*************************************************************************
  71. **************************************************************************
  72. **
  73. **  EvalueEquation ()
  74. **
  75. **  Traverse une string contenant l'equation logique a evaluer.
  76. **  Les symboles errones sont ignores.
  77. **
  78. **  Les OR excessifs sont elimines, ainsi que les symboles redondants
  79. **  dans les operations AND.
  80. **
  81. **  Les touches du keypad arrivent une par une.  Comme les OR ne sont
  82. **  pas permis en fin d'equation, ils sont elimines.  Le booleen NOR
  83. **  est TRUE quand on veut eliminer ce symbole en fin de ligne.
  84. **
  85. */
  86.  
  87.  
  88. UBYTE EvalueEquation (EquPtr, CorrPtr, NOR)
  89. UBYTE *EquPtr;
  90. UBYTE *CorrPtr;
  91. BOOL   NOR;
  92. {
  93.     UBYTE  LF = 0x00;    /* Element neutre pour OR  */
  94.     UBYTE  AndByte = 0xFF;    /* Element neutre pour AND */
  95.  
  96.     UBYTE  SousEqu[EQUBUFFLEN];  /* Pour l'appel recursif */
  97.     UBYTE  SousCorr[EQUBUFFLEN]; /* Pour l'appel recursif */
  98.     UBYTE  *SEPtr;               /* Pointe dans SousEqu   */
  99.     UBYTE  NbParOuv;         /* Nb de parentheses ouvertes */
  100.  
  101.     UBYTE  Symboles = 0x00;    /* Masques des symboles du AND courant */
  102.     UBYTE  SymbMasque;    /* Masque pour le symbole */
  103.     UBYTE  SymbVal;        /* Valeur du symbole considere */
  104.  
  105.     BOOL   Valide = FALSE;    /* Devient TRUE au premier caractere reconnu */
  106.  
  107.     ParErr = FALSE;        /* Devient TRUE aux erreurs de parentheses */
  108.  
  109.       /*=== Conversion avec correction ===*/
  110.  
  111.     while (*CorrPtr++ = *EquPtr)
  112.     {
  113.  
  114.        switch (*EquPtr++)
  115.        {
  116.           case KeyA_ID  : SymbVal = 0xF0; SymbMasque = 0x01; break;
  117.           case KeyNA_ID : SymbVal = 0x0F; SymbMasque = 0x02; break;
  118.           case KeyB_ID  : SymbVal = 0xCC; SymbMasque = 0x04; break;
  119.           case KeyNB_ID : SymbVal = 0x33; SymbMasque = 0x08; break;
  120.           case KeyC_ID  : SymbVal = 0xAA; SymbMasque = 0x10; break;
  121.           case KeyNC_ID : SymbVal = 0x55; SymbMasque = 0x20; break;
  122.           case ParFer_ID: CorrPtr--;
  123.                           continue;
  124.  
  125.           case ParOuv_ID: SymbMasque = 0x00;
  126.  
  127.                         /*=== Copie de string entre () de meme niveau ===*/
  128.  
  129.                           SEPtr = SousEqu;
  130.                           NbParOuv = 1;
  131.                           FOREVER
  132.                           {
  133.                              *SEPtr = *EquPtr++;
  134.                              if (*SEPtr == '\0') break;
  135.                              if (*SEPtr == ParOuv_ID) NbParOuv++;
  136.                              if (*SEPtr == ParFer_ID)
  137.                              {
  138.                                 NbParOuv--;
  139.                                 if (NbParOuv==0) break;
  140.                              }
  141.                              SEPtr++;
  142.                           }
  143.  
  144.                         /*=== On recure si le dernier car est ParFer_ID ===*/
  145.  
  146.                           if (*SEPtr == ParFer_ID)
  147.                           {
  148.                              *SEPtr = '\0';
  149.                              SymbVal = EvalueEquation (SousEqu,SousCorr,NOR);
  150.  
  151.                              /* Erreur ? Alors on sort ! */
  152.                              if (ParErr) return 0;
  153.  
  154.                              SEPtr = SousCorr;
  155.                              while (*CorrPtr++ = *SEPtr++);
  156.                              *(CorrPtr-1) = ParFer_ID;
  157.                              *CorrPtr = '\0';
  158.                           }
  159.                           else /*=== Sinon c'est une erreur ===*/
  160.                           {
  161.                              ParErr = TRUE;
  162.                              return 0;
  163.                           }
  164.                           break;
  165.  
  166.           case KeyOR_ID : if (AndByte != 0xFF)
  167.                           {
  168.                              LF |= AndByte;
  169.                              AndByte = 0xFF;
  170.                              Symboles= 0x00;
  171.                           }
  172.                           else /*=== OU excedentaire ===*/
  173.                           {
  174.                              CorrPtr--;
  175.                           }
  176.                           continue;
  177.  
  178.           default       : CorrPtr--; /*=== Symbole non-reconnu ===*/
  179.                           continue;
  180.  
  181.        } /* SWITCH */
  182.  
  183.        if (Symboles & SymbMasque)
  184.        {
  185.           CorrPtr--;
  186.           continue;
  187.        }
  188.        else
  189.        {
  190.           Symboles |= SymbMasque;
  191.           AndByte  &= SymbVal;
  192.        }
  193.  
  194.        if (AndByte != 0xFF) Valide = TRUE; /*= Au moins 1 bon element =*/
  195.  
  196.  
  197.     } /* WHILE */
  198.  
  199.  
  200.       /*=== On elimine le OR excendentaire, s'il y en a. ===*/
  201.  
  202.     if ( (*(CorrPtr-2)==KeyOR_ID) && NOR ) *(CorrPtr-2) = '\0';
  203.  
  204.       /*=== Si l'equation n'est pas valide, on remet tout a zero. ===*/
  205.  
  206.     if (!Valide)
  207.     {
  208.        LF = 0;
  209.        AndByte = 0;
  210.     }
  211.  
  212.       /*=== Si la AndByte == 0xFF, le dernier caractere est un OR. ===*/
  213.  
  214.     if (AndByte == 0xFF) return (LF);
  215.                     else return (LF |= AndByte);
  216. }
  217.  
  218.  
  219. /*************************************************************************
  220. **************************************************************************
  221. **
  222. **  ModifieStringGadget ()
  223. **
  224. **  Modifie le buffer d'un string gadget.
  225. **
  226. **
  227. **  Que les paroles de -=RJ=- nous impregnent :
  228. **
  229. **  "Note that to modify the imagery of a gadget, you must first remove
  230. **   that gadget from the Window's Gadget list, using RemoveGadget() (or
  231. **   RemoveGList()).  After changing the Image, Border, Text (including
  232. **   Text for a String Gadget), the gadget is replaced in the Gadget List
  233. **   (using AddGadget() or AddGList()).  Adding gadgets does not cause
  234. **   them to be displayed (refreshed), so this function, or RefreshGList()
  235. **   is typically called."
  236. **
  237. **  Le premier argument pointe au StringGadget a modifier.
  238. **  Le deuxieme a la nouvelle valeur du string gadget.
  239. **  Le troisieme argument specifie le type de cadrage desire lorsque
  240. **  le buffer depasse la capacite d'affichage.  Lorsque le buffer peut
  241. **  etre completement affiche, on centre.
  242. **  CurPos est la nouvelle position du curseur dans le buffer.
  243. **
  244. */
  245.  
  246. void ModifieStringGadget (SGadget, SrcPtr, Droite, CurPos)
  247. struct Gadget *SGadget;
  248. UBYTE *SrcPtr;
  249. BOOL  Droite;
  250. SHORT CurPos;
  251. {
  252.     STATIC USHORT PositionGadg; /* Position dans la liste des gadgets */
  253.     STATIC UBYTE  *DestPtr;        /* Pointe a son buffer */
  254.     STATIC SHORT  BufLen;        /* Longueur du nouveau buffer */
  255.  
  256.     STATIC struct StringInfo *S;/* Pointeur au StringInfo du Gadget */
  257.  
  258.       /*=== On note l'adresse de la struture StringInfo ===*/
  259.  
  260.     S = (struct StringInfo *)SGadget->SpecialInfo;
  261.  
  262.       /*=== On enleve le gadget ===*/
  263.  
  264.     PositionGadg = RemoveGadget (Fenetre, SGadget);
  265.  
  266.       /*=== On modifie son buffer ===*/
  267.  
  268.     BufLen = 0;
  269.     DestPtr = S->Buffer;
  270.     while (*DestPtr++ = *SrcPtr++) BufLen++;
  271.  
  272.       /*=== Choix du cadrage ===*/
  273.  
  274.     SGadget->Activation &= ~(STRINGCENTER|STRINGRIGHT);
  275.     if (BufLen<S->DispCount)
  276.     {
  277.        SGadget->Activation |= STRINGCENTER;
  278.        S->DispPos = -1;
  279.     }
  280.     else if (Droite)
  281.     {
  282.        SGadget->Activation |= STRINGRIGHT;
  283.        S->DispPos = BufLen-S->DispCount;
  284.     }
  285.     else
  286.     {
  287.        S->DispPos = 0;
  288.     }
  289.  
  290.     S->BufferPos = CurPos;
  291.  
  292.       /*=== On replace le gadget ===*/
  293.  
  294.     AddGadget (Fenetre, SGadget, (ULONG) PositionGadg);
  295.     RefreshGList (SGadget, Fenetre, NULL, 1L);
  296. }
  297.  
  298.  
  299.  
  300. /*************************************************************************
  301. **************************************************************************
  302. **
  303. **  Scroll ()
  304. **
  305. **  Deplace l'equation a droite ou a gauche.
  306. **
  307. */
  308.  
  309. void Scroll (Cote)
  310. UBYTE Cote;
  311. {
  312.     STATIC USHORT Position;
  313.     struct StringInfo *S = (struct StringInfo *) EquGadg.SpecialInfo;
  314.  
  315.     if (!(EquGadg.Activation & STRINGCENTER))
  316.     {
  317.        /*=== On peut inserer ===*/
  318.  
  319.           Insertion = TRUE;
  320.  
  321.        /*=== On enleve le string gadget ===*/
  322.  
  323.           Position = RemoveGadget (Fenetre, &EquGadg);
  324.  
  325.        /*=== On scroll ===*/
  326.  
  327.           if ( (Cote == ScrolG_ID) && (S->DispPos > 0) )
  328.           {
  329.              S->DispPos--;
  330.              S->BufferPos--;
  331.           }
  332.  
  333.           if ( (Cote == ScrolD_ID) && ( (S->DispPos+S->DispCount) <= S->NumChars ) )
  334.           {
  335.              S->DispPos++;
  336.              S->BufferPos++;
  337.           }
  338.  
  339.        /*=== On replace le gadget ===*/
  340.  
  341.           AddGadget (Fenetre, &EquGadg, (ULONG) Position);
  342.           RefreshGList (&EquGadg, Fenetre, NULL, 1L);
  343.           ActivateGadget (&EquGadg, Fenetre, NULL);
  344.     }
  345. }
  346.  
  347.  
  348.  
  349. /*************************************************************************
  350. **************************************************************************
  351. **
  352. **  AfficheVenn ()
  353. **
  354. **  Colore le diagramme de Venn selon le code LF courant:
  355. **
  356. **        bit 0 : abc     bit 4 : Abc
  357. **        bit 1 : abC     bit 5 : AbC
  358. **        bit 2 : aBc     bit 6 : ABc
  359. **        bit 3 : aBC     bit 7 : ABC
  360. **
  361. **  Par question d'efficacite, l'etat des regions est change directement
  362. **  a l'aide d'une operation du blitter, plutot que par la modification
  363. **  de la liste de gadgets du diagramme de Venn.
  364. **
  365. **  NOTE: le champ 'UserData' des gadgets pointe aux bitmaps qui les
  366. **        representent.
  367. **
  368. */
  369.  
  370. void AfficheVenn ()
  371. {
  372.     STATIC SHORT Index;
  373.  
  374.     struct Gadget *Liste = &VennGadgList;    /* Pour traverser les gadgets */
  375.     UBYTE  LF = LFControlByte;        /* Pour analyser ses bits */
  376.     UBYTE  RA = RegionsAllumees;        /* Pour analyser ses bits */
  377.  
  378.     for (Index=0; Index<8; Index++)
  379.     {
  380.        if ( (LF & 0x01)^(RA & 0x01) ) 
  381.           BltBitMapRastPort
  382.           (
  383.            Liste->UserData,            /* BitMap source */
  384.            0L, 0L,                /* SrcX, SrcY */
  385.            Fenetre->RPort,            /* BitMap destination */
  386.            (LONG)(Liste->LeftEdge),        /* DestX */
  387.            (LONG)(Liste->TopEdge),        /* DestY */
  388.            (LONG)(Liste->Width),        /* Nb Pixels en X */
  389.                (LONG)(Liste->Height),        /* Nb Pixels en Y */
  390.            (LONG)0x66            /* Minterms: B^C */
  391.           );
  392.  
  393.        LF >>= 1;
  394.        RA >>= 1;
  395.  
  396.        Liste = Liste->NextGadget;        /* Au suivant ! */
  397.     }
  398.  
  399.       /*=== Les regions allumees correspondent maintenant au code LF ===*/
  400.  
  401.     RegionsAllumees = LFControlByte;
  402. }
  403.  
  404.  
  405.  
  406. /*************************************************************************
  407. **************************************************************************
  408. **
  409. **  Normalise ()
  410. **
  411. **  Affiche l'equation normalisee de la LFControlByte courante.
  412. **
  413. */
  414.  
  415. UBYTE *MinTermes[8] = {(UBYTE *)"abc", (UBYTE *)"abC", (UBYTE *)"aBc",
  416.                    (UBYTE *)"aBC", (UBYTE *)"Abc", (UBYTE *)"AbC",
  417.                    (UBYTE *)"ABc", (UBYTE *)"ABC"};
  418.  
  419. void Normalise ()
  420. {
  421.     STATIC SHORT Index;
  422.     STATIC UBYTE *Dest, *MinPtr;
  423.  
  424.       /*=== Il n'y a plus d'erreur de parentheses ===*/
  425.  
  426.     ParErr = FALSE;
  427.  
  428.       /*=== Ce n'est pas de l'affichage parasite ===*/
  429.  
  430.     Parasites = FALSE;
  431.  
  432.       /*=== On ne peut plus inserer du Keypad ===*/
  433.  
  434.     Insertion = FALSE;
  435.  
  436.       /*=== On formule l'equation normalisee ===*/
  437.  
  438.     Dest=TempBuff;
  439.     *Dest++ = ' ';
  440.     *Dest   = '\0';
  441.  
  442.     for (Index=0; Index<8; Index++)
  443.     {
  444.        if (LFControlByte & (1<<Index))
  445.        {
  446.           Dest--;
  447.           if (*Dest != ' ') *Dest++ = KeyOR_ID;
  448.           MinPtr = MinTermes[Index];
  449.           while (*Dest++ = *MinPtr++);
  450.        }
  451.     }
  452.  
  453.       /*=== On affiche la nouvelle equation ===*/
  454.  
  455.     if (LFControlByte == 0)
  456.     {
  457.        ModifieStringGadget (&EquGadg, NOP_STRING, FALSE, 0);
  458.        Parasites = TRUE;
  459.     }
  460.     else ModifieStringGadget (&EquGadg, TempBuff, FALSE, 0);
  461. }
  462.  
  463.  
  464.  
  465. /*************************************************************************
  466. **************************************************************************
  467. **
  468. **  CAB ()
  469. **
  470. **  Converti de ASCII vers UBYTE, selon le mode (HEX ou DEC).
  471. **  L'argument est une string a convertir.
  472. **
  473. */
  474.  
  475. UBYTE CAB (Ptr)
  476. UBYTE *Ptr;
  477. {
  478.     STATIC UBYTE Bin;
  479.  
  480.     Bin = 0;
  481.  
  482.     while (*Ptr)
  483.     {
  484.        if (islower(*Ptr)) *Ptr = _toupper (*Ptr);
  485.  
  486.        if ( (*Ptr>='0') && (*Ptr<='9') )
  487.        {
  488.           Bin *= (ModeControle==HEX)?0x10:10;
  489.           Bin += ( *Ptr - '0' );
  490.        }
  491.  
  492.        if ( (ModeControle==HEX) && (*Ptr>='A') && (*Ptr<='F') )
  493.        {
  494.           Bin *= 0x10;
  495.           Bin += ( *Ptr - 'A' + 10 );
  496.        }
  497.  
  498.        Ptr++;
  499.     }
  500.  
  501.     return Bin;
  502. }
  503.  
  504.  
  505.  
  506. /*************************************************************************
  507. **************************************************************************
  508. **
  509. **  CBA ()
  510. **
  511. **  Converti de UBYTE vers ASCII selon le Mode.
  512. **  Dans le mode hexadecimal, on met les lettres en majuscules.
  513. **
  514. */
  515.  
  516. void CBA (LF, Buff)
  517. UBYTE LF;
  518. UBYTE *Buff;
  519. {
  520.     if (ModeControle == HEX)
  521.     {
  522.        sprintf (Buff, "0x%02x", LF);
  523.        if (isalpha(*(Buff+2))) *(Buff+2) = _toupper(*(Buff+2));
  524.        if (isalpha(*(Buff+3))) *(Buff+3) = _toupper(*(Buff+3));
  525.     }
  526.     else /* DEC */
  527.        sprintf (Buff, "%u", LF);
  528. }
  529.  
  530.  
  531.  
  532. /*************************************************************************
  533. **************************************************************************
  534. **
  535. **  AfficheLF ()
  536. **
  537. **  Affiche le resultat courant.
  538. **  Sert aussi a afficher un message d'erreur quand l'equation
  539. **  est erronee (au niveau des parentheses).
  540. **
  541. */
  542.  
  543. void AfficheLF ()
  544. {
  545.     if ( ParErr )
  546.     {
  547.        ModifieStringGadget (&LFGadg, "(?)", NULL, 0);
  548.     }
  549.     else
  550.     {
  551.        CBA (LFControlByte, TempBuff);
  552.        ModifieStringGadget (&LFGadg, TempBuff, NULL, 0);
  553.     }
  554. }
  555.  
  556.  
  557.  
  558. /*************************************************************************
  559. **************************************************************************
  560. **
  561. **  Equ ()
  562. **
  563. **  L'usager vient d'entrer une equation.
  564. **
  565. */
  566.  
  567. void Equ ()
  568. {
  569.       /*=== On evalue l'equation, avec correction ===*/
  570.  
  571.     LFControlByte = EvalueEquation (EquGadgSInfo.Buffer, TempBuff, TRUE);
  572.  
  573.       /*=== Si l'equation comporte une erreur de parenthese, ===*/
  574.       /*=== on ne modifie modifie pas son affichage.         ===*/
  575.  
  576.     if (!ParErr) ModifieStringGadget (&EquGadg, TempBuff, FALSE, 0);
  577.  
  578.       /*=== On affiche le resultat ===*/
  579.  
  580.     AfficheLF   ();
  581.     AfficheVenn ();
  582. }
  583.  
  584.  
  585.  
  586. /*************************************************************************
  587. **************************************************************************
  588. **
  589. **  InsEqu ()
  590. **
  591. **  On entre en mode d'insertion.  Nettoyage si Parasites.
  592. **
  593. */
  594.  
  595. void InsEqu ()
  596. {
  597.       /*=== On permet l'insertion ===*/
  598.  
  599.     Insertion = TRUE;
  600.  
  601.       /*=== On nettoie l'equation si elle contient des parasites ===*/
  602.  
  603.     if (Parasites) ModifieStringGadget (&EquGadg, "", FALSE, 0);
  604. }
  605.  
  606.  
  607.  
  608. /*************************************************************************
  609. **************************************************************************
  610. **
  611. **  LF ()
  612. **
  613. **  L'usager vient d'entrer une valeur LF.
  614. **
  615. */
  616.  
  617. void LF ()
  618. {
  619.       /*=== On converti en binaire ===*/
  620.  
  621.     LFControlByte = (UBYTE) CAB (LFGadgSInfo.Buffer);
  622.  
  623.       /*=== On affiche ===*/
  624.  
  625.     Normalise   ();
  626.     AfficheLF   ();
  627.     AfficheVenn ();
  628. }
  629.  
  630.  
  631.  
  632. /*************************************************************************
  633. **************************************************************************
  634. **
  635. **  Diag ()
  636. **
  637. **  L'usager opere a travers le diagramme de Venn.
  638. **  On fait afficher le LF correspondant.
  639. **
  640. **  Les ID des gadgets (regions) correspondent aux positions des bits
  641. **  dans le minterm.
  642. **
  643. */
  644.  
  645. void Diag (Region)
  646. SHORT Region;
  647. {
  648.       /*=== On modifie le minterm. ===*/
  649.  
  650.     RegionsAllumees = LFControlByte ^= ((UBYTE)1<<(UBYTE)Region);
  651.  
  652.       /*=== On normalise l'affichage ===*/
  653.  
  654.     if (LFControlByte == 0)
  655.     {
  656.        ModifieStringGadget (&EquGadg, NOP_STRING, FALSE, 0);
  657.        Parasites = TRUE;
  658.        ParErr    = FALSE;
  659.     }
  660.     else Normalise ();
  661.  
  662.       /*=== On affiche le resultat ===*/
  663.  
  664.     AfficheLF   ();
  665. }
  666.  
  667.  
  668.  
  669. /*************************************************************************
  670. **************************************************************************
  671. **
  672. **  Keypad ()
  673. **
  674. **  Insere la touche appuyee au bout de l'equation.
  675. **
  676. */
  677.  
  678. void Keypad (Touche)
  679. UBYTE Touche;
  680. {
  681.     STATIC UBYTE *Src, *Dest;
  682.     STATIC UBYTE TempBuff2[EQUBUFFLEN];
  683.     STATIC SHORT Index;
  684.     STATIC SHORT NouPos;
  685.     STATIC SHORT NouLen;
  686.  
  687.       /*=== Si c'est la premiere action, on enleve la presentation.   ===*/
  688.       /*=== 'Parasites' est mis a FALSE dans la fonction du serveur.  ===*/
  689.  
  690.     if (Parasites)
  691.     {
  692.        EquGadgSInfo.Buffer[0] = '\0';
  693.        Parasites = FALSE;
  694.     }
  695.  
  696.       /*=== On traite la touche ===*/
  697.  
  698.     if (Touche == Mode_ID)        /*=== On change de mode ===*/
  699.        {
  700.           ModeControle = (ModeControle==HEX)?DEC:HEX;
  701.           CBA (LFControlByte, TempBuff);
  702.           ModifieStringGadget (&LFGadg, TempBuff, NULL, 0);
  703.        }
  704.     else if (Touche == KeyRst_ID)    /*=== On met tout a zero ===*/
  705.        {
  706.           LFControlByte = 0;
  707.           ModifieStringGadget (&EquGadg, NOP_STRING, NULL, 0);
  708.           Parasites = TRUE;
  709.           ParErr    = FALSE;
  710.           Insertion = FALSE;
  711.           AfficheLF   ();
  712.           AfficheVenn ();
  713.        }
  714.     else if (Touche == KeyEqu_ID)    /*=== On normalise l'equation ===*/
  715.        {
  716.           Normalise ();
  717.        }
  718.     else /*=== C'est un terme a ajouter a l'equation ===*/
  719.        {
  720.           if ( strlen(EquGadgSInfo.Buffer) < (EQUBUFFLEN-2) )
  721.           /* -2 a cause d'un bug d'affichage des string gadgets */
  722.           {
  723.              /*=== On ajoute le symbole a l'equation ===*/
  724.  
  725.                Src  = EquGadgSInfo.Buffer;
  726.                Dest = TempBuff2;
  727.  
  728.                if (Insertion)
  729.                {
  730.                   for (Index=0; Index<EquGadgSInfo.BufferPos; Index++)
  731.                      *Dest++ = *Src++;
  732.                   if (Touche != Back_ID)
  733.                      *Dest++ = Touche;
  734.                   else if (EquGadgSInfo.BufferPos > 0)
  735.                      Dest--;
  736.                }
  737.  
  738.                while (*Dest++ = *Src++);
  739.  
  740.                if (!Insertion)
  741.                {
  742.                   *(Dest-1) = Touche;
  743.                   *Dest = '\0';
  744.                }
  745.  
  746.              /*=== On evalue l'equation ===*/
  747.  
  748.                LFControlByte = EvalueEquation (TempBuff2, TempBuff, FALSE);
  749.  
  750.              /*=== Affichage des resultats ===*/
  751.  
  752.                if (ParErr)
  753.                {
  754.                   Src = TempBuff2;
  755.                   NouLen = strlen (TempBuff2);
  756.                }
  757.                else
  758.                {
  759.                   Src = TempBuff;
  760.                   NouLen = strlen (TempBuff);
  761.                }
  762.  
  763.                NouPos = EquGadgSInfo.BufferPos + (NouLen - EquGadgSInfo.NumChars);
  764.  
  765.                ModifieStringGadget (&EquGadg, Src,  TRUE, NouPos);
  766.  
  767.                AfficheLF   ();
  768.                AfficheVenn ();
  769.  
  770.              /*=== On active le gadget de l'equation, si Insertion. ===*/
  771.  
  772.                if (Insertion) ActivateGadget (&EquGadg, Fenetre, NULL);
  773.           }
  774.           else
  775.           {
  776.              /*=== Pas de place, on le signale a l'usager. ===*/
  777.  
  778.                DisplayBeep (NULL);
  779.           }
  780.        }
  781. }
  782.  
  783.  
  784.  
  785. /*************************************************************************
  786. **************************************************************************
  787. **
  788. **  TraiteGadget ()
  789. **
  790. **  Serveur pour traiter les commandes de l'usager.
  791. **  L'argument est un pointeur au gadget appuye.
  792. **
  793. */
  794.  
  795. void TraiteGadget (Classe, GadgAdresse)
  796. ULONG  Classe;
  797. struct Gadget *GadgAdresse;
  798. {
  799.  
  800.         switch (GadgAdresse->GadgetID)
  801.     {
  802.  
  803.      /*=== Keypad ===*/
  804.  
  805.        case Mode_ID   :    Keypad (Mode_ID);        break;
  806.        case KeyA_ID   :    Keypad (KeyA_ID);        break;
  807.        case KeyNA_ID  :    Keypad (KeyNA_ID);        break;
  808.        case KeyB_ID   :    Keypad (KeyB_ID);        break;
  809.        case KeyNB_ID  :    Keypad (KeyNB_ID);        break;
  810.        case KeyC_ID   :    Keypad (KeyC_ID);        break;
  811.        case KeyNC_ID  :    Keypad (KeyNC_ID);        break;
  812.        case KeyOR_ID  :    Keypad (KeyOR_ID);        break;
  813.        case KeyEqu_ID :    Keypad (KeyEqu_ID);        break;
  814.        case KeyRst_ID :    Keypad (KeyRst_ID);        break;
  815.        case ParOuv_ID :    Keypad (ParOuv_ID);        break;
  816.        case ParFer_ID :    Keypad (ParFer_ID);        break;
  817.        case Back_ID   :    Keypad (Back_ID);        break;
  818.  
  819.        case ScrolD_ID :    Scroll (ScrolD_ID);        break;
  820.        case ScrolG_ID :    Scroll (ScrolG_ID);        break;
  821.  
  822.      /*=== Diagramme de Venn ===*/
  823.  
  824.        case Venn0_ID  :    Diag (Venn0_ID);        break;
  825.        case VennA_ID  :    Diag (VennA_ID);        break;
  826.        case VennB_ID  :    Diag (VennB_ID);        break;
  827.        case VennC_ID  :    Diag (VennC_ID);        break;
  828.        case VennAB_ID :    Diag (VennAB_ID);        break;
  829.        case VennAC_ID :    Diag (VennAC_ID);        break;
  830.        case VennBC_ID :    Diag (VennBC_ID);        break;
  831.        case VennABC_ID:    Diag (VennABC_ID);        break;
  832.  
  833.      /*=== Gadgets texte ===*/
  834.  
  835.        case LFGadg_ID :    LF ();
  836.                             break;
  837.  
  838.        case EquGadg_ID:    if (Classe == GADGETDOWN)
  839.                                InsEqu ();
  840.                             else
  841.                                Equ ();
  842.                             break;
  843.  
  844.        default        :     break; /* i.e. MENUDOWN sans Insertion */
  845.     }
  846. }
  847.  
  848.  
  849.  
  850. /*************************************************************************
  851. **************************************************************************
  852. **
  853. **  Sortie ()
  854. **
  855. **  Ferme ce qui a ete ouvert.
  856. **
  857. */
  858.  
  859. void Sortie ()
  860. {
  861.     if (Fenetre)       CloseWindow  (Fenetre);
  862.     if (IntuitionBase) CloseLibrary (IntuitionBase);
  863.     if (GfxBase)       CloseLibrary (GfxBase);
  864.     if (Fonte)       CloseFont    (Fonte);
  865.  
  866.     _exit (0L);
  867. }
  868.  
  869.  
  870.  
  871. /*************************************************************************
  872. **************************************************************************
  873. **
  874. **  Erreur ()
  875. **
  876. **  Affiche un message d'erreur a travers un requester.
  877. **  Laisse le choix entre l'abandon de la procedure et
  878. **  un autre essai.
  879. **
  880. */
  881.  
  882. #define ErrGfxLib   0
  883. #define ErrIntuiLib 1
  884. #define ErrOpenWin  2
  885. #define ErrFonte    3
  886.  
  887. struct IntuiText Message = { 2, 1, JAM1, 17, 10, NULL, NULL, NULL };
  888. struct IntuiText Essai   = { 2, 1, JAM1, 5, 5, NULL, (UBYTE *) "Tentative", NULL };
  889. struct IntuiText Abandon = { 2, 1, JAM1, 5, 5, NULL, (UBYTE *) "Abandon", NULL };
  890.  
  891. void Erreur (Err)
  892. SHORT Err;
  893. {
  894.     SHORT EssaieEncore;
  895.  
  896.     switch (Err)
  897.     {
  898.        case ErrGfxLib   : Message.IText = (UBYTE *) "Erreur: OpenLibrary: GfxLib";
  899.                           break;
  900.        case ErrIntuiLib : Message.IText = (UBYTE *) "Erreur: OpenLibrary: IntuiLib)";
  901.                           break;
  902.        case ErrOpenWin  : Message.IText = (UBYTE *) "Erreur: OpenWindow";
  903.                           break;
  904.        case ErrFonte    : Message.IText = (UBYTE *) "Erreur: OpenFont: Topaz 8";
  905.                           break;
  906.        default          : Message.IText = (UBYTE *) "Erreur inconnue !";
  907.                           break;
  908.     }
  909.  
  910.     EssaieEncore = AutoRequest (Fenetre, &Message, &Essai, &Abandon,
  911.                                 NULL, NULL, 300L, 60L);
  912.  
  913.     if (EssaieEncore) return;
  914.  
  915.     Sortie ();
  916. }
  917.  
  918.  
  919.  
  920. /*************************************************************************
  921. **************************************************************************
  922. **
  923. **  Initialise ()
  924. **
  925. */
  926.  
  927. void Initialise ()
  928. {
  929.    /*=== La librairie Intuition ===*/
  930.    /*=== Si on n'a pas la bonne version, on ouvre celle presente pour ===*/
  931.    /*=== appeler la fonction AutoRequest ().                          ===*/
  932.  
  933.     FOREVER
  934.     {
  935.        IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 33L); /* v1.2+ */
  936.        if (!IntuitionBase)
  937.        {
  938.           IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L);
  939.           if (!IntuitionBase) Sortie ();   /* Plus le choix ! */
  940.           Erreur (ErrIntuiLib);
  941.           Sortie ();
  942.        }
  943.        else break;
  944.     }
  945.  
  946.    /*=== La librairie graphique ===*/
  947.  
  948.     FOREVER
  949.     {
  950.        GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
  951.        if (!GfxBase) Erreur (ErrGfxLib);
  952.                 else break;
  953.     }
  954.  
  955.    /*=== La ROMFonte par defaut ===*/
  956.  
  957.     FOREVER
  958.     {
  959.        Fonte = OpenFont (&FonteAttr);
  960.        if (!Fonte) Erreur (ErrFonte);
  961.               else break;
  962.     }
  963.  
  964.    /*=== On ouvre la fenetre ===*/
  965.  
  966.     FOREVER
  967.     {
  968.        Fenetre = OpenWindow (&FenetreData);
  969.        if (!Fenetre) Erreur (ErrOpenWin);
  970.                 else break;
  971.     }
  972.  
  973.    /*=== On pointe le RastPort de la fenetre ===*/
  974.  
  975.     RP = Fenetre->RPort;
  976.  
  977.    /*=== On assigne la fonte ===*/
  978.  
  979.     SetFont (RP, Fonte);
  980.  
  981.    /*=== On dessine la calculatrice ===*/
  982.  
  983.     DrawImage (RP, &Dessin, 0L, 0L);
  984.  
  985.    /*=== On rafraichit l'imagerie des gadgets ===*/
  986.  
  987.     RefreshGList (&EquGadg,  Fenetre, NULL, 2L); /* Les strings */
  988.     RefreshGList (&ModeGadg, Fenetre, NULL, 1L); /* Le mode */
  989. }
  990.  
  991.  
  992.  
  993. /*************************************************************************
  994. **************************************************************************
  995. **
  996. **  _Abort ()
  997. **
  998. **  Remplace la fonction du systeme qui trappe les CTRL-C.
  999. **
  1000. */
  1001.  
  1002. void _Abort ()
  1003. {
  1004.     Sortie ();
  1005. }
  1006.  
  1007.  
  1008.  
  1009. /*************************************************************************
  1010. **************************************************************************
  1011. **************************************************************************
  1012. ***
  1013. ***  main ()
  1014. ***
  1015. ***  Depart du CLI :
  1016. ***
  1017. ***     - Si on a un argument, on assume que c'est une equation
  1018. ***       a resoudre immediatement, sans passer par la calculatrice.
  1019. ***
  1020. ***     - Sans arguments, on ouvre la calculatrice interactive.
  1021. ***
  1022. ***  Depart du WorkBench :
  1023. ***
  1024. ***     - On ouvre la calculatrice interactive.
  1025. ***
  1026. **/
  1027.  
  1028. main (NbArgs, Args)
  1029. SHORT NbArgs;
  1030. UBYTE **Args;
  1031. {
  1032.     UBYTE    *EquPtr = *(Args+1);  /* Premier argument (equation) */
  1033.  
  1034.     struct IntuiMessage *Msg;     /* Pointeur pour prendre les messages */
  1035.     ULONG Classe;                 /* Pour noter la classe du message */
  1036.     APTR  Adresse;                /* Pour noter l'addresse du gadget */
  1037.  
  1038.     ULONG Eve;              /* Masque pour l'evenement signale */
  1039.  
  1040.    /*=== On permet l'abandon du programme ===*/
  1041.  
  1042.     Enable_Abort = 1;
  1043.  
  1044.    /*=== Si on a des arguments, on repond au CLI, et on sort. ===*/
  1045.  
  1046.     if (NbArgs > 1)
  1047.     {
  1048.        LFControlByte = EvalueEquation (EquPtr, TempBuff, TRUE);
  1049.        printf ("LF : hex(0x%02x), dec(%u)\n",LFControlByte, LFControlByte);
  1050.        printf ("Equation corrigee : %s\n", TempBuff);
  1051.        _exit (0L);
  1052.     }
  1053.  
  1054.    /*=== On ouvre la calculatrice ===*/
  1055.  
  1056.     Initialise ();
  1057.  
  1058.     FOREVER
  1059.     {
  1060.  
  1061.     /*=== On attends un evenement: IntuiMessage ou CTRL_C. ===*/
  1062.  
  1063.        Eve = Wait (1L<<Fenetre->UserPort->mp_SigBit | SIGBREAKF_CTRL_C);
  1064.  
  1065.        if (Eve & SIGBREAKF_CTRL_C)
  1066.           Sortie ();
  1067.        else
  1068.           Msg = GetMsg (Fenetre->UserPort);
  1069.  
  1070.     /*=== On note les informations pertinentes du message ===*/
  1071.  
  1072.        Classe  = Msg->Class;
  1073.        Adresse = Msg->IAddress;
  1074.  
  1075.     /*=== On informe Intuition qu'on a lu le message ===*/
  1076.  
  1077.        ReplyMsg (Msg);
  1078.  
  1079.     /*=== On branche sur la bonne voie.  Si c'est le premier msg, ===*/
  1080.     /*=== on fait un nettoyage de l'affichage.                    ===*/
  1081.  
  1082.        if (Classe == CLOSEWINDOW)
  1083.           Sortie ();
  1084.        else
  1085.           TraiteGadget (Classe, Adresse);
  1086.     }
  1087. }
  1088.