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 / scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-29  |  7.5 KB  |  370 lines

  1. #include "window.h"
  2. #include "trees.h"
  3. #include "atari_proto.h"
  4. #undef P
  5.  
  6. extern int    vdi_handle ;
  7.  
  8. bool
  9. getsrcdiff (win, RECT, dh, dv, snit, diff, nr_diff)
  10.     WINDOW    *win ;
  11.     int    RECT ;
  12.     int    dh ;
  13.     int    dv ;
  14.     int    *snit ;
  15.     int    diff[][4] ;
  16.     int    *nr_diff ;
  17. {
  18.     int    src[4] = { left, top, right, bottom } ;
  19.     int    orgh = win->orgh ;
  20.     int    orgv = win->orgv ;
  21.     int    width = win->width ;
  22.     int    height = win->height ;
  23.  
  24.     if (dh > 0)
  25.         src[2] -= dh ;
  26.     if (dh < 0)
  27.         src[0] -= dh ;
  28.  
  29.     if (dv > 0)
  30.         src[3] -= dv ;
  31.     if (dv < 0)
  32.         src[1] -= dv ;
  33.  
  34.     /*
  35.     ** Clip the rectangle with the window to get the clean source ...
  36.     */
  37.  
  38.     snit[0] = orgh ;
  39.     snit[1] = orgv ;
  40.     snit[2] = orgh + width ;
  41.     snit[3] = orgv + height ;
  42. /*wdebug ("      l   r   t   b|src  %3d %3d %3d %3d|snit %3d %3d %3d %3d", src[0],
  43.     src[1], src[2], src[3], snit[0], snit[1], snit[2], snit[3]) ;
  44. */    if (!intersect (src, snit)) {
  45. /*wdebug ("no intersection") ;
  46. */        *nr_diff = 1 ;
  47.         diff[0][0] = orgh - dh ;
  48.         diff[0][1] = orgv - dv ;
  49.         diff[0][2] = orgh + width - dh ;
  50.         diff[0][3] = orgv + height - dv ;
  51.  
  52.         return (FALSE) ;
  53.     }
  54. /*wdebug ("      l   r   t   b|src  %3d %3d %3d %3d|snit %3d %3d %3d %3d", src[0],
  55.     src[1], src[2], src[3], snit[0], snit[1], snit[2], snit[3]) ;
  56. */    rectsubt (src, snit, diff, nr_diff) ;
  57.  
  58.     return (TRUE) ;
  59. }
  60.  
  61. void
  62. scrollby (win, RECT, dh, dv)
  63.     WINDOW    *win ;
  64.     int    RECT ;
  65.     int    dh ;
  66.     int    dv ;
  67. {
  68.     FDB    dummy = { 0L, 0, 0, 0, 0, 0, 0, 0, 0 } ;
  69.     int    logic = 3 ;
  70.     int    xyarray[8] ;
  71.     bool    mouseoff = FALSE ;
  72.     int    status ;
  73.     int    m_h ;
  74.     int    m_v ;
  75.  
  76.     DOCTOSCR (win, left, top, xyarray[0], xyarray[1]) ;
  77.     DOCTOSCR (win, right - 1, bottom - 1, xyarray[2], xyarray[3]) ;
  78.  
  79.     DOCTOSCR (win, left + dh, top + dv, xyarray[4], xyarray[5]) ;
  80.     DOCTOSCR (win, right + dh - 1, bottom + dv - 1, xyarray[6], xyarray[7]) ;
  81.  
  82.     vq_mouse (vdi_handle, &status, &m_h, &m_v) ;
  83.  
  84.     if (m_h > win->h - wlineheight () &&
  85.         m_h < win->h + win->width + wlineheight () &&
  86.         m_v > win->v - 2 * wcharwidth ('m') &&
  87.         m_v < win->v + win->height + 2 * wcharwidth ('m')) {
  88.         mouseoff = TRUE ;
  89.         graf_mouse (M_OFF, &dummy) ;
  90.     }
  91.  
  92.     wind_update (BEG_UPDATE) ;
  93.  
  94.     setclip (win, 1, win->orgh, win->orgv, win->orgh + win->width,
  95.                         win->orgv + win->height) ;
  96.  
  97.     vro_cpyfm (vdi_handle, logic, xyarray, &dummy, &dummy) ;
  98.  
  99.     setclip (win, 0, win->orgh, win->orgv, win->orgh + win->width,
  100.                         win->orgv + win->height) ;
  101.  
  102.     wind_update (END_UPDATE) ;
  103.  
  104.     if (mouseoff)
  105.         graf_mouse (M_ON, &dummy) ;
  106. }
  107.  
  108. void
  109. wscroll (win, RECT, dh, dv)
  110.     WINDOW    *win ;
  111.     int    RECT ;
  112.     int    dh ;
  113.     int    dv ;
  114. {
  115.     int    src[4] ;
  116.     int    diff[4][4] ;
  117.     int    nr_diff ;
  118.     int    i ;
  119.     int    changed[4] ;
  120.  
  121.     if (win == NULL) {
  122.         wdebug ("wscroll: illegal window pointer") ;
  123.         return ;
  124.     }
  125.  
  126.     rmcaret () ;
  127.  
  128.     if (left >= right || top >= bottom || (dh == 0 && dv == 0))
  129.         return ;
  130.  
  131.     if (getsrcdiff (win, RECT, dh, dv, src, diff, &nr_diff))
  132.         scrollby (win, src[0], src[1], src[2], src[3], dh, dv) ;
  133.  
  134.     wgetchange (win, &changed[0], &changed[1], &changed[2], &changed[3]) ;
  135.     if (intersect (src, changed))
  136.         wchange (win, changed[0] + dh, changed[1] + dv,
  137.                 changed[2] + dh, changed[3] + dv) ;
  138.  
  139.     for (i = 0 ; i < nr_diff ; i++) {
  140.         wchange (win, diff[i][0] + dh, diff[i][1] + dv,
  141.                 diff[i][2] + dh, diff[i][3] + dv) ;
  142.     }
  143.  
  144.     showcaret () ;
  145.  
  146.     wupdate (win) ;
  147. }
  148.  
  149. void
  150. setscrollbars (win)
  151.     WINDOW    *win ;
  152. {
  153.     int    dummy ;
  154.     int    old ;
  155.     int    size ;
  156.     int    pos ;
  157.     int    win_width = win->width ;
  158.     int    win_height = win->height;
  159.     int    doc_width = win->doc_width ;
  160.     int    doc_height = win->doc_height ;
  161.     int    orgh = win->orgh ;
  162.     int    orgv = win->orgv ;
  163.  
  164.     if (doc_width <= win_width) {
  165.         size = 1000 ;
  166.         pos = 0 ;
  167.     }
  168.     else {
  169.         size = (long) win_width * 1000L / (long) doc_width ;
  170.         pos = (long) orgh * 1000L / (long) (doc_width - win_width) ;
  171.     }
  172.  
  173.     if (size > 1000)
  174.         size = 1000 ;
  175.  
  176.     wind_get (win->handle, WF_HSLIDE, &old, &dummy, &dummy, &dummy) ;
  177.     if (old != pos)
  178.         wind_set (win->handle, WF_HSLIDE, pos, dummy, dummy, dummy) ;
  179.     wind_get (win->handle, WF_HSLSIZE, &old, &dummy, &dummy, &dummy) ;
  180.     if (old != size)
  181.         wind_set (win->handle, WF_HSLSIZE, size, dummy, dummy, dummy) ;
  182.  
  183.     if (doc_height <= win_height) {
  184.         size = 1000 ;
  185.         pos = 0 ;
  186.     }
  187.     else {
  188.         size = win_height * 1000L / (long) doc_height ;
  189.         pos = orgv * 1000L / (long) (doc_height - win_height) ;
  190.     }
  191.  
  192.     if (size > 1000)
  193.         size = 1000 ;
  194.  
  195.     wind_get (win->handle, WF_VSLIDE, &old, &dummy, &dummy, &dummy) ;
  196.     if (old != pos)
  197.         wind_set (win->handle, WF_VSLIDE, pos, dummy, dummy, dummy) ;
  198.     wind_get (win->handle, WF_VSLSIZE, &old, &dummy, &dummy, &dummy) ;
  199.     if (old != size)
  200.         wind_set (win->handle, WF_VSLSIZE, size, dummy, dummy, dummy) ;
  201. }
  202.  
  203. void
  204. do_scroll (msg_buf)
  205.     int    msg_buf[8] ;
  206. {
  207. #define HOR_STEP    (width / 10 <= 0 ? wcharwidth ('m') :\
  208.                             width / 10)
  209.  
  210.     WINDOW    *win = getwin (msg_buf[3]) ;
  211.     int    orgh = win->orgh ;
  212.     int    orgv = win->orgv ;
  213.     int    width = win->width ;
  214.     int    height = win->height ;
  215.     int    dummy = 0 ;
  216.  
  217.     if (win == NULL) {
  218.         wdebug ("do_scroll: window doesn't belong to me") ;
  219.         return ;
  220.     }
  221.  
  222.     if (msg_buf[0] == WM_ARROWED) {
  223.         switch (msg_buf[4]) {
  224.         case 0 :    /* Page up */
  225.             orgv -= (height - wlineheight ()) ;
  226.             break ;
  227.         case 1 :    /* Page down */
  228.             orgv += (height - wlineheight ()) ;
  229.             break ;
  230.         case 2 :    /* Arrow up */
  231.             orgv -= wlineheight () ;
  232.             break ;
  233.         case 3 :    /* Arrow down */
  234.             orgv += wlineheight () ;
  235.             break ;
  236.         case 4 :    /* Page left */
  237.             orgh -= (width - HOR_STEP) ;
  238.             break ;
  239.         case 5 :    /* Page right */
  240.             orgh += (width - HOR_STEP) ;
  241.             break ;
  242.         case 6 :    /* Arrow left */
  243.             orgh -= HOR_STEP ;
  244.             break ;
  245.         case 7 :    /* Arrow right */
  246.             orgh += HOR_STEP ;
  247.             break ;
  248.         }
  249.     }
  250.     else if (msg_buf[0] == WM_HSLID)
  251.         orgh = (long) msg_buf[4] * (long) (win->doc_width - width)
  252.                                 / 1000L ;
  253.     else
  254.         orgv = (long) msg_buf[4] * (long) (win->doc_height - height)
  255.                                 / 1000L;
  256.  
  257.     wsetorigin (win, orgh, orgv) ;
  258.  
  259. #undef HOR_STEP
  260. }
  261.  
  262. void 
  263. rectsubt (a, b, diff, nr_diff)
  264.     int    *a ;
  265.     int    *b ;
  266.     int    diff[][4] ;
  267.     int    *nr_diff ;
  268. {
  269.     int    i = 0 ;
  270.  
  271.     *nr_diff = 0 ;
  272. /*wdebug ("   l   t   r   b|a %3d %3d %3d %3d|b %3d %3d %3d %3d", a[0], a[1],
  273.     a[2], a[3], b[0], b[1], b[2], b[3]) ;
  274. */    if (a[LEFT] < b[LEFT]) {
  275. /*wdebug ("left") ;
  276. */        diff[i][LEFT] = a[LEFT] ;
  277.         diff[i][TOP] = a[TOP] ;
  278.         diff[i][RIGHT] = b[LEFT] ;
  279.         diff[i][BOTTOM] = a[BOTTOM] ;
  280.         i++ ;
  281.  
  282.         if (a[RIGHT] < b[LEFT]) {
  283. /*wdebug ("outside") ;
  284. */            diff[i - 1][RIGHT] = a[RIGHT] ;
  285.             *nr_diff = i ;
  286.             return ;
  287.         }
  288.     }
  289.  
  290.     if (a[RIGHT] > b[RIGHT]) {
  291. /*wdebug ("right") ;
  292. */        diff[i][LEFT] = b[RIGHT] ;
  293.         diff[i][TOP] = a[TOP] ;
  294.         diff[i][RIGHT] = a[RIGHT] ;
  295.         diff[i][BOTTOM] = a[BOTTOM] ;
  296.         i += 1 ;
  297.  
  298.         if (a[LEFT] > b[RIGHT]) {
  299. /*wdebug ("outside") ;
  300. */            diff[i - 1][LEFT] = a[LEFT] ;
  301.             *nr_diff = i ;
  302.             return ;
  303.         }
  304.     }
  305.  
  306.     if (a[TOP] < b[TOP]) {
  307. /*wdebug ("top") ;
  308. */        diff[i][LEFT] = a[LEFT] ;
  309.         diff[i][TOP] = a[TOP] ;
  310.         diff[i][RIGHT] = a[RIGHT] ;
  311.         diff[i][BOTTOM] = b[TOP] ;
  312.         i += 1 ;
  313.  
  314.         if (a[BOTTOM] < b[TOP]) {
  315. /*wdebug ("outside") ;
  316. */            diff[i - 1][BOTTOM] = a[BOTTOM] ;
  317.             *nr_diff = i ;
  318.             return ;
  319.         }
  320.     }
  321.  
  322.     if (a[BOTTOM] > b[BOTTOM]) {
  323. /*wdebug ("bottom") ;
  324. */        diff[i][LEFT] = a[LEFT] ;
  325.         diff[i][TOP] = b[BOTTOM] ;
  326.         diff[i][RIGHT] = a[RIGHT] ;
  327.         diff[i][BOTTOM] = a[BOTTOM] ;
  328.         i += 1 ;
  329.  
  330.         if (a[TOP] > b[BOTTOM]) {
  331. /*wdebug ("outside") ;
  332. */            diff[i - 1][TOP] = a[TOP] ;
  333.             *nr_diff = i ;
  334.             return ;
  335.         }
  336.     }
  337. /*wdebug ("nr rect %d", i) ;
  338. */    *nr_diff = i ;
  339. }
  340.  
  341. void
  342. autoscroll (win, h, v)
  343.     WINDOW    *win ;
  344.     int    h ;
  345.     int    v ;
  346. {
  347.     int    dh = 0 ;
  348.     int    dv = 0 ;
  349.  
  350.     if (win == NULL)
  351.         return ;
  352.  
  353.     if (h < win->h)
  354.         dh = h - win->h ;
  355.     else if (h > win->h + win->width)
  356.         dh = h - (win->h + win->width) ;
  357.  
  358.     if (v < win->v)
  359.         dv = v - win->v ;
  360.     else if (v > win->v + win->height)
  361.         dv = v - (win->v + win->height) ;
  362.  
  363.     if (dh != 0 || dv != 0) {
  364.         int    orgh = win->orgh + dh ;
  365.         int    orgv = win->orgv + dv ;
  366.  
  367.         wsetorigin (win, orgh, orgv) ;
  368.     }
  369. }
  370.