home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src_ansi / ace / c / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-05  |  16.2 KB  |  731 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: event trapping code **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.    Date: 26th October-30th November, 1st-13th December 1991,
  24.    14th,20th-27th January 1992, 
  25.    2nd-17th, 21st-29th February 1992, 
  26.    1st,13th,14th,22nd,23rd March 1992,
  27.    21st,22nd April 1992,
  28.    2nd,3rd,11th,15th,16th May 1992,
  29.    7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.    2nd-8th,14th-19th,26th-29th July 1992,
  31.    1st-3rd,7th,8th,9th August 1992,
  32.    6th,7th,21st December 1992,
  33.    13th,28th February 1993,
  34.    1st March 1993,
  35.    25th September 1993,
  36.    24th,25th,26th October 1993,
  37.    2nd,8th-10th November 1993,
  38.    24th July 1994,
  39.    7th,8th August 1995
  40.  */
  41.  
  42. #include "acedef.h"
  43. #include <string.h>
  44. #include <clib/mathffp_protos.h>
  45.  
  46. /* externals */
  47. extern int sym;
  48. extern int lastsym;
  49. extern SYM *curr_item;
  50.  
  51. extern char id[MAXIDSIZE];
  52. extern SHORT shortval;
  53. extern LONG longval;
  54. extern float singleval;
  55.  
  56. extern BOOL break_event;
  57. extern BOOL menu_event;
  58. extern BOOL mouse_event;
  59. extern BOOL timer_event;
  60. extern BOOL error_event;
  61. extern BOOL wdw_event;
  62. extern BOOL gad_event;
  63.  
  64. extern BOOL break_event_label_exists;
  65. extern BOOL menu_event_label_exists;
  66. extern BOOL mouse_event_label_exists;
  67. extern BOOL timer_event_label_exists;
  68. extern BOOL error_event_label_exists;
  69. extern BOOL wdw_event_label_exists;
  70. extern BOOL gad_event_label_exists;
  71.  
  72. extern BOOL ontimerused;
  73.  
  74. extern BOOL break_opt;
  75. extern BOOL wdw_close_opt;
  76.  
  77. extern int break_event_branch;
  78. extern int menu_event_branch;
  79. extern int mouse_event_branch;
  80. extern int timer_event_branch;
  81. extern int error_event_branch;
  82. extern int wdw_event_branch;
  83. extern int gad_event_branch;
  84.  
  85. extern char break_event_label[80];
  86. extern char menu_event_label[80];
  87. extern char mouse_event_label[80];
  88. extern char timer_event_label[80];
  89. extern char error_event_label[80];
  90. extern char wdw_event_label[80];
  91. extern char gad_event_label[80];
  92.  
  93. extern float timer_event_seconds;
  94. extern char ontimer_seconds[40];
  95.  
  96. /* functions */
  97. void get_event_trap_label (void)
  98. {
  99. /* ON <event>|[TIMER(n)] GOSUB <label> | GOTO <label> | CALL <SUBname> */
  100.   int event;
  101.   int branchsym;
  102.   char theLabel[80];
  103.  
  104.   if ((sym != breaksym) && (sym != menusym) &&
  105.       (sym != mousesym) && (sym != timersym) &&
  106.       (sym != errorsym) && (sym != windowsym) &&
  107.       (sym != gadgetsym))
  108.     _error (55);
  109.   else
  110.     {
  111.       event = sym;        /* remember event specifier */
  112.  
  113.       /* if TIMER, get single-precision seconds */
  114.       if (event == timersym)
  115.     {
  116.       insymbol ();
  117.       if (sym != lparen)
  118.         _error (14);
  119.       else
  120.         {
  121.           insymbol ();
  122.           if ((sym != shortconst) && (sym != longconst) &&
  123.           (sym != singleconst))
  124.         _error (27);    /* numeric constant expected */
  125.           else
  126.         {
  127.           switch (sym)
  128.             {
  129.             case shortconst:
  130.               timer_event_seconds = SPFlt ((ULONG) shortval);
  131.               break;
  132.             case longconst:
  133.               timer_event_seconds = SPFlt ((ULONG) longval);
  134.               break;
  135.             case singleconst:
  136.               timer_event_seconds = singleval;
  137.               break;
  138.             }
  139. /* sprintf (ontimer_seconds, "#$%lx", timer_event_seconds); original */
  140.           sprintf (ontimer_seconds, "#$%x", timer_event_seconds);
  141.           insymbol ();
  142.           if (sym != rparen)
  143.             _error (9);
  144.         }
  145.         }
  146.     }
  147.       insymbol ();
  148.       if (sym != gosubsym && sym != gotosym && sym != callsym)
  149.     _error (56);
  150.       else
  151.     {
  152.       branchsym = sym;    /* GOSUB, GOTO or CALL? */
  153.  
  154.       insymbol ();
  155.       if (sym != ident && sym != shortconst && sym != longconst)
  156.         _error (57);    /* label or SUB name expected */
  157.       else
  158.         {
  159.           /* Make a label from a line number? */
  160.           if (sym != ident)
  161.         make_label_from_linenum (sym, id);
  162.  
  163.           /* 
  164.              ** Convert to a SUB label, check for existence 
  165.              ** (defined or declared) of SUB and number of 
  166.              ** parameters (must be zero to be valid).
  167.            */
  168.           if (branchsym == callsym)
  169.         {
  170.           sprintf (theLabel, "_SUB_%s", id);
  171.           if (!exist (theLabel, subprogram))
  172.             {
  173.               _error (59);
  174.               return;
  175.             }
  176.           else if (curr_item->no_of_params != 0)
  177.             {
  178.               _error (78);
  179.               return;
  180.             }
  181.         }
  182.           else
  183.         strcpy (theLabel, id);
  184.  
  185.           switch (event)
  186.         {
  187.         case breaksym:
  188.           strcpy (break_event_label, theLabel);
  189.           break_event_label_exists = TRUE;
  190.           break_event_branch = branchsym;
  191.           break;
  192.  
  193.         case menusym:
  194.           strcpy (menu_event_label, theLabel);
  195.           menu_event_label_exists = TRUE;
  196.           menu_event_branch = branchsym;
  197.           break;
  198.  
  199.         case mousesym:
  200.           strcpy (mouse_event_label, theLabel);
  201.           mouse_event_label_exists = TRUE;
  202.           mouse_event_branch = branchsym;
  203.           break;
  204.  
  205.         case timersym:
  206.           strcpy (timer_event_label, theLabel);
  207.           timer_event_label_exists = TRUE;
  208.           timer_event_branch = branchsym;
  209.           break;
  210.  
  211.         case errorsym:
  212.           strcpy (error_event_label, theLabel);
  213.           error_event_label_exists = TRUE;
  214.           error_event_branch = branchsym;
  215.           break;
  216.  
  217.         case windowsym:
  218.           strcpy (wdw_event_label, theLabel);
  219.           wdw_event_label_exists = TRUE;
  220.           wdw_event_branch = branchsym;
  221.           break;
  222.  
  223.         case gadgetsym:
  224.           strcpy (gad_event_label, theLabel);
  225.           gad_event_label_exists = TRUE;
  226.           gad_event_branch = branchsym;
  227.           break;
  228.         }
  229.           insymbol ();
  230.         }
  231.     }
  232.     }
  233. }
  234.  
  235. void change_event_trapping_status (int event)
  236. {
  237. /* <event> ON|OFF|STOP */
  238.   int action;
  239.  
  240.   if (lastsym != windowsym && lastsym != gadgetsym &&
  241.       lastsym != menusym)
  242.     insymbol ();
  243.  
  244.   if ((sym != onsym) && (sym != offsym) && (sym != stopsym))
  245.     _error (58);        /* ON, OFF or STOP expected */
  246.   else
  247.     {
  248.       action = sym;        /* remember action symbol */
  249.       insymbol ();
  250.       /* enable event trapping for <event>. */
  251.       if (action == onsym)
  252.     switch (event)
  253.       {
  254.       case breaksym:
  255.         if (break_event_label_exists)
  256.           break_event = TRUE;
  257.         else
  258.           _error (59);
  259.         break;
  260.  
  261.       case menusym:
  262.         if (menu_event_label_exists)
  263.           menu_event = TRUE;
  264.         else
  265.           _error (59);
  266.         break;
  267.  
  268.       case mousesym:
  269.         if (mouse_event_label_exists)
  270.           mouse_event = TRUE;
  271.         else
  272.           _error (59);
  273.         break;
  274.  
  275.       case timersym:
  276.         if (timer_event_label_exists)
  277.           {
  278.         timer_event = TRUE;
  279.         ontimerused = TRUE;
  280.           }
  281.         else
  282.           _error (59);
  283.         break;
  284.  
  285.       case errorsym:
  286.         if (error_event_label_exists)
  287.           error_event = TRUE;
  288.         else
  289.           _error (59);
  290.         break;
  291.  
  292.       case windowsym:
  293.         if (wdw_event_label_exists)
  294.           wdw_event = TRUE;
  295.         else
  296.           _error (59);
  297.         break;
  298.  
  299.       case gadgetsym:
  300.         if (gad_event_label_exists)
  301.           gad_event = TRUE;
  302.         else
  303.           _error (59);
  304.         break;
  305.       }
  306.       else
  307.     /* disable event trapping for <event>. */
  308.       if (action == offsym)
  309.     switch (event)
  310.       {
  311.       case breaksym:
  312.         if (break_event_label_exists)
  313.           {
  314.         break_event = FALSE;
  315.         break_event_label_exists = FALSE;
  316.           }
  317.         else
  318.           _error (59);
  319.         break;
  320.  
  321.       case menusym:
  322.         if (menu_event_label_exists)
  323.           {
  324.         menu_event = FALSE;
  325.         menu_event_label_exists = FALSE;
  326.           }
  327.         else
  328.           _error (59);
  329.         break;
  330.  
  331.       case mousesym:
  332.         if (mouse_event_label_exists)
  333.           {
  334.         mouse_event = FALSE;
  335.         mouse_event_label_exists = FALSE;
  336.           }
  337.         else
  338.           _error (59);
  339.         break;
  340.  
  341.       case timersym:
  342.         if (timer_event_label_exists)
  343.           {
  344.         timer_event = FALSE;
  345.         timer_event_label_exists = FALSE;
  346.           }
  347.         else
  348.           _error (59);
  349.         break;
  350.  
  351.       case errorsym:
  352.         if (error_event_label_exists)
  353.           {
  354.         error_event = FALSE;
  355.         error_event_label_exists = FALSE;
  356.           }
  357.         else
  358.           _error (59);
  359.         break;
  360.  
  361.       case windowsym:
  362.         if (wdw_event_label_exists)
  363.           {
  364.         wdw_event = FALSE;
  365.         wdw_event_label_exists = FALSE;
  366.           }
  367.         else
  368.           _error (59);
  369.         break;
  370.  
  371.       case gadgetsym:
  372.         if (gad_event_label_exists)
  373.           {
  374.         gad_event = FALSE;
  375.         gad_event_label_exists = FALSE;
  376.           }
  377.         else
  378.           _error (59);
  379.         break;
  380.       }
  381.       else
  382.     /* disable event trapping for <event> but remember trapping routine. */
  383.       if (action == stopsym)
  384.     switch (event)
  385.       {
  386.       case breaksym:
  387.         if (break_event_label_exists)
  388.           break_event = FALSE;
  389.         else
  390.           _error (59);
  391.         break;
  392.  
  393.       case menusym:
  394.         if (menu_event_label_exists)
  395.           menu_event = FALSE;
  396.         else
  397.           _error (59);
  398.         break;
  399.  
  400.       case mousesym:
  401.         if (mouse_event_label_exists)
  402.           mouse_event = FALSE;
  403.         else
  404.           _error (59);
  405.         break;
  406.  
  407.       case timersym:
  408.         if (timer_event_label_exists)
  409.           timer_event = FALSE;
  410.         else
  411.           _error (59);
  412.         break;
  413.  
  414.       case errorsym:
  415.         if (error_event_label_exists)
  416.           error_event = FALSE;
  417.         else
  418.           _error (59);
  419.         break;
  420.  
  421.       case windowsym:
  422.         if (wdw_event_label_exists)
  423.           wdw_event = FALSE;
  424.         else
  425.           _error (59);
  426.         break;
  427.  
  428.       case gadgetsym:
  429.         if (gad_event_label_exists)
  430.           gad_event = FALSE;
  431.         else
  432.           _error (59);
  433.         break;
  434.       }
  435.  
  436.       insymbol ();
  437.     }
  438. }
  439.  
  440. void turn_event_off (char *eventHandler)
  441. {
  442. /* 
  443.    ** Turn event trapping off if this 
  444.    ** subroutine/subprogram belongs to 
  445.    ** an event.
  446.  */
  447.   if ((strcmp (eventHandler, break_event_label) == 0) && (break_event))
  448.     {
  449.       break_event = FALSE;
  450.       break_event_label_exists = FALSE;
  451.     }
  452.   else if ((strcmp (eventHandler, menu_event_label) == 0) && (menu_event))
  453.     {
  454.       menu_event = FALSE;
  455.       menu_event_label_exists = FALSE;
  456.     }
  457.   else if ((strcmp (eventHandler, mouse_event_label) == 0) && (mouse_event))
  458.     {
  459.       mouse_event = FALSE;
  460.       mouse_event_label_exists = FALSE;
  461.     }
  462.   else if ((strcmp (eventHandler, timer_event_label) == 0) && (timer_event))
  463.     {
  464.       timer_event = FALSE;
  465.       timer_event_label_exists = FALSE;
  466.     }
  467.   else if ((strcmp (eventHandler, error_event_label) == 0) && (error_event))
  468.     {
  469.       error_event = FALSE;
  470.       error_event_label_exists = FALSE;
  471.     }
  472.   else if ((strcmp (eventHandler, wdw_event_label) == 0) && (wdw_event))
  473.     {
  474.       wdw_event = FALSE;
  475.       wdw_event_label_exists = FALSE;
  476.     }
  477.   else if ((strcmp (eventHandler, gad_event_label) == 0) && (gad_event))
  478.     {
  479.       gad_event = FALSE;
  480.       gad_event_label_exists = FALSE;
  481.     }
  482. }
  483.  
  484. void check_for_event (void)
  485. {
  486. /* produce code for event trapping */
  487.   if (break_opt)
  488.     ctrl_c_test ();
  489.   if (break_event)
  490.     break_event_test ();
  491.   if (menu_event)
  492.     menu_event_test ();
  493.   if (wdw_close_opt)
  494.     wdw_close_test ();
  495.   if (wdw_event)
  496.     wdw_event_test ();
  497.   if (gad_event)
  498.     gad_event_test ();
  499.   if (mouse_event)
  500.     mouse_event_test ();
  501.   if (timer_event)
  502.     timer_event_test ();
  503.   if (error_event)
  504.     error_event_test ();
  505. }
  506.  
  507. void ctrl_c_test (void)
  508. {
  509.   char lab[80], lablabel[80];
  510.  
  511. /* test for ctrl-c signal 
  512.    and exit program if a 
  513.    break signal is pending. */
  514.  
  515.   make_label (lab, lablabel);
  516.  
  517.   gen ("jsr", "_ctrl_c_test", "  ");
  518.   gen ("tst.l", "d0", "  ");
  519.   gen ("beq.s", lab, "  ");
  520.   gen ("jmp", "_EXIT_PROG", "  ");
  521.   gen (lablabel, "  ", "  ");
  522.  
  523.   enter_XREF ("_ctrl_c_test");
  524. }
  525.  
  526. void break_event_test (void)
  527. {
  528.   char lab[80], lablabel[80];
  529.  
  530. /* test for ctrl-c signal 
  531.    and pass control to the
  532.    BREAK trapping subroutine. */
  533.  
  534.   make_label (lab, lablabel);
  535.  
  536.   gen ("jsr", "_ctrl_c_test", "  ");
  537.   gen ("tst.l", "d0", "  ");
  538.   gen ("beq.s", lab, "  ");
  539.  
  540.   if (break_event_branch == callsym)
  541.     gen ("jsr", break_event_label, "  ");
  542.   else if (break_event_branch == gosubsym)
  543.     gen_branch ("jsr", break_event_label);
  544.   else
  545.     gen_branch ("jmp", break_event_label);
  546.  
  547.   gen (lablabel, "  ", "  ");
  548.  
  549.   enter_XREF ("_ctrl_c_test");
  550. }
  551.  
  552. void menu_event_test (void)
  553. {
  554.   char lab[80], lablabel[80];
  555.  
  556. /* test for menu button press 
  557.    and pass control to the
  558.    MENU trapping subroutine. */
  559.  
  560.   gen ("jsr", "_menu_test", "  ");
  561.   gen ("tst.l", "d0", "  ");
  562.   make_label (lab, lablabel);
  563.   gen ("beq.s", lab, "  ");
  564.  
  565.   if (menu_event_branch == callsym)
  566.     gen ("jsr", menu_event_label, "  ");
  567.   else if (menu_event_branch == gosubsym)
  568.     gen_branch ("jsr", menu_event_label);
  569.   else
  570.     gen_branch ("jmp", menu_event_label);
  571.   gen (lablabel, "  ", "  ");
  572.   enter_XREF ("_menu_test");
  573. }
  574.  
  575. void mouse_event_test (void)
  576. {
  577.   char lab[80], lablabel[80];
  578.  
  579. /* test for left mouse button 
  580.    press and pass control to the
  581.    MOUSE trapping subroutine. */
  582.  
  583.   gen ("moveq", "#0", "d0");
  584.   gen ("jsr", "_mouse", "  ");
  585.   gen ("tst.l", "d0", "  ");
  586.   make_label (lab, lablabel);
  587.   gen ("beq.s", lab, "  ");
  588.  
  589.   if (mouse_event_branch == callsym)
  590.     gen ("jsr", mouse_event_label, "  ");
  591.   else if (mouse_event_branch == gosubsym)
  592.     gen_branch ("jsr", mouse_event_label);
  593.   else
  594.     gen_branch ("jmp", mouse_event_label);
  595.   gen (lablabel, "  ", "  ");
  596.   enter_XREF ("_mouse");
  597. }
  598.  
  599. void timer_event_test (void)
  600. {
  601.   char lab[80], lablabel[80];
  602.  
  603. /* test for timer event 
  604.    and pass control to the
  605.    TIMER trapping subroutine. */
  606.  
  607.   gen ("move.l", ontimer_seconds, "d0");
  608.   gen ("jsr", "_ontimer", "  ");
  609.   gen ("tst.l", "d0", "  ");
  610.   make_label (lab, lablabel);
  611.   gen ("beq.s", lab, "  ");
  612.  
  613.   if (timer_event_branch == callsym)
  614.     gen ("jsr", timer_event_label, "  ");
  615.   else if (timer_event_branch == gosubsym)
  616.     gen_branch ("jsr", timer_event_label);
  617.   else
  618.     gen_branch ("jmp", timer_event_label);
  619.   gen (lablabel, "  ", "  ");
  620.   enter_XREF ("_ontimer");
  621.   enter_XREF ("_MathBase");    /* timer routines need mathffp.library */
  622. }
  623.  
  624. void error_event_test (void)
  625. {
  626.   char lab[80], lablabel[80];
  627.  
  628. /* Test for I/O error condition 
  629.    and pass control to the ERROR
  630.    trapping subroutine.
  631.  */
  632.  
  633.   gen ("jsr", "_testerror", "  ");
  634.   gen ("tst.l", "d0", "  ");
  635.   make_label (lab, lablabel);
  636.   gen ("beq.s", lab, "  ");
  637.  
  638.   if (error_event_branch == callsym)
  639.     gen ("jsr", error_event_label, "  ");
  640.   else if (error_event_branch == gosubsym)
  641.     gen_branch ("jsr", error_event_label);
  642.   else
  643.     gen_branch ("jmp", error_event_label);
  644.   gen (lablabel, "  ", "  ");
  645.   enter_XREF ("_testerror");
  646. }
  647.  
  648. void wdw_close_test (void)
  649. {
  650.   char lab[80], lablabel[80];
  651.  
  652. /* Test for close-gadget selection 
  653.    in any window and exit program 
  654.    if close-gadget click detected.
  655.  
  656.    The clicked window will be closed
  657.    before the program exits.
  658.  */
  659.   make_label (lab, lablabel);
  660.  
  661.   gen ("move.l", "#1", "-(sp)");
  662.   gen ("jsr", "_wdw_close_test", "  ");
  663.   gen ("addq", "#4", "sp");
  664.   gen ("tst.l", "d0", "  ");
  665.   gen ("beq.s", lab, "  ");
  666.   gen ("jmp", "_EXIT_PROG", "  ");
  667.   gen (lablabel, "  ", "  ");
  668.  
  669.   enter_XREF ("_wdw_close_test");
  670. }
  671.  
  672. void wdw_event_test (void)
  673. {
  674.   char lab[80], lablabel[80];
  675.  
  676. /* Test for close-gadget selection 
  677.    in any window and transfer control
  678.    to a user-defined subroutine if 
  679.    close-gadget click detected.
  680.  
  681.    This may be extended in the future
  682.    to accomodate other window events
  683.    (eg: resizing).   
  684.  */
  685.   make_label (lab, lablabel);
  686.  
  687.   gen ("move.l", "#0", "-(sp)");
  688.   gen ("jsr", "_wdw_close_test", "  ");
  689.   gen ("addq", "#4", "sp");
  690.   gen ("tst.l", "d0", "  ");
  691.   gen ("beq.s", lab, "  ");
  692.  
  693.   if (wdw_event_branch == callsym)
  694.     gen ("jsr", wdw_event_label, "  ");
  695.   else if (wdw_event_branch == gosubsym)
  696.     gen_branch ("jsr", wdw_event_label);
  697.   else
  698.     gen_branch ("jmp", wdw_event_label);
  699.   gen (lablabel, "  ", "  ");
  700.  
  701.   enter_XREF ("_wdw_close_test");
  702. }
  703.  
  704. void gad_event_test (void)
  705. {
  706.   char lab[80], lablabel[80];
  707.  
  708. /* Test for user-defined gadget selection 
  709.    in current output window and transfer 
  710.    control to a user-defined subroutine 
  711.    if a gadget click is detected.
  712.  */
  713.   make_label (lab, lablabel);
  714.  
  715.   gen ("move.l", "#0", "-(sp)");
  716.   gen ("jsr", "_gadget_event_test", "  ");
  717.   gen ("addq", "#4", "sp");
  718.   gen ("tst.l", "d0", "  ");
  719.   gen ("beq.s", lab, "  ");
  720.  
  721.   if (gad_event_branch == callsym)
  722.     gen ("jsr", gad_event_label, "  ");
  723.   else if (gad_event_branch == gosubsym)
  724.     gen_branch ("jsr", gad_event_label);
  725.   else
  726.     gen_branch ("jmp", gad_event_label);
  727.   gen (lablabel, "  ", "  ");
  728.  
  729.   enter_XREF ("_gadget_event_test");
  730. }
  731.