home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / progut~1 / stdwin.zoo / atari / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-29  |  13.6 KB  |  689 lines

  1. #include <time.h>
  2. #include "window.h"
  3. #include "trees.h"
  4. #include "atari_proto.h"
  5.  
  6. static void do_timer P((EVENT *ep ));
  7. static bool find_update P((EVENT *ep ));
  8. static void set_timer P((EVENT *ep , int *phightime , unsigned int *plowtime ));
  9. static void do_keybd P((EVENT *ep , int key ));
  10. static void do_button P((EVENT *ep , Mouse *mrec ));
  11. static void do_messag P((EVENT *ep , int msg_buf []));
  12. static void do_redraw P((int msg_buf []));
  13. static void do_topped P((EVENT *ep , int msg_buf []));
  14. static void do_closed P((EVENT *ep , int msg_buf []));
  15. static void do_size P((EVENT *ep , int msg_buf []));
  16. #undef P
  17.  
  18. #define DIST_CLICK    5
  19. #define CLICK_TICKS    500L
  20.  
  21. extern int    vdi_handle ;
  22.  
  23. extern WINDOW    **winlist ;
  24. extern int    nrwin ;
  25. extern WINDOW    *active ;
  26. static WINDOW    *lactive = (WINDOW *) NULL ;
  27.  
  28. static EVENT    levent = { WE_NULL } ;
  29.  
  30. extern void    menuupdate () ;
  31. extern void    do_menu () ;
  32. extern void    do_scroll () ;
  33.  
  34. static int    mupwaiting = FALSE ;
  35. static msec    prev_tick = 0 ;
  36. static int    prev_state = 0 ;
  37. static int    prev_h = 10 ;
  38. static int    prev_v = 10 ;
  39. static int    nr_clicks = 0 ;
  40. bool    mousedown = FALSE ;
  41.  
  42. bool    mouseoff = FALSE ;
  43.  
  44. static int    shape = ARROW ;
  45. static int    oldshape = THIN_CROSS ;
  46.  
  47. static void    do_timer () ;
  48. static bool    find_update () ;
  49. static void    set_timer () ;
  50. static void    do_keybd () ;
  51. static void    do_button () ;
  52. static void    do_messag () ;
  53. static void    do_redraw () ;
  54. static void    do_topped () ;
  55. static void    do_closed () ;
  56. static void    do_size () ;
  57. /* static void    do_acces () ; */
  58.  
  59. void
  60. wungetevent (ep)
  61.     EVENT    *ep ;
  62. {
  63.     levent = *ep ;
  64. }
  65.  
  66. void
  67. wgetevent (ep)
  68.     EVENT    *ep ;
  69. {
  70.     int    which = (MU_TIMER | MU_KEYBD | MU_BUTTON | MU_MESAG | MU_M2) ;
  71.                     /* Which events are relevant          */
  72.     int    nr_clicks = 1 ;        /* How many clicks are you waiting for*/
  73.     int    what_button = 1 ;    /* Which button are you waiting for   */
  74.     int    button_state ;        /* What button state are you waiting  */
  75.     int    msg_buf[8] ;        /* Buffer for message returned        */
  76.     unsigned int    lowtime ;    /* Low word for timer                 */
  77.     int    hightime ;        /* High word for timer                */
  78.     int    m_x, m_y, m_b, m_k ;    /* integers for Mouse                 */
  79.     Mouse    mevnt_rec = {&m_x, &m_y, &m_b, &m_k} ;
  80.                     /* Mouse postion when event occured   */
  81.     int    key_pressed ;        /* The key pressed                    */
  82.     int    nr_times ;        /* Nr of times mouse entered state    */
  83.     int    clickinout = 1 ;
  84.     int    wininout = 0 ;
  85.     Rect    clickrect ;
  86.     Rect    winrect ;
  87.     int    dummy = 0 ;
  88.     int    rc ;
  89.     unsigned long longtime;
  90.  
  91.     menuupdate () ;
  92.  
  93.     if (levent.type != WE_NULL) {
  94.         *ep = levent ;
  95.         levent.type = WE_NULL ;
  96.         return ;
  97.     }
  98.  
  99.     if (mupwaiting) {
  100.         ep->type = WE_MOUSE_UP ;
  101.         ep->window = active ;
  102.         ep->u.where.button = 1 ;
  103.         ep->u.where.h = prev_h ;
  104.         ep->u.where.v = prev_v ;
  105.         ep->u.where.clicks = nr_clicks ;
  106.         mupwaiting = mousedown = FALSE ;
  107.         prev_tick = MSTIME () ;
  108.         return ;
  109.     }
  110.  
  111.     if (lactive != active && active != NULL) {
  112.         ep->type = WE_ACTIVATE ;
  113.         ep->window = active ;
  114.         lactive = active ;
  115.         wind_set (active->handle, WF_TOP, dummy, dummy, dummy, dummy) ;
  116.         return ;
  117.     }
  118.     else
  119.         lactive = active ;
  120.  
  121.     ep->type = WE_NULL ;
  122.  
  123.     do {
  124.         set_timer (ep, &hightime, &lowtime) ;
  125.  
  126.         if (ep->type == WE_TIMER)
  127.             return ;
  128.  
  129.         button_state = 1 - prev_state ;
  130.  
  131.         if (mousedown) {    /* waiting for button up */
  132.             which |= MU_M1 ;
  133.             DOCTOSCR (active, prev_h, prev_v, clickrect.x,
  134.                                 clickrect.y) ;
  135.             clickrect.x -= 1 ;
  136.             clickrect.y -= 1 ;
  137.             clickrect.w = 3 ;
  138.             clickrect.h = 3 ;
  139.         }
  140.         else
  141.             which &= ~MU_M1 ;
  142.  
  143.         if (active != NULL) {
  144.             which |= MU_M2 ;
  145.  
  146.             winrect.x = active->h ;
  147.             winrect.y = active->v ;
  148.             winrect.w = active->width ;
  149.             winrect.h = active->height ;
  150.  
  151.             wininout = shape == THIN_CROSS ;
  152.         }
  153.         else
  154.             which &= ~MU_M2 ;
  155.  
  156.         if (shape != oldshape) {
  157.             oldshape = shape ;
  158.             graf_mouse (shape, &dummy) ;
  159.         } 
  160.  
  161.         if (mouseoff) {
  162.             mouseoff = FALSE ;
  163.             graf_mouse (M_ON, &dummy) ;
  164.         }
  165. /*        longtime = hightime;
  166.         longtime = (longtime) << 16 | lowtime; */
  167.         longtime = lowtime;
  168.         longtime = (longtime << 16) | hightime;
  169.  
  170.         rc = evnt_multi (which,
  171.                  nr_clicks,
  172.                 what_button,
  173.                 button_state,
  174.                 clickinout,
  175.             clickrect.x, clickrect.y,clickrect.w,clickrect.h,
  176.                 wininout,
  177.             winrect.x,winrect.y,winrect.w,winrect.h,
  178.                 msg_buf,
  179. /*                lowtime, 
  180.                 hightime, */
  181.                 longtime,
  182.             mevnt_rec.x,mevnt_rec.y,mevnt_rec.b,mevnt_rec.k,
  183.                 &key_pressed,
  184.                 &nr_times) ;
  185.  
  186.         if (rc & MU_TIMER) {
  187.             do_timer (ep) ;
  188.             if (ep->type != WE_NULL)
  189.                 break ;
  190.         }
  191.  
  192.         if (rc & MU_KEYBD) {
  193.             do_keybd (ep, key_pressed) ;
  194.             if (ep->type != WE_NULL)
  195.                 break ;
  196.         }
  197.  
  198.         if (rc & MU_M1 || rc & MU_BUTTON) {
  199.             do_button (ep, &mevnt_rec) ;
  200.             if (ep->type != WE_NULL)
  201.                 break ;
  202.         }
  203.  
  204.         if (rc & MU_M2) {
  205.             if (!mousedown) {
  206.                 if (shape == ARROW) {
  207.                     oldshape = shape ;
  208.                     shape = THIN_CROSS ;
  209.                 }
  210.                 else {
  211.                     oldshape = shape ;
  212.                     shape = ARROW ;
  213.                 }
  214.             }
  215.         }
  216.  
  217.         if (rc & MU_MESAG) {
  218.             do_messag (ep, msg_buf) ;
  219.         }
  220.     } while (ep->type == WE_NULL) ;
  221. }
  222.  
  223. static WINDOW    *timer_win ;
  224.  
  225. static void
  226. do_timer (ep)
  227.     EVENT    *ep ;
  228. {
  229.     if (find_update (ep))
  230.         return ;
  231.  
  232.     if (timer_win == NULL) {
  233. wdebug ("do_timer: timer event with no timer window|or pending updates") ;
  234.         return ;
  235.     }
  236.  
  237.     ep->type = WE_TIMER ;
  238.     ep->window = timer_win ;
  239.     wsettimer (timer_win, 0) ;
  240. }
  241.  
  242. static bool
  243. find_update (ep)
  244.     EVENT    *ep ;
  245. {
  246.     int    i ;
  247.     bool    rc = FALSE ;
  248.  
  249.     if (active != NULL && active->needupdate) {
  250.         rc = TRUE ;
  251.  
  252.         if (active->drawproc == NULL) {
  253.             ep->type = WE_DRAW ;
  254.             ep->window = active ;
  255.             wgetchange (active, &ep->u.area.left, &ep->u.area.top,
  256.                     &ep->u.area.right, &ep->u.area.bottom) ;
  257.             wupdate (ep->window) ;
  258.             return (rc) ;
  259.         }
  260.         else
  261.             wupdate (active) ;
  262.     }
  263.     for (i = 0; i < nrwin; i++) {
  264.         if (winlist[i] != active && winlist[i]->needupdate) {
  265.             rc = TRUE ;
  266.  
  267.             if (winlist[i]->drawproc == NULL) {
  268.                 ep->type = WE_DRAW ;
  269.                 ep->window = winlist[i] ;
  270.                 wgetchange (winlist[i], &ep->u.area.left,
  271.                             &ep->u.area.top,
  272.                             &ep->u.area.right,
  273.                             &ep->u.area.bottom) ;
  274.                 wupdate (ep->window) ;
  275.                 return (rc) ;
  276.             }
  277.             else
  278.                 wupdate (winlist[i]) ;
  279.         }
  280.     }
  281.  
  282.     return (rc) ;
  283. }
  284.  
  285. static void
  286. set_timer (ep, phightime, plowtime)
  287.     EVENT    *ep ;
  288.     int    *phightime ;
  289.     unsigned int    *plowtime ;
  290. {
  291.     msec    currtime ;
  292.     int    i ;
  293.     bool    pend_updates = FALSE ;
  294.  
  295.     timer_win = NULL ;
  296.  
  297.     currtime = MSTIME () ;
  298.  
  299.     for (i = 0 ; i < nrwin ; i++) {
  300.         WINDOW    *cand = winlist[i] ;
  301.         msec    t = cand->alarm ;
  302.  
  303.         if (t > 0) {
  304.             if (timer_win == NULL || t < timer_win->alarm)
  305.                 timer_win = cand ;
  306.         }
  307.  
  308.         if (cand->needupdate)
  309.             pend_updates = TRUE ;
  310.     }
  311.  
  312.     if (timer_win != NULL) {
  313.         /* window with alarm set found */
  314.  
  315. /*        wdebug ("settimer: timer window found") ;
  316.         wdebug ("alarm:%ld|curr:%ld", timer_win->alarm, currtime) ;
  317. */
  318.         if (timer_win->alarm <= currtime) {
  319.             /* alarm should go of somewhere in the past.
  320.             ** return a timer event from this window
  321.             */
  322.             ep->type = WE_TIMER ;
  323.             ep->window = timer_win ;
  324.             wsettimer (timer_win, 0) ;
  325.         }
  326.         else if (pend_updates == TRUE) {
  327.             /* There are pendings updates. Set the timer on 1 msec
  328.             ** to check that there aren't any events waiting.
  329.             */
  330.             *phightime = 0 ;
  331.             *plowtime = 1 ;
  332.         }
  333.         else {
  334.             /* Set the timer to the alarm time. */
  335.             *phightime = (timer_win->alarm - currtime) >> 16 ;
  336.             *plowtime = (timer_win->alarm - currtime) & 0xffff ;
  337.         }
  338.     }
  339.     else if (pend_updates == TRUE) {
  340.         /* There are pendings updates. Set the timer on 1 msec
  341.         ** to check that there aren't any events waiting.
  342.         */
  343.         *phightime = 0 ;
  344.         *plowtime = 1 ;
  345.     }
  346.     else {
  347.         /* No window found with an alarm set */
  348.         *phightime = 0x7fff ;
  349.         *plowtime = 0xffff ;
  350.     }
  351.  
  352. /*    wdebug ("settimer: h %d l %d", *phightime, *plowtime) ;
  353. */}
  354.  
  355. static void
  356. do_keybd (ep, key)
  357.     EVENT    *ep ;
  358.     int    key ;
  359. {
  360.     int    status ;
  361.  
  362.     vq_key_s (vdi_handle, &status) ;
  363.  
  364.     if (status & 0x08) {
  365.         checksc (ep, key) ;
  366.         return ;
  367.     }
  368.  
  369.     if ((key & 0xFF) == 0) {
  370.  
  371.         /*
  372.         ** 'Special' key: If last  byte is nul then check extract
  373.         ** from the first byte the key number.
  374.         */
  375.         switch (key >> 8) {
  376.         case 0x47 :    /* Clr Home */
  377.             ep->u.command = WC_CLEAR ;
  378.             break ;
  379.         case 0x48 :    /* Cursor Up */
  380.             ep->u.command = WC_UP ;
  381.             break ;
  382.         case 0x4B :    /* Cursor Left */
  383.             ep->u.command = WC_LEFT ;
  384.             break ;
  385.         case 0x4D :    /* Cursor Right */
  386.             ep->u.command = WC_RIGHT ;
  387.             break ;
  388.         case 0x50 :    /* Cursor Down */
  389.             ep->u.command = WC_DOWN ;
  390.             break ;
  391.         case 0x52 :    /* Insert */
  392.             ep->u.command = WC_INS ;
  393.             break ;
  394.         case 0x53 :    /* Delete */
  395.             ep->u.command = WC_DEL ;
  396.             break ;
  397.         case 0x61 :    /* Undo */
  398.             ep->u.command = WC_CANCEL ;
  399.             break ;
  400.         default :
  401.             return ;
  402.         }
  403.  
  404.         ep->type = WE_COMMAND ;
  405.         ep->window = active ;
  406.         return ;
  407.     }
  408.  
  409.     ep->type = WE_COMMAND ;
  410.     ep->window = active ;
  411.  
  412.     switch (key & 0xFF) { 
  413.         case 0x03 :
  414.             ep->u.command = WC_CANCEL ;
  415.             break ;
  416.         case 0x08 :
  417.             ep->u.command = WC_BACKSPACE ;
  418.             break ;
  419.         case 0x09 :
  420.             ep->u.command = WC_TAB ;
  421.             break ;
  422.         case 0x0A :
  423.         case 0x0D :
  424.             ep->u.command = WC_RETURN ;
  425.             break ;
  426.         default :
  427.             ep->type = WE_CHAR ;
  428.             ep->window = active ;
  429.             ep->u.character = key & 0xFF ;
  430.             break ;
  431.     }
  432. }
  433.  
  434. static void
  435. do_button (ep, mrec)
  436.     EVENT    *ep ;
  437.     Mouse    *mrec ;
  438. {
  439.     WINDOW    *win = active ;
  440.     msec    tick ;
  441.     int    h ;
  442.     int    v ;
  443.     int    dh ;
  444.     int    dv ;
  445.  
  446.     if (win == NULL ||
  447.         ((*mrec->x < win->h || *mrec->x > win->h + win->width ||
  448.           *mrec->y < win->v || *mrec->y > win->v + win->height) &&
  449.          !mousedown))
  450.         return ;
  451.  
  452.     tick = MSTIME () ;
  453.     while (tick < prev_tick)
  454.         prev_tick -= 10*0x8000L ;
  455.  
  456.     SCRTODOC (win, *mrec->x, *mrec->y, h, v) ;
  457.  
  458.     dh = h - prev_h ;
  459.     dv = v - prev_v ;
  460.  
  461.     if (dh*dh+dv*dv > DIST_CLICK*DIST_CLICK) {
  462.         nr_clicks = 0 ;
  463.     }
  464.  
  465.     if (prev_state == 1) {
  466.         if (!(*mrec->b & 0x01)) {    /* Mouse up event */
  467.             ep->type = WE_MOUSE_UP ;
  468.             ep->u.where.button = 1 ;    /* Till now only the
  469.                             ** leftmost button is
  470.                             ** detected
  471.                             */
  472.             mousedown = FALSE ;
  473.         }
  474.         else {
  475.             if (nr_clicks > 0 || dh*dh+dv*dv == 0)
  476.                 return ;
  477.             else {
  478.                 if (*mrec->x < win->h ||
  479.                     *mrec->x > win->h + win->width ||
  480.                     *mrec->y < win->v ||
  481.                     *mrec->y > win->v + win->height)
  482.                     autoscroll (win, *mrec->x, *mrec->y) ;
  483.     
  484.                 ep->type = WE_MOUSE_MOVE ;
  485.                 ep->u.where.button = 1 ;
  486.             }
  487.         }
  488.     }
  489.     else {
  490.         if (!(*mrec->b & 0x01))
  491.             mupwaiting = TRUE ;
  492.  
  493.         if (tick - prev_tick <= CLICK_TICKS)
  494.             ++nr_clicks ;
  495.         else
  496.             nr_clicks = 1 ;
  497.  
  498.         ep->type = WE_MOUSE_DOWN ;
  499.         ep->u.where.button = 1 ;
  500.         mousedown = TRUE ;
  501.     }
  502.  
  503.     ep->window = win ;
  504.     ep->u.where.h = prev_h = h ;
  505.     ep->u.where.v = prev_v = v ;
  506.     ep->u.where.clicks = nr_clicks ;
  507.  
  508.     prev_tick = tick ;
  509.     prev_state = *mrec->b & 0x01 ;
  510. }
  511.  
  512. static void
  513. do_messag (ep, msg_buf)
  514.     EVENT    *ep ;
  515.     int    msg_buf[8] ;
  516. {
  517.     switch (msg_buf[0]) {
  518.         case MN_SELECTED :
  519. /*            wdebug ("Menu selected") ;
  520. */            do_menu(ep, msg_buf) ;
  521.             break ;
  522.         case WM_REDRAW :
  523. /*            wdebug ("Redraw wanted") ;
  524. */            do_redraw (msg_buf) ;
  525.             break ;
  526.         case WM_TOPPED :
  527. /*            wdebug ("New active window") ;
  528. */            do_topped (ep, msg_buf) ;
  529.             break ;
  530.         case WM_CLOSED :
  531. /*            wdebug ("Window closed") ;
  532. */            do_closed (ep, msg_buf) ;
  533.             break ;
  534.         case WM_FULLED :
  535.         case WM_SIZED :
  536.         case WM_MOVED :
  537. /*            wdebug ("Window position changed") ;
  538. */            do_size (ep, msg_buf) ;
  539.             break ;
  540.         case WM_ARROWED :
  541.         case WM_HSLID :
  542.         case WM_VSLID :
  543. /*            wdebug ("Window scrolled") ;
  544. */            do_scroll (msg_buf) ;
  545.             break ;
  546.     }
  547. }
  548.  
  549. static void
  550. do_redraw (msg_buf)
  551.     int    msg_buf[8] ;
  552. {
  553.     WINDOW    *win ;
  554.     int    changed[4] ;
  555.     int    work[4] ;
  556.  
  557.     win = getwin (msg_buf[3]) ;
  558.  
  559.     if (win == NULL) {
  560.         wdebug ("do_redraw: window %d doesn't belong to me", msg_buf[3]) ;
  561.         return ;
  562.     }
  563.  
  564.     SCRTODOC (win, msg_buf[4], msg_buf[5], changed[0], changed[1]) ;
  565.  
  566.     changed[2] = changed[0] + msg_buf[6] ;
  567.     changed[3] = changed[1] + msg_buf[7] ;
  568.  
  569.     wgetwinorigin (win, &work[0], &work[1]) ;
  570.     wgetwinsize (win, &work[2], &work[3]) ;
  571.  
  572.     work[2] += work[0] ;
  573.     work[3] += work[1] ;
  574.  
  575.     if (!intersect (work, changed))
  576.         return ;
  577.  
  578.     wchange (win, changed[0], changed[1], changed[2], changed[3]) ;
  579. }
  580.  
  581. static void
  582. do_topped (ep, msg_buf)
  583.     EVENT    *ep ;
  584.     int    msg_buf[8] ;
  585. {
  586.     WINDOW    *win = getwin (msg_buf[3]) ;
  587.     int    dummy = 0 ;
  588.  
  589.     if (win == NULL) {
  590.         wdebug ("do_topped: window doesn't belong to me") ;
  591.         return ;
  592.     }
  593.  
  594.     ep->type = WE_ACTIVATE ;
  595.     ep->window = win ;
  596.     wsetactive (win) ;
  597.     lactive = active ;
  598. }
  599.  
  600. static void
  601. do_closed (ep, msg_buf)
  602.     EVENT    *ep ;
  603.     int    msg_buf[8] ;
  604. {
  605.     WINDOW    *win = getwin (msg_buf[3]) ;
  606.  
  607.     if (win == NULL) {
  608.         wdebug ("do_closed: window doesn't belong to me") ;
  609.         return ;
  610.     }
  611.  
  612.     ep->type = WE_COMMAND ;
  613.     ep->window = win ;
  614.     ep->u.command = WC_CLOSE ;
  615. }
  616.  
  617. static void
  618. do_size (ep, msg_buf)
  619.     EVENT    *ep ;
  620.     int    msg_buf[8] ;
  621. {
  622.     WINDOW    *win = getwin (msg_buf[3]) ;
  623.     int    orgh = win->orgh ;
  624.     int    orgv = win->orgv ;
  625.     int    h ;
  626.     int    v ;
  627.     int    width ;
  628.     int    height ;
  629.  
  630.     if (win == NULL) {
  631.         wdebug ("do_sized: window doesn't belong to me") ;
  632.         return ;
  633.     }
  634.  
  635.     if (msg_buf[0] == WM_FULLED) {
  636.         if (win->fulled) { 
  637.             wind_get (win->handle, WF_PREVXYWH, &h, &v, &width,
  638.                                 &height) ;
  639.             win->fulled = FALSE ;
  640.         }
  641.         else {
  642.             wind_get (win->handle, WF_FULLXYWH, &h, &v, &width,
  643.                                 &height) ;
  644.             win->fulled = TRUE ;
  645.         }
  646.     }
  647.     else {
  648.         h    = msg_buf[4] ;
  649.         v    = msg_buf[5] ;
  650.         width    = msg_buf[6] ;
  651.         height    = msg_buf[7] ;
  652.         win->fulled = FALSE ;
  653.     }
  654.  
  655.     if (!wind_set (win->handle, WF_CURRXYWH, h, v, width, height)) {
  656.         wdebug ("do_sized: wind_set") ;
  657.         return ;
  658.     }
  659.     _setsize (win, h, v, width, height) ;
  660.  
  661.     if (win->orgh + win->width > win->doc_width + 10)
  662.         orgh = win->doc_width - win->width + 10 ;
  663.  
  664.     if (win->orgv + win->height > win->doc_height + wlineheight ())
  665.         orgv = win->doc_height - win->height + wlineheight () ;
  666.  
  667.     wsetorigin (win, orgh, orgv) ;
  668.     setscrollbars (win) ;
  669.  
  670.     if (msg_buf[0] != WM_MOVED) {
  671.         ep->type = WE_SIZE ;
  672.         ep->window = win ;
  673.     }
  674.  
  675.     {
  676.         int x, y, w, he ;
  677.  
  678.         wind_get (win->handle, WF_CURRXYWH, &x, &y, &w, &he) ;
  679.         if (x != h)
  680.             wdebug ("x %d %d", h, x) ;
  681.         if (y != v)
  682.             wdebug ("y %d %d", v, y) ;
  683.         if (w != width)
  684.             wdebug ("w %d %d", width, w) ;
  685.         if (he != height)
  686.             wdebug ("h %d %d", height, he) ;
  687.     }
  688. }
  689.