home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Ports / alfa / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-05  |  10.1 KB  |  656 lines  |  [TEXT/????]

  1. /* ALFA STDWIN -- DRAWING. */
  2.  
  3. #include "alfa.h"
  4.  
  5. static char *textline[MAXLINES];
  6. static char *modeline[MAXLINES];
  7. static short textlen[MAXLINES];
  8. static char texttouched[MAXLINES];
  9.  
  10. static TEXTATTR draw_saveattr;
  11. static WINDOW *draw_win;
  12.  
  13. /* Cause a redraw of part of a window. */
  14.  
  15. /*ARGSUSED*/
  16. void
  17. wchange(win, left, top, right, bottom)
  18.     WINDOW *win;
  19.     int left, top;
  20.     int right, bottom;
  21. {
  22.     int id= win - winlist;
  23.     int i;
  24.     
  25.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  26.         return;
  27.     top -= win->offset;
  28.     bottom -= win->offset;
  29.     if (top < win->top)
  30.         top= win->top;
  31.     if (bottom > win->bottom)
  32.         bottom= win->bottom;
  33.     for (i= top; i < bottom; ++i)
  34.         uptodate[i]= FALSE;
  35.     _wnewtitle(win);
  36. }
  37.  
  38. /* (Try to) make sure a particular part of a window is visible,
  39.    by scrolling in distant parts if necessary. */
  40.  
  41. void scrollupdate();
  42.  
  43. /*ARGSUSED*/
  44. void
  45. wshow(win, left, top, right, bottom)
  46.     WINDOW *win;
  47.     int left, top;
  48.     int right, bottom;
  49. {
  50.     int id= win - winlist;
  51.     int offset;
  52.     int extra;
  53.     int dv;
  54.     
  55.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  56.         return;
  57.     extra= ( (win->bottom - win->top) - (bottom - top) ) / 2;
  58.     if (extra < 0)
  59.         extra= 0;
  60.     offset= win->offset;
  61.     if (bottom > win->bottom + offset)
  62.         offset= bottom - win->bottom + extra;
  63.     if (top < win->top + offset)
  64.         offset= top - win->top - extra;
  65.     if (win->top + offset < 0)
  66.         offset= -win->top;
  67.     dv= offset - win->offset;
  68.     if (dv == 0)
  69.         return;
  70.     win->offset= offset;
  71.     /* Now we'll use top, bottom to indicate the changed part. */
  72.     top= win->top;
  73.     bottom= win->bottom;
  74.     scrollupdate(top, bottom, dv);
  75.     trmscrollup(top, bottom-1, dv);
  76. }
  77.  
  78. /* Similar, but by giving an explicit new origin */
  79.  
  80. /*ARGSUSED*/
  81. void
  82. wsetorigin(win, h, v)
  83.     WINDOW *win;
  84.     int h, v;
  85. {
  86.     int id= win - winlist;
  87.     int top, bottom;
  88.     int dv;
  89.  
  90.     if (id < 0 || id >= MAXWINDOWS || !win->open)
  91.         return;
  92.     dv = (v - win->top) - win->offset;
  93.     if (dv == 0)
  94.         return;
  95.     win->offset += dv;
  96.     top = win->top;
  97.     bottom = win->bottom;
  98.     scrollupdate(top, bottom, dv);
  99.     trmscrollup(top, bottom-1, dv);
  100. }
  101.  
  102. /* Scroll the update bits */
  103.  
  104. /*ARGSUSED*/
  105. void
  106. scrollupdate(top, bottom, dv)
  107.     int top, bottom;
  108.     int dv;
  109. {
  110.     int i;
  111.  
  112. #ifndef EUROGEMODDER
  113.     for (i= top; i < bottom; ++i)
  114.         uptodate[i] = FALSE;
  115. #else
  116.     /* XXX This code was never fixed to update the mode array */
  117.     char *p;
  118.  
  119.     if(dv==0)
  120.         return;
  121.     if(dv > 0) {
  122.         for (i= top; i < bottom; ++i) {
  123.             if (uptodate[i+dv]) {
  124.                 p=textline[i];
  125.                 textline[i]=textline[i+dv];
  126.                 textlen[i]=textlen[i+dv];
  127.                 uptodate[i]= TRUE;
  128.                 textline[i+dv]= p;
  129.                 /*needed? textlen[i+dv]= 0; */
  130.                 uptodate[i+dv]= FALSE;
  131.             } else {
  132.                 uptodate[i]= FALSE;
  133.             }
  134.         }
  135.     } else {
  136.         for (i= bottom-1; i >= top; --i) {
  137.             if (uptodate[i+dv]) {
  138.                 p=textline[i];
  139.                 textline[i]=textline[i+dv];
  140.                 textlen[i]=textlen[i+dv];
  141.                 uptodate[i]= TRUE;
  142.                 textline[i+dv]= p;
  143.                 /*needed? textlen[i+dv]= 0; */
  144.                 uptodate[i+dv]= FALSE;
  145.             } else {
  146.                 uptodate[i]= FALSE;
  147.             }
  148.         }
  149.     }
  150. #endif
  151. }
  152.  
  153. /* Set the caret (cursor) position. */
  154.  
  155. void
  156. wsetcaret(win, h, v)
  157.     WINDOW *win;
  158.     int h, v;
  159. {
  160.     win->curh= h;
  161.     win->curv= v;
  162.     /* wshow(win, h, v, h+1, v+1); */
  163.     /* Shouldn't call wshow here -- it's not always desirable! */
  164. }
  165.  
  166. /* Remove the caret altogether. */
  167.  
  168. void
  169. wnocaret(win)
  170.     WINDOW *win;
  171. {
  172.     win->curh= win->curv= -1;
  173. }
  174.  
  175. /* Cause a redraw of the window 's title bar. */
  176.  
  177. void
  178. _wnewtitle(win)
  179.     WINDOW *win;
  180. {
  181.     if (win->top > 0)
  182.         uptodate[win->top-1]= FALSE;
  183. }
  184.  
  185. /* Compute the smallest rectangle that needs an update.
  186.    As a side effect, uptodate is set to TRUE for the affected lines,
  187.    and the lines are cleared and set to touched
  188.    (but no actual output is performed).
  189.    Return FALSE if the rectangle is empty. */
  190.  
  191. bool
  192. wgetchange(win, pleft, ptop, pright, pbottom)
  193.     WINDOW *win;
  194.     int *pleft, *ptop, *pright, *pbottom;
  195. {
  196.     int top= win->bottom;
  197.     int bottom= win->top;
  198.     int i;
  199.     
  200.     for (i= win->top; i < win->bottom; ++i) {
  201.         if (!uptodate[i]) {
  202.             texttouched[i]= TRUE;
  203.             textlen[i]= 0;
  204.             uptodate[i]= TRUE;
  205.             if (top > i)
  206.                 top= i;
  207.             bottom= i+1;
  208.         }
  209.     }
  210.     if (top > bottom) {
  211.         *pleft= *pright= *ptop= *pbottom= 0;
  212.         return FALSE;
  213.     }
  214.     else {
  215.         *pleft= 0;
  216.         *pright= columns;
  217.         *ptop= top + win->offset;
  218.         *pbottom= bottom + win->offset;
  219.         return TRUE;
  220.     }
  221. }
  222.  
  223. void
  224. wupdate(win)
  225.     WINDOW *win;
  226. {
  227.     int left, top, right, bottom;
  228.     
  229.     wgetchange(win, &left, &top, &right, &bottom);
  230.     
  231.     wbegindrawing(win);
  232.     
  233.     if (win->drawproc != NULL)
  234.         (*win->drawproc)(win, 0, top, columns, bottom);
  235.     
  236.     wenddrawing(win);
  237. }
  238.  
  239. void
  240. wbegindrawing(win)
  241.     WINDOW *win;
  242. {
  243.     int i, j;
  244.     
  245.     if (draw_win != NULL)
  246.         wenddrawing(draw_win); /* Finish previous job */
  247.     
  248.     /* Auto-initialization of the textline and modeline array.
  249.        The other arrays needn't be initialized,
  250.        since they are preset to zero. */
  251.     /* XXX Crash if malloc() fails! */
  252.     for (i= win->top; i < win->bottom; ++i) {
  253.         if (textline[i] == NULL)
  254.             textline[i]= malloc((unsigned) (columns+1));
  255.         if (modeline[i] == NULL) {
  256.             modeline[i]= malloc((unsigned) columns);
  257.             for (j = 0; j < columns; j++)
  258.                 modeline[i][j] = PLAIN;
  259.         }
  260.     }
  261.     
  262.     draw_saveattr= wattr;
  263.     wattr= win->attr;
  264.     draw_win= win;
  265. }
  266.  
  267. void
  268. wenddrawing(win)
  269.     WINDOW *win;
  270. {
  271.     int i;
  272.     
  273.     if (draw_win != win) {
  274.         return; /* Bad call */
  275.     }
  276.     
  277.     for (i= win->top; i < win->bottom; ++i) {
  278.         if (texttouched[i]) {
  279.             texttouched[i]= FALSE;
  280.             textline[i][textlen[i]]= EOS;
  281.             trmputdata(i, i, 0, textline[i], modeline[i]);
  282.         }
  283.     }
  284.     
  285.     wattr= draw_saveattr;
  286.     draw_win= NULL;
  287. }
  288.  
  289. void
  290. wdrawtitle(win)
  291.     WINDOW *win;
  292. {
  293.     int titline= win->top - 1;
  294.     char buf[256];
  295.     char *title= win->title == NULL ? "" : win->title;
  296.     int tlen= strlen(title);
  297.     int space= columns-tlen;
  298.     int mask= (win == front) ? 0200 : 0;
  299.     int k;
  300.     
  301.     for (k= 0; k < space/2 - 1; ++k)
  302.         buf[k]= '-';
  303.     buf[k++]= ' ';
  304.     while (k < columns && *title != EOS)
  305.         buf[k++]= *title++;
  306.     if (k < columns)
  307.         buf[k++]= ' ';
  308.     while (k < columns)
  309.         buf[k++]= '-';
  310.     buf[k]= EOS;
  311.     if (win == front) {
  312.         char mode[256];
  313.         int i;
  314.         for (i = 0; i < k; i++)
  315.             mode[i] = STANDOUT;
  316.         trmputdata(titline, titline, 0, buf, mode);
  317.     }
  318.     else {
  319.         trmputdata(titline, titline, 0, buf, (char *)0);
  320.     }
  321.     uptodate[titline]= TRUE;
  322. }
  323.  
  324. void
  325. wdrawtext(h, v, str, len)
  326.     int h, v;
  327.     char *str;
  328.     int len;
  329. {
  330.     int k;
  331.     int flag= (wattr.style == 0) ? PLAIN : STANDOUT;
  332.     char *text;
  333.     char *mode;
  334.     WINDOW *win= draw_win;
  335.     
  336.     if (len < 0)
  337.         len= strlen(str);
  338.     v -= win->offset;
  339.     if (v < win->top || v >= win->bottom || h >= columns || len == 0)
  340.         return;
  341.     text= textline[v];
  342.     mode= modeline[v];
  343.     k= textlen[v];
  344.     for (; k < h; k++) {
  345.         text[k]= ' ';
  346.         mode[k]= PLAIN;
  347.     }
  348.     while (len > 0) {
  349. #define APPC(c) \
  350.     if (h >= 0) {text[h]= (c); mode[h]= flag;} if (++h >= columns) break
  351.         unsigned char c= *str++;
  352.         --len;
  353.         if (c < ' ') {
  354.             APPC('^');
  355.             APPC(c | '@');
  356.         }
  357.         else  if (c < 0177) {
  358.             APPC(c);
  359.         }
  360.         else if (c < 0200) {
  361.             APPC('^');
  362.             APPC('?');
  363.         }
  364.         else {
  365.             APPC('\\');
  366.             APPC('0' | ((c>>6) & 07));
  367.             APPC('0' | ((c>>3) & 07));
  368.             APPC('0' | (c & 07));
  369.         }
  370. #undef APPC
  371.     }
  372.     if (h > textlen[v])
  373.         textlen[v]= h;
  374.     texttouched[v]= TRUE;
  375. }
  376.  
  377. void
  378. wdrawchar(h, v, c)
  379.     int h, v;
  380.     int c;
  381. {
  382.     char cbuf[2];
  383.     cbuf[0]= c;
  384.     cbuf[1]= EOS;
  385.     wdrawtext(h, v, cbuf, 1);
  386. }
  387.  
  388. void
  389. wgetwintextattr(win, attr)
  390.     WINDOW *win;
  391.     TEXTATTR *attr;
  392. {
  393.     *attr= win->attr;
  394. }
  395.  
  396. void
  397. wsetwintextattr(win, attr)
  398.     WINDOW *win;
  399.     TEXTATTR *attr;
  400. {
  401.     win->attr= *attr;
  402. }
  403.  
  404. /* Non-text drawing dummy functions: */
  405.  
  406. /*ARGSUSED*/
  407. void
  408. wdrawline(h1, v1, h2, v2)
  409.     int h1, v1, h2, v2;
  410. {
  411. }
  412.  
  413. /*ARGSUSED*/
  414. void
  415. wxorline(h1, v1, h2, v2)
  416.     int h1, v1, h2, v2;
  417. {
  418. }
  419.  
  420. /*ARGSUSED*/
  421. void
  422. wdrawcircle(h, v, radius)
  423.     int h, v;
  424.     int radius;
  425. {
  426. }
  427.  
  428. /*ARGSUSED*/
  429. void
  430. wfillcircle(h, v, radius)
  431.     int h, v;
  432.     int radius;
  433. {
  434. }
  435.  
  436. /*ARGSUSED*/
  437. void
  438. wxorcircle(h, v, radius)
  439.     int h, v;
  440.     int radius;
  441. {
  442. }
  443.  
  444. /*ARGSUSED*/
  445. void
  446. wdrawelarc(h, v, radh, radv, ang1, ang2)
  447.     int h, v;
  448.     int radh, radv;
  449.     int ang1, ang2;
  450. {
  451. }
  452.  
  453. /*ARGSUSED*/
  454. void
  455. wfillelarc(h, v, radh, radv, ang1, ang2)
  456.     int h, v;
  457.     int radh, radv;
  458.     int ang1, ang2;
  459. {
  460. }
  461.  
  462. /*ARGSUSED*/
  463. void
  464. wxorelarc(h, v, radh, radv, ang1, ang2)
  465.     int h, v;
  466.     int radh, radv;
  467.     int ang1, ang2;
  468. {
  469. }
  470.  
  471. /*ARGSUSED*/
  472. void
  473. wdrawbox(left, top, right, bottom)
  474.     int left, top, right, bottom;
  475. {
  476. }
  477.  
  478. /*ARGSUSED*/
  479. void
  480. wpaint(left, top, right, bottom)
  481.     int left, top, right, bottom;
  482. {
  483. }
  484.  
  485. /*ARGSUSED*/
  486. void
  487. wshade(left, top, right, bottom, percentage)
  488.     int left, top, right, bottom;
  489.     int percentage;
  490. {
  491. }
  492.  
  493. /*ARGSUSED*/
  494. void
  495. winvert(left, top, right, bottom)
  496.     int left, top, right, bottom;
  497. {
  498.     WINDOW *win= draw_win;
  499.     int v;
  500.     
  501.     if (left < 0)
  502.         left= 0;
  503.     if (right >= columns)
  504.         right= columns;
  505.     if (left >= right)
  506.         return;
  507.     top -= win->offset;
  508.     bottom -= win->offset;
  509.     if (top < win->top)
  510.         top= win->top;
  511.     if (bottom > win->bottom)
  512.         bottom= win->bottom;
  513.     for (v= top; v < bottom; ++v) {
  514.         int k= textlen[v];
  515.         char *text= textline[v];
  516.         char *mode= modeline[v];
  517.         if (k < right) {
  518.             do {
  519.                 text[k]= ' ';
  520.                 mode[k]= PLAIN;
  521.                 k++;
  522.             } while (k < right);
  523.             textlen[v]= k;
  524.         }
  525.         for (k= left; k < right; ++k) {
  526.             if (mode[k] != PLAIN)
  527.                 mode[k]= PLAIN;
  528.             else
  529.                 mode[k]= STANDOUT;
  530.         }
  531.         texttouched[v]= TRUE;
  532.     }
  533. }
  534.  
  535. /*ARGSUSED*/
  536. void
  537. werase(left, top, right, bottom)
  538.     int left, top, right, bottom;
  539. {
  540.     WINDOW *win= draw_win;
  541.     int v;
  542.     
  543.     if (left < 0)
  544.         left= 0;
  545.     if (right >= columns)
  546.         right= columns;
  547.     if (left >= right)
  548.         return;
  549.     top -= win->offset;
  550.     bottom -= win->offset;
  551.     if (top < win->top)
  552.         top= win->top;
  553.     if (bottom > win->bottom)
  554.         bottom= win->bottom;
  555.     for (v= top; v < bottom; ++v) {
  556.         int k= textlen[v];
  557.         char *text= textline[v];
  558.         char *mode= modeline[v];
  559.         if (k > right)
  560.             k= right;
  561.         while (--k >= left) {
  562.             text[k]= ' ';
  563.             mode[k]= PLAIN;
  564.         }
  565.         texttouched[v]= TRUE;
  566.     }
  567. }
  568.  
  569. /*ARGSUSED*/
  570. void
  571. wdrawpoly(n, points)
  572.     int n;
  573.     POINT *points;
  574. {
  575. }
  576.  
  577. /*ARGSUSED*/
  578. void
  579. wfillpoly(n, points)
  580.     int n;
  581.     POINT *points;
  582. {
  583. }
  584.  
  585. /*ARGSUSED*/
  586. void
  587. wxorpoly(n, points)
  588.     int n;
  589.     POINT *points;
  590. {
  591. }
  592.  
  593. /*ARGSUSED*/
  594. void
  595. wcliprect(left, top, right, bottom)
  596.     int left, top, right, bottom;
  597. {
  598.     /* XXX not implemented */
  599. }
  600.  
  601. /*ARGSUSED*/
  602. void
  603. wnoclip()
  604. {
  605.     /* XXX not implemented */
  606. }
  607.  
  608. /*ARGSUSED*/
  609. int
  610. wsetfont(fontname)
  611.     char *fontname;
  612. {
  613.     return 0; /* There are no fonts... */
  614. }
  615.  
  616. /*ARGSUSED*/
  617. void
  618. wsetsize(size)
  619.     int size;
  620. {
  621. }
  622.  
  623. /*ARGSUSED*/
  624. COLOR
  625. wfetchcolor(colorname)
  626.     char *colorname;
  627. {
  628.     return 0;
  629. }
  630.  
  631. /*ARGSUSED*/
  632. void
  633. wsetfgcolor(color)
  634.     COLOR color;
  635. {
  636. }
  637.  
  638. COLOR
  639. wgetfgcolor()
  640. {
  641.     return 0;
  642. }
  643.  
  644. /*ARGSUSED*/
  645. void
  646. wsetbgcolor(color)
  647.     COLOR color;
  648. {
  649. }
  650.  
  651. COLOR
  652. wgetbgcolor()
  653. {
  654.     return 0;
  655. }
  656.