home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / text < prev    next >
Encoding:
Text File  |  1991-02-04  |  26.3 KB  |  822 lines

  1. /* > $.CLIB.C.text
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      These routines provide a text area in a window.  The text is stored
  21.  *      as a 2-D array of characters.  The routines draw parts of the area,
  22.  *      insert and delete characters and lines, scroll the text and provide
  23.  *      a VDU stream like interface.  It is possible to find things out
  24.  *      about the text and set its foreground and background colours.  The
  25.  *      text in a window does not need to cover the whole of the window, but
  26.  *      is always aligned with the top left corner of the window work area.
  27.  */
  28. #include "includes.h"
  29. #include <stdarg.h>
  30.  
  31. /*
  32.  *      draw the given text area on the screen.  The area is "txt", the
  33.  *      graphics X and Y coords of the area to be drawn is (gx0,gy0) to
  34.  *      (gx1,gy1).  adjx, adjy are the coordinate adjustments to get from
  35.  *      screen coords to window coords.  This routine is called in a similar
  36.  *      way to the graphics_plot() routine to do the graphics bits of a
  37.  *      window.  If the top bit of the character is set flip the foreground
  38.  *      and background colours.
  39.  */
  40. void text_plot(text *txt, int adjx, int adjy, int gx0, int gx1, int gy0,
  41.                int gy1) {
  42.  
  43.         register char   *ptr, ch;
  44.         register int    x, sx, ex, y;
  45.         int             sy, ey, charx, chary, intext, xpos, ypos, flip;
  46.  
  47.         if ((!txt) || (!txt->text))
  48.                 return;
  49.         charx = haswin_readvduvariable(VDUVAR_CharXsize);
  50.         chary = haswin_readvduvariable(VDUVAR_CharYsize);
  51.         sy = (adjy-gy1)/chary;
  52.         ey = ((adjy-gy0)/chary)+1;
  53.         if (ey >= txt->ysize)
  54.                 ey = txt->ysize-1;
  55.         sx = (gx0-adjx)/charx;
  56.         ex = (gx1-adjx)/charx+1;
  57.         if (ex >= txt->xsize)
  58.                 ex = txt->xsize-1;
  59.         ypos = adjy-sy*chary;
  60.         graphics_gcol(0, txt->bcol);
  61.         graphics_rectanglefill(adjx+sx*charx, ypos,
  62.                                (ex-sx+1)*charx, (sy-ey-1)*chary);
  63.         graphics_gcol(0, txt->fcol);
  64.         for (y=sy; y<=ey; y++) {
  65.                 ptr = &txt->text[sx+y*txt->xsize];
  66.                 intext = HASWIN_FALSE;
  67.                 xpos = adjx+sx*charx;
  68.                 for (x=sx; x<=ex; x++) {
  69.                         if (*ptr & 0x80) {
  70.                                 ch = *ptr & 0x7f;
  71.                                 flip = HASWIN_TRUE;
  72.                                 graphics_gcol(0, txt->fcol);
  73.                                 graphics_rectanglefill(xpos+charx-1, ypos-chary, 1-charx, chary);
  74.                                 graphics_gcol(0, txt->bcol);
  75.                         } else {
  76.                                 if (flip) {
  77.                                         graphics_gcol(0, txt->fcol);
  78.                                         flip = HASWIN_FALSE;
  79.                                 }
  80.                                 ch = *ptr;
  81.                         }
  82.                         if ((ch > ' ') && (ch < 127)) {
  83.                                 if (!intext) {
  84.                                         intext=HASWIN_TRUE;
  85.                                         graphics_move(xpos, ypos);
  86.                                 }
  87.                                 putchar(ch);
  88.                         } else {
  89.                                 intext = HASWIN_FALSE;
  90.                         }
  91.                         xpos += charx;
  92.                         ptr++;
  93.                 }
  94.                 ypos -= chary;
  95.         }
  96.         return;
  97. }
  98.  
  99. /*
  100.  *      create a new, or alter an existing text area.
  101.  *      If on entry either x or y are zero their value is taken from an
  102.  *      existing text area in the window.
  103.  */
  104. text *haswin_textmakearea(text *txt, int x, int y, char f, char b) {
  105.  
  106.         text            *tmptxt;
  107.         register char   *ptr1, *ptr2;
  108.         register int    j, xe, ye;
  109.  
  110.         if (txt) {
  111.                 if (x == 0)
  112.                         x = txt->xsize;
  113.                 if (y == 0)
  114.                         y = txt->ysize;
  115.         }
  116.         if ((x <= 0) || (y <= 0))
  117.                 return(HASWIN_FALSE);
  118.         tmptxt = haswin_malloc(sizeof(text), "haswin_maketextarea", "text block");
  119.         if (!tmptxt)
  120.                 return(HASWIN_FALSE);
  121.         tmptxt->text = haswin_malloc(x*y, "haswin_maketextarea", "text characters");
  122.         if (!tmptxt->text) {
  123.                 haswin_free(tmptxt);
  124.                 return(HASWIN_FALSE);
  125.         }
  126.         memset(tmptxt->text, ' ', x*y);
  127.         tmptxt->xsize = x;
  128.         tmptxt->ysize = y;
  129.         tmptxt->xposn = tmptxt->yposn = 0;
  130.         tmptxt->fcol = f;
  131.         tmptxt->bcol = b;
  132.         if (txt) {
  133.                 if (txt->text) {
  134.                         xe = (txt->xsize > x) ? x : txt->xsize;
  135.                         ye = (txt->ysize > y) ? y : txt->ysize;
  136.                         ptr1 = tmptxt->text;
  137.                         ptr2 = txt->text;
  138.                         for (j=0; j<ye; j++) {
  139.                                 memcpy(ptr1, ptr2, xe);
  140.                                 ptr1 += tmptxt->xsize;
  141.                                 ptr2 += txt->xsize;
  142.                         }
  143.                         haswin_free(txt->text);
  144.                 }
  145.                 free(txt);
  146.         }
  147.         return(tmptxt);
  148. }
  149.  
  150. /*
  151.  *      create a new, or alter an existing text area.
  152.  *      If on entry either x or y are zero their value is taken from an
  153.  *      existing text area in the window.
  154.  */
  155. int haswin_maketextoverlay(window *win, int x, int y, char f, char b) {
  156.  
  157.         int     ox, oy;
  158.  
  159.         if ((int)win <= 0)
  160.                 return(0);
  161.         if (win->text) {
  162.                 ox = win->text->xposn;
  163.                 oy = win->text->xposn;
  164.         } else
  165.                 ox = -1;
  166.         if ((win->text=haswin_textmakearea(win->text, x, y, f, b)) == 0)
  167.                 return(0);
  168.         if (!win->caret)
  169.                 win->caret = haswin_makecaret(win, 0, 0, 0,
  170.                                  haswin_readvduvariable(VDUVAR_CharYsize),
  171.                                  11, CARET_REALCOL, 0);
  172.         if (ox != -1)
  173.                 haswin_textmove(win, ox, oy);
  174.         return(HASWIN_TRUE);
  175. }
  176.  
  177. /*
  178.  *      mark the given text area to be redrawn.
  179.  */
  180. int haswin_textredraw(window *win, int x0, int x1, int y0, int y1) {
  181.  
  182.         int     charx, chary;
  183.  
  184.         if (((int)win <= 0) || (!win->text))
  185.                 return(HASWIN_FALSE);
  186.         if (!(haswin_getwindowflags(win) & WINDOW_OPEN))
  187.                 return(HASWIN_TRUE);
  188.         charx = haswin_readvduvariable(VDUVAR_CharXsize);
  189.         chary = haswin_readvduvariable(VDUVAR_CharYsize);
  190.         if (!haswin_converttxtxytowin(win, &x0, &y0))
  191.                 return(HASWIN_FALSE);
  192.         if (!haswin_converttxtxytowin(win, &x1, &y1))
  193.                 return(HASWIN_FALSE);
  194.         haswin_redrawwindow(win, x0-charx, x1+charx, y0-chary, y1+chary);
  195.         return(HASWIN_TRUE);
  196. }
  197.  
  198. /*
  199.  *      we provide a similar interface to that provided by the Archimedes
  200.  *      VDU drivers.  The following commands are understood.
  201.  *      character      action
  202.  *        ^@   0        NULL
  203.  *        ^G   7        ring the bell
  204.  *        ^H   8        move left  (stops at left edge)
  205.  *        ^I   9        move right  (wraps to next line, stops at bottom)
  206.  *        ^J  10        move down  (bottom wraps to top)
  207.  *        ^K  11        move up  (top wraps to bottom)
  208.  *        ^L  12        clear text  (move cursor to top left)
  209.  *        ^M  13        move to begining of next line (can scroll)
  210.  *        ^N  14        insert character
  211.  *        ^O  15        insert line
  212.  *        ^P  16        delete character
  213.  *        ^Q  17        delete line
  214.  *        ^R  18        scroll left
  215.  *        ^S  19        scroll right
  216.  *        ^T  20        scroll down
  217.  *        ^U  21        scroll up
  218.  *        ^*  30        move cursor to top left.
  219.  *        ^_  31        move cursor to X, Y.
  220.  *     <sp>-~ 32-126    character added to text (wraps to next line, scrolls)
  221.  *        ^?  127       delete character and move left (stops at left edge)
  222.  *
  223.  *      new characters added to the text overwrite those that are already
  224.  *      there.
  225.  */
  226.  
  227. int haswin_textvdu(window *win, char ch) {
  228.  
  229.         register char   *ptr, *end;
  230.         caret           car;
  231.  
  232.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  233.                 return(HASWIN_FALSE);
  234.         if ((ch < 0) || (ch > 127))
  235.                 return(HASWIN_FALSE);
  236.         switch (ch) {
  237.         case   0:
  238.                 break;
  239.         case   1:
  240.         case   2:
  241.         case   3:
  242.         case   4:
  243.         case   5:
  244.         case   6:
  245.                 return(HASWIN_FALSE);
  246.         case   7:
  247.                 haswin_bell();
  248.                 break;
  249.         case   8:
  250.                 win->text->xposn--;
  251.                 break;
  252.         case   9:
  253.                 win->text->xposn++;
  254.                 break;
  255.         case  10:
  256.                 win->text->yposn--;
  257.                 break;
  258.         case  11:
  259.                 win->text->yposn++;
  260.                 break;
  261.         case  12:
  262.                 end = &win->text->text[win->text->xsize*win->text->ysize];
  263.                 for (ptr=win->text->text; ptr<end; ptr++)
  264.                         *ptr = (*ptr & 0x80) | ' ';
  265.                 win->text->xposn = win->text->yposn = 0;
  266.                 haswin_textredraw(win,0,win->text->xsize,win->text->ysize,0);
  267.                 break;
  268.         case  13:
  269.                 win->text->yposn++;
  270.                 win->text->xposn = 0;
  271.                 break;
  272.         case  14:
  273.                 haswin_textinsertchar(win,win->text->xposn,win->text->yposn);
  274.                 break;
  275.         case  15:
  276.                 haswin_textinsertline(win, win->text->yposn);
  277.                 break;
  278.         case  16:
  279.                 haswin_textdeletechar(win,win->text->xposn,win->text->yposn);
  280.                 break;
  281.         case  17:
  282.                 haswin_textdeleteline(win, win->text->yposn);
  283.                 break;
  284.         case  18:
  285.                 haswin_textscrollleft(win);
  286.                 break;
  287.         case  19:
  288.                 haswin_textscrollright(win);
  289.                 break;
  290.         case  20:
  291.                 haswin_textscrolldown(win);
  292.                 break;
  293.         case  21:
  294.                 haswin_textscrollup(win);
  295.                 break;
  296.         case  22:
  297.         case  23:
  298.         case  24:
  299.         case  25:
  300.         case  26:
  301.         case  27:
  302.         case  28:
  303.         case  29:
  304.                 return(HASWIN_FALSE);
  305.         case  30:
  306.                 haswin_textmove(win, 0, 0);
  307.                 break;
  308.         case  31:
  309.                 break;
  310.         case 127:
  311.                 win->text->xposn--;
  312.                 if (win->text->xposn < 0)
  313.                         win->text->xposn = 0;
  314.                 haswin_textdeletechar(win,win->text->xposn,win->text->yposn);
  315.                 break;
  316.         default:
  317.                 ptr = &win->text->text[win->text->xposn+win->text->xsize*win->text->yposn];
  318.                 *ptr = (*ptr & 0x80) | (ch & 0x7F);
  319.                 haswin_textredraw(win, win->text->xposn, win->text->xposn,
  320.                                        win->text->yposn, win->text->yposn);
  321.                 win->text->xposn++;
  322.                 break;
  323.         }
  324.         if (win->text->xposn >= win->text->xsize) {
  325.                 win->text->xposn = 0;
  326.                 win->text->yposn++;
  327.         } else if (win->text->xposn < 0) {
  328.                 win->text->xposn = 0;
  329.         }
  330.         if (win->text->yposn >= win->text->ysize) {
  331.                 win->text->yposn = win->text->ysize-1;
  332.                 haswin_textscrolldown(win);
  333.         } else if (win->text->yposn < 0) {
  334.                 win->text->yposn = 0;
  335.         }
  336.         if (win->caret) {
  337.                 win->caret->x = haswin_converttxtxtowin(win, win->text->xposn);
  338.                 win->caret->y = haswin_converttxtytowin(win, win->text->yposn) - haswin_readvduvariable(VDUVAR_CharYsize);
  339.                 haswin_getcaretinfo(&car);
  340.                 if ((car.win == win) && (car.ic == 0) &&
  341.                     (haswin_getwindowflags(win) & WINDOW_OPEN))
  342.                         haswin_setcaret(win->caret);
  343.         }
  344.         return(HASWIN_TRUE);
  345. }
  346.  
  347. int haswin_textsetmark(window *win, int x0, int x1, int y0, int y1) {
  348.  
  349.         register char   *ptr;
  350.         register int    x, y;
  351.  
  352.         if (((int)win <= 0) || (!win->text))
  353.                 return(HASWIN_FALSE);
  354.         if ((x0<0) || (x1<0) || (y0<0) || (y1<0) || (x1<x0) || (y1<y0))
  355.                 return(HASWIN_FALSE);
  356.         if ((x1 >= win->text->xsize) || (y1 >= win->text->ysize))
  357.                 return(HASWIN_FALSE);
  358.         for (y=y0; y<=y1; y++) {
  359.                 ptr = &win->text->text[x0+y*win->text->xsize];
  360.                 for (x=x0; x<=x1; x++) {
  361.                         *ptr++ |= 0x80;
  362.                 }
  363.         }
  364.         return((x1-x0)*(y1-y0));
  365. }
  366.  
  367. int haswin_textclearmark(window *win, int x0, int x1, int y0, int y1) {
  368.  
  369.         register char   *ptr;
  370.         register int    x, y;
  371.  
  372.         if (((int)win <= 0) || (!win->text))
  373.                 return(HASWIN_FALSE);
  374.         if ((x0<0) || (x1<0) || (y0<0) || (y1<0) || (x1<x0) || (y1<y0))
  375.                 return(HASWIN_FALSE);
  376.         if ((x1 >= win->text->xsize) || (y1 >= win->text->ysize))
  377.                 return(HASWIN_FALSE);
  378.         for (y=y0; y<=y1; y++) {
  379.                 ptr = &win->text->text[x0+y*win->text->xsize];
  380.                 for (x=x0; x<=x1; x++) {
  381.                         *ptr++ &= 0x7F;
  382.                 }
  383.         }
  384.         return((x1-x0)*(y1-y0));
  385. }
  386.  
  387. int haswin_textdeletechar(window *win, int x, int y) {
  388.  
  389.         register int    i;
  390.         register char   *ptr, *ptr1;
  391.  
  392.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  393.                 return(HASWIN_FALSE);
  394.         if (x < 0)
  395.                 x = 0;
  396.         else if (x >= win->text->xsize)
  397.                 x = win->text->xsize - 1;
  398.         if (y < 0)
  399.                 y = 0;
  400.         else if (y >= win->text->ysize)
  401.                 y = win->text->ysize - 1;
  402.         ptr = &(win->text->text[x+y*win->text->xsize]);
  403.         ptr1 = ptr++;
  404.         for (i=x+1; i<win->text->xsize; i++)
  405.                 *ptr1++ = *ptr++;
  406.         *ptr1 = ' ';
  407.         haswin_textredraw(win, x+1, win->text->xsize, y, y);
  408.         return(HASWIN_TRUE);
  409. }
  410.  
  411. int haswin_textdeleteline(window *win, int y) {
  412.  
  413.         register int    i;
  414.         register char   *ptr, *ptr1;
  415.  
  416.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  417.                 return(HASWIN_FALSE);
  418.         if (y < 0)
  419.                 y = 0;
  420.         else if (y >= win->text->ysize)
  421.                 y = win->text->ysize - 1;
  422.         ptr = &(win->text->text[y*win->text->xsize]);
  423.         ptr1 = ptr+win->text->xsize;
  424.         for (i=y+1; i<win->text->ysize; i++) {
  425.                 memcpy(ptr, ptr1, win->text->xsize);
  426.                 ptr += win->text->xsize;
  427.                 ptr1 += win->text->xsize;
  428.         }
  429.         memset(ptr, ' ', win->text->xsize);
  430.         haswin_textredraw(win, 0, win->text->xsize, win->text->ysize, y);
  431.         return(HASWIN_TRUE);
  432. }
  433.  
  434. int haswin_textinsertchar(window *win, int x, int y) {
  435.  
  436.         register int    i;
  437.         register char   *ptr, *ptr1;
  438.  
  439.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  440.                 return(HASWIN_FALSE);
  441.         if (x < 0)
  442.                 x = 0;
  443.         else if (x >= win->text->xsize)
  444.                 x = win->text->xsize - 1;
  445.         if (y < 0)
  446.                 y = 0;
  447.         else if (y >= win->text->ysize)
  448.                 y = win->text->ysize - 1;
  449.         ptr = &(win->text->text[(y+1)*win->text->xsize-1]);
  450.         ptr1 = ptr--;
  451.         for (i=x+1; i<win->text->xsize; i++)
  452.                 *ptr1-- = *ptr--;
  453.         ptr[1] = ' ';
  454.         haswin_textredraw(win, x+1, win->text->xsize, y, y);
  455.         return(HASWIN_TRUE);
  456. }
  457.  
  458. int haswin_textinsertline(window *win, int y) {
  459.  
  460.         register int    i;
  461.         register char   *ptr, *ptr1;
  462.  
  463.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  464.                 return(HASWIN_FALSE);
  465.         if (y < 0)
  466.                 y = 0;
  467.         else if (y >= win->text->ysize)
  468.                 y = win->text->ysize - 1;
  469.         ptr = &(win->text->text[(win->text->ysize-1)*win->text->xsize]);
  470.         ptr1 = ptr-win->text->xsize;
  471.         for (i=y+1; i<win->text->ysize; i++) {
  472.                 memcpy(ptr, ptr1, win->text->xsize);
  473.                 ptr -= win->text->xsize;
  474.                 ptr1 -= win->text->xsize;
  475.         }
  476.         memset(ptr, ' ', win->text->xsize);
  477.         haswin_textredraw(win, 0, win->text->xsize, win->text->ysize, y);
  478.         return(HASWIN_TRUE);
  479. }
  480.  
  481. int haswin_textscrolldown(window *win) {
  482.  
  483.         return(haswin_textdeleteline(win, 0));
  484. }
  485.  
  486. int haswin_textscrollup(window *win) {
  487.  
  488.         return(haswin_textinsertline(win, 0));
  489. }
  490.  
  491. int haswin_textscrollright(window *win) {
  492.  
  493.         register int    i, y;
  494.         register char   *ptr, *ptr1;
  495.  
  496.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  497.                 return(HASWIN_FALSE);
  498.         for (y=0; y<win->text->ysize; y++) {
  499.                 ptr = &(win->text->text[(y+1)*win->text->xsize-1]);
  500.                 ptr1 = ptr--;
  501.                 for (i=1; i<win->text->xsize; i++)
  502.                         *ptr1-- = *ptr--;
  503.                 ptr[1] = ' ';
  504.         }
  505.         haswin_textredraw(win, 0, win->text->xsize, win->text->ysize, 0);
  506.         return(HASWIN_TRUE);
  507. }
  508.  
  509. int haswin_textscrollleft(window *win) {
  510.  
  511.         register int    i, y;
  512.         register char   *ptr, *ptr1;
  513.  
  514.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  515.                 return(HASWIN_FALSE);
  516.         for (y=0; y<win->text->ysize; y++) {
  517.                 ptr = &(win->text->text[y*win->text->xsize]);
  518.                 ptr1 = ptr++;
  519.                 for (i=1; i<win->text->xsize; i++)
  520.                         *ptr1++ = *ptr++;
  521.                 *ptr1 = ' ';
  522.         }
  523.         haswin_textredraw(win, 0, win->text->xsize, win->text->ysize, 0);
  524.         return(HASWIN_TRUE);
  525. }
  526. int haswin_textgetchar(window *win, int x, int y) {
  527.  
  528.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  529.                 return(-1);
  530.         if (x < 0)
  531.                 x = 0;
  532.         else if (x >= win->text->xsize)
  533.                 x = win->text->xsize - 1;
  534.         if (y < 0)
  535.                 y = 0;
  536.         else if (y >= win->text->ysize)
  537.                 y = win->text->ysize - 1;
  538.         return(win->text->text[x*y]);
  539. }
  540.  
  541. int haswin_textgetblock(window *win, int x0, int y0, int x1, int y1) {
  542.  
  543.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  544.                 return(HASWIN_FALSE);
  545.         if (x0 < 0)
  546.                 x0 = 0;
  547.         else if (x0 >= win->text->xsize)
  548.                 x0 = win->text->xsize - 1;
  549.         if (y0 < 0)
  550.                 y0 = 0;
  551.         else if (y0 >= win->text->ysize)
  552.                 y0 = win->text->ysize - 1;
  553.         if (x1 < 0)
  554.                 x1 = 0;
  555.         else if (x1 >= win->text->xsize)
  556.                 x1 = win->text->xsize - 1;
  557.         if (y1 < 0)
  558.                 y1 = 0;
  559.         else if (y1 >= win->text->ysize)
  560.                 y1 = win->text->ysize - 1;
  561.         if ((x0 >= x1) || (y0 >= y1))
  562.                 return(HASWIN_FALSE);
  563.         return(HASWIN_TRUE);
  564. }
  565.  
  566. int haswin_textmove(window *win, int x, int y) {
  567.  
  568.         int     ret = HASWIN_TRUE;
  569.  
  570.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  571.                 return(HASWIN_FALSE);
  572.         if (x < 0) {
  573.                 x = 0;
  574.                 ret = HASWIN_FALSE;
  575.         } else if (x >= win->text->xsize) {
  576.                 x = win->text->xsize - 1;
  577.                 ret = HASWIN_FALSE;
  578.         }
  579.         if (y < 0) {
  580.                 y = 0;
  581.                 ret = HASWIN_FALSE;
  582.         } else if (y >= win->text->ysize) {
  583.                 y = win->text->ysize - 1;
  584.                 ret = HASWIN_FALSE;
  585.         }
  586.         if (win->caret) {
  587.                 win->caret->x = haswin_converttxtxtowin(win, x);
  588.                 win->caret->y = haswin_converttxtytowin(win, y) - haswin_readvduvariable(VDUVAR_CharYsize);
  589.                 if (haswin_getwindowflags(win) & WINDOW_OPEN)
  590.                         haswin_setcaret(win->caret);
  591.         }
  592.         win->text->xposn = x;
  593.         win->text->yposn = y;
  594.         return(ret);
  595. }
  596.  
  597. /*
  598.  *      do printf() in the text window given.
  599.  */
  600. int haswin_textprintf(window *win, char *fmt, ...) {
  601.  
  602.         char    *ptr;
  603.         va_list ap;
  604.         int     len;
  605.         /* We have to try and guess the length of the final string to
  606.            allocate memory for it.  Remember that we will only need the
  607.            memory for a short time.  Guess at 10K.  */
  608.         char            str[10240];
  609.  
  610.         if (((int)win <= 0) || (!win->text) || (!win->text->text))
  611.                 return(HASWIN_FALSE);
  612.         va_start(ap, fmt);
  613.         len = vsprintf(str, fmt, ap);
  614.         ptr = str;
  615.         while (*ptr) {
  616.                 haswin_textvdu(win, *ptr++);
  617.         }
  618.         va_end(ap);
  619.         return(len);
  620. }
  621.  
  622. int haswin_textgetxposn(window *win) {
  623.  
  624.         if (((int)win <= 0) || (!win->text))
  625.                 return(-1);
  626.         return(win->text->xposn);
  627. }
  628.  
  629. int haswin_textgetyposn(window *win) {
  630.  
  631.         if (((int)win <= 0) || (!win->text))
  632.                 return(-1);
  633.         return(win->text->yposn);
  634. }
  635.  
  636. int haswin_textgetxsize(window *win) {
  637.  
  638.         if (((int)win <= 0) || (!win->text))
  639.                 return(-1);
  640.         return(win->text->xsize);
  641. }
  642.  
  643. int haswin_textgetysize(window *win) {
  644.  
  645.         if (((int)win <= 0) || (!win->text))
  646.                 return(-1);
  647.         return(win->text->ysize);
  648. }
  649.  
  650. /*
  651.  *      convert window and text x to a x offset in the window (left of char).
  652.  */
  653. int haswin_converttxtxtowin(window *wptr, int x) {
  654.  
  655.         if ((int)wptr <= 0)
  656.                 return(x);
  657.         if (!wptr->text)
  658.                 return(HASWIN_UNKNOWN);
  659.         if (x < 0)
  660.                 x = 0;
  661.         else if (x >= wptr->text->xsize)
  662.                 x = wptr->text->xsize-1;
  663.         x *= haswin_readvduvariable(VDUVAR_CharXsize);
  664.         return(x-wptr->orgx);
  665. }
  666.  
  667. /*
  668.  *      convert window and text y to a y offset in the window (bottom of
  669.  *      char).
  670.  */
  671. int haswin_converttxtytowin(window *wptr, int y) {
  672.  
  673.         if ((int)wptr <= 0)
  674.                 return(y);
  675.         if (!wptr->text)
  676.                 return(HASWIN_UNKNOWN);
  677.         if (y < 0)
  678.                 y = 0;
  679.         else if (y >= wptr->text->ysize)
  680.                 y = wptr->text->ysize-1;
  681.         y *= haswin_readvduvariable(VDUVAR_CharYsize);
  682.         return(wptr->orgy-y);
  683. }
  684.  
  685. /*
  686.  *      convert window and x,y text position to a x,y offset in the window.
  687.  */
  688. int haswin_converttxtxytowin(window *wptr, int *x, int *y) {
  689.  
  690.         if (((int)wptr <= 0) || (!wptr->text))
  691.                 return(HASWIN_FALSE);
  692.         if (*x < 0)
  693.                 *x = 0;
  694.         else if (*x >= wptr->text->xsize)
  695.                 *x = wptr->text->xsize-1;
  696.         if (*y < 0)
  697.                 *y = 0;
  698.         else if (*y >= wptr->text->ysize)
  699.                 *y = wptr->text->ysize-1;
  700.         *x *= haswin_readvduvariable(VDUVAR_CharXsize);
  701.         *y *= haswin_readvduvariable(VDUVAR_CharYsize);
  702.  
  703.         *x = *x - wptr->orgx;
  704.         *y = wptr->orgy - *y;
  705.         return(HASWIN_TRUE);
  706. }
  707.  
  708. /*
  709.  *      convert window and x offset to text x position in window.
  710.  */
  711. int haswin_convertwinxtotxt(window *wptr, int x) {
  712.  
  713.         if ((int)wptr <= 0)
  714.                 return(x);
  715.         if (!wptr->text)
  716.                 return(HASWIN_UNKNOWN);
  717.         x = (x+wptr->orgx)/haswin_readvduvariable(VDUVAR_CharXsize);
  718.         if (x <= 0)
  719.                 return(0);
  720.         if (x > wptr->text->xsize-1)
  721.                 return(wptr->text->xsize-1);
  722.         return(x);
  723. }
  724.  
  725. /*
  726.  *      convert window and y offset to text y position in window.
  727.  */
  728. int haswin_convertwinytotxt(window *wptr, int y) {
  729.  
  730.         if ((int)wptr <= 0)
  731.                 return(y);
  732.         if (!wptr->text)
  733.                 return(HASWIN_UNKNOWN);
  734.         y = (wptr->orgy-y)/haswin_readvduvariable(VDUVAR_CharYsize);
  735.         if (y <= 0)
  736.                 return(0);
  737.         if (y > wptr->text->ysize-1)
  738.                 return(wptr->text->ysize-1);
  739.         return(y);
  740. }
  741.  
  742. /*
  743.  *      convert window and x,y offset pair to text position in window.
  744.  */
  745. int haswin_convertwinxytotxt(window *wptr, int *x, int *y) {
  746.  
  747.         if (((int)wptr <= 0) || (!wptr->text))
  748.                 return(HASWIN_FALSE);
  749.         *x = (*x+wptr->orgx)/haswin_readvduvariable(VDUVAR_CharXsize);
  750.         if (*x < 0)
  751.                 *x = 0;
  752.         else if (*x > wptr->text->xsize-1)
  753.                 *x = wptr->text->xsize-1;
  754.         *y = (wptr->orgy- *y)/haswin_readvduvariable(VDUVAR_CharYsize);
  755.         if (*y < 0)
  756.                 *y = 0;
  757.         else if (*y > wptr->text->ysize-1)
  758.                 *y = wptr->text->ysize-1;
  759.         return(HASWIN_TRUE);
  760. }
  761.  
  762. /*
  763.  *      convert a text x position and a window to the real position on the
  764.  *      screen.
  765.  */
  766. int haswin_converttxtxtoscr(window *wptr, int x) {
  767.  
  768.         return(haswin_convertwinxtoscr(wptr, haswin_converttxtxtowin(wptr, x)));
  769. }
  770.  
  771. /*
  772.  *      convert a text y position and a window to the real position on the
  773.  *      screen.
  774.  */
  775. int haswin_converttxtytoscr(window *wptr, int y) {
  776.  
  777.         return(haswin_convertwinytoscr(wptr, haswin_converttxtytowin(wptr, y)));
  778. }
  779.  
  780. /*
  781.  *      convert a text x,y pair and a window to the real position on the
  782.  *      screen.
  783.  */
  784. int haswin_converttxtxytoscr(window *wptr, int *x, int *y) {
  785.  
  786.         if (haswin_converttxtxytowin(wptr, x, y))
  787.                 return(haswin_convertwinxytoscr(wptr, x, y));
  788.         else
  789.                 return(HASWIN_FALSE);
  790. }
  791.  
  792. /*
  793.  *      convert a real x position on the screen to a text position in the
  794.  *      window
  795.  */
  796. int haswin_convertscrxtotxt(window *wptr, int x) {
  797.  
  798.         return(haswin_convertwinxtotxt(wptr, haswin_convertscrxtowin(wptr, x)));
  799. }
  800.  
  801. /*
  802.  *      convert a real y position on the screen to a text position in the
  803.  *      window
  804.  */
  805. int haswin_convertscrytotxt(window *wptr, int y) {
  806.  
  807.         return(haswin_convertwinytotxt(wptr, haswin_convertscrytowin(wptr, y)));
  808. }
  809.  
  810. /*
  811.  *      convert a real x,y pair on the screen to a text position in the
  812.  *      window
  813.  */
  814. int haswin_convertscrxytotxt(window *wptr, int *x, int *y) {
  815.  
  816.         if (haswin_convertscrxytowin(wptr, x, y))
  817.                 return(haswin_convertwinxytotxt(wptr, x, y));
  818.         else
  819.                 return(HASWIN_FALSE);
  820. }
  821.  
  822.