home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1820.lha / XDME / subs.c < prev    next >
C/C++ Source or Header  |  1993-03-09  |  16KB  |  816 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     subs.c
  5.  
  6.     DESCRIPTION
  7.     General subroutines.
  8.  
  9.     NOTES
  10.  
  11.     BUGS
  12.  
  13.     TODO
  14.  
  15.     EXAMPLES
  16.  
  17.     SEE ALSO
  18.  
  19.     INDEX
  20.  
  21.     HISTORY
  22.     16. Jan 1993    ada created
  23.  
  24. ******************************************************************************/
  25.  
  26. /**************************************
  27.         Includes
  28. **************************************/
  29. #include "defs.h"
  30. #include <clib/macros.h>
  31. #include <graphics/display.h>
  32. #define MYDEBUG     0
  33. #include "debug.h"
  34.  
  35.  
  36. /**************************************
  37.         Globale Variable
  38. **************************************/
  39. Prototype void     makemygadget     (struct Gadget *);
  40. Prototype int     firstns     (char *);
  41. Prototype int     lastns      (char *);
  42. Prototype int     wordlen     (char *);
  43. Prototype Bool     getpathto     (BPTR, char *, char *);
  44. Prototype void * allocline     (long);
  45. Prototype int     detab         (char *, char *, int);
  46. Prototype int     xefgets     (FILE *, char *, int);
  47. Prototype ED   * finded      (char *, int);
  48. Prototype void     mountrequest     (int);
  49. Prototype FONT * GetFont     (char *, short);
  50. Prototype void     freeline     (LINE);
  51. Prototype void     movetocursor     (void);
  52. Prototype int     extend      (ED *, int);
  53. Prototype int     makeroom     (int);
  54. Prototype void     freelist     (LINE *, int);
  55. Prototype long     lineflags     (int);
  56. Prototype void     scroll_display  (short, short, Column, Line, Column, Line);
  57. Prototype char * skip_whitespace (char *);
  58. Prototype char     is_number     (char *);
  59. Prototype char * getnextcomline  (FILE *, int *);
  60. Prototype char * fname         (char *);
  61. Prototype Bool     switch_ed     (ED *);
  62. Prototype void     do_makecursorvisible (void);
  63. Prototype void     MakeRectVisible (WIN *, USHORT, USHORT, USHORT, USHORT);
  64. Prototype int     LINELEN     (ED *, Line);
  65.  
  66. /* Assembler */
  67. Prototype void swapmem (void *, void *, ULONG);
  68.  
  69.  
  70. /**************************************
  71.       Interne Defines & Strukturen
  72. **************************************/
  73. typedef struct FileInfoBlock FIB;
  74.  
  75.  
  76. /**************************************
  77.         Interne Variable
  78. **************************************/
  79.  
  80.  
  81. /**************************************
  82.        Interne Prototypes
  83. **************************************/
  84.  
  85.  
  86. /*
  87.  *  Create XDME's text icon.
  88.  */
  89.  
  90. void makemygadget (struct Gadget *gad)
  91. {
  92.     const static unsigned short ga[] =
  93.     {
  94.      /* Plane 0 */
  95.      0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0C00,
  96.      0x0000,0x0000,0x0000,0x0C00,0x0FFF,0xFFFF,0xFFFF,0x8C00,
  97.      0x0C00,0x0000,0x0000,0x0C00,0x0C1F,0xFFFF,0xFFE0,0x0C00,
  98.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x08BF,0xFFE0,0x0C00,
  99.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x25FF,0xFFE0,0x0C00,
  100.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x0BFF,0xFFE0,0x0C00,
  101.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x1FFF,0xFFE0,0x0C00,
  102.      0x0C16,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x7FFF,0xFFE0,0x0C00,
  103.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0800,0x0000,0x0000,0x0C00,
  104.      0x0000,0x0000,0x0000,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  105.      0x0031,0x98CE,0x7318,0x0C00,0x001B,0x186F,0xF318,0x0C00,
  106.      0x001B,0x186F,0xF360,0x0C00,0x000E,0x186D,0xB3E0,0x0C00,
  107.      0x001B,0x186D,0xB360,0x0C00,0x001B,0x186C,0x3318,0x0C00,
  108.      0x0031,0x98CC,0x3318,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  109.      0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
  110.      /* Plane 1 */
  111.      0xFFFF,0xFFFF,0xFFFF,0xF800,0xD555,0x5555,0x5555,0x5000,
  112.      0xD555,0x5555,0x5555,0x5000,0xD000,0x0000,0x0000,0x5000,
  113.      0xD000,0x0000,0x0000,0xD000,0xD000,0x0000,0x0000,0xD000,
  114.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  115.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  116.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  117.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  118.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  119.      0xD003,0xFFFF,0xFF00,0xD000,0xD7FF,0xFFFF,0xFFFF,0xD000,
  120.      0xD555,0x5555,0x5555,0x5000,0xD504,0x0041,0x0005,0x5000,
  121.      0xD544,0x4511,0x0445,0x5000,0xD544,0x4510,0x0445,0x5000,
  122.      0xD544,0x4510,0x0415,0x5000,0xD551,0x4510,0x4415,0x5000,
  123.      0xD544,0x4510,0x4415,0x5000,0xD544,0x4511,0x4445,0x5000,
  124.      0xD544,0x4511,0x4445,0x5000,0xD504,0x0041,0x0005,0x5000,
  125.      0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000
  126.     };
  127.     const static struct Image image =
  128.     {
  129.      0, 0, 54, 30, 2, (unsigned short *)ga, 3, 0, NULL
  130.     };
  131.  
  132.     clrmem (gad, sizeof(struct Gadget));
  133.  
  134.     gad->Width          = 54;
  135.     gad->Height       = 31; /* Blank line between Image and Text ! */
  136.     gad->Flags          = GADGIMAGE|GADGHCOMP;
  137.     gad->GadgetType   = BOOLGADGET;
  138.     gad->Activation   = RELVERIFY|GADGIMMEDIATE;
  139.     gad->GadgetRender = (APTR)ℑ
  140. } /* makemygadget */
  141.  
  142.  
  143. /*
  144.  * return index of first non space.  Returns 0 if no spaces found.
  145.  */
  146.  
  147. int firstns (char * str)
  148. {
  149.     short i;
  150.  
  151.     for (i = 0; str[i] && str[i] == ' '; i ++);
  152.  
  153.     if (str[i] == 0)
  154.     i = 0;
  155.  
  156.     return (i);
  157. } /* firstns */
  158.  
  159.  
  160. /*
  161.  *  Return index of last non-space, 0 if no spaces.
  162.  */
  163.  
  164. int lastns (char * str)
  165. {
  166.     short i;
  167.  
  168.     /* get last char of string (i might be -1 after that !).
  169.        now walk left until a char != ' ' is found or i == 0. */
  170.     for (i = strlen(str) - 1; i > 0 && str[i] == ' '; i --);
  171.  
  172.     if (i < 0)  /* string empty */
  173.     i = 0;
  174.  
  175.     return (i);
  176. } /* lastns */
  177.  
  178.  
  179. /*
  180.  *  Return length of word under cursor
  181.  */
  182.  
  183. int wordlen (char * str)
  184. {
  185.     short i;
  186.  
  187.     for (i = 0; *str && *str != ' '; ++i, ++str);
  188.  
  189.     return(i);
  190. } /* wordlen */
  191.  
  192.  
  193. /*
  194.  *  Backtracks the program lock, 0 on failure, 1 on success.
  195.  *  The filename is appended to the lock, if it exists.
  196.  */
  197.  
  198. Bool getpathto (BPTR lock, char * filename, char * buf)
  199. {
  200.     if (!NameFromLock (lock, buf, PATHSIZE))
  201.     return (FALSE);
  202.  
  203.     if (filename)
  204.     AddPart (buf, filename, PATHSIZE);
  205.  
  206.     return (TRUE);
  207. }
  208.  
  209.  
  210. /*
  211.  *  Allocation routines and other shortcuts
  212.  */
  213.  
  214. static LINE empty_line = "";
  215.  
  216. void * allocline (long size)
  217. {
  218.      if (size <= 1) return (empty_line);     /* no more tiny empty blocks */
  219.  
  220.      /* Make sure we always get a padded block */
  221.      size += 7;
  222.      size &= ~7;
  223.  
  224.      return (AllocMem (size, 0));
  225. } /* allocline */
  226.  
  227.  
  228. void freeline (LINE line)
  229. {
  230.     short size;
  231.  
  232.     if (line && line != empty_line)
  233.     {
  234.     size = strlen (line) + 8;
  235.     size &= ~7;
  236.  
  237.     FreeMem (line, size);
  238.     }
  239. } /* freeline */
  240.  
  241.  
  242. /*
  243.  *  Remove tabs in a buffer
  244.  */
  245.  
  246. int detab (char * ibuf, char * obuf, int maxlen)
  247. {
  248.     short i, j;
  249.  
  250.     maxlen -= 1;
  251.  
  252.     for (i = j = 0; ibuf[i] && j < maxlen; ++i)
  253.     {
  254.     if (ibuf[i] == 9)
  255.     {
  256.         do
  257.         {
  258.         obuf[j++] = ' ';
  259.         } while ((j & 7) && j < maxlen);
  260.     } else
  261.     {
  262.         obuf[j++] = ibuf[i];
  263.     }
  264.     }
  265.  
  266.     if (j && obuf[j-1] == '\n')
  267.     --j;
  268.  
  269.     while (j && obuf[j-1] == ' ')
  270.     --j;
  271.  
  272.     obuf[j] = 0;
  273.  
  274.     return (j);
  275. } /* detab */
  276.  
  277.  
  278. int xefgets (FILE * fi, char * buf, int max)
  279. {
  280.     char ebuf[MAXLINELEN];
  281.  
  282.     if (fgets (ebuf, max, fi))
  283.     return (detab (ebuf, buf, max));
  284.  
  285.     return (-1);
  286. } /* xefgets */
  287.  
  288.  
  289. ED * finded (char * str, int doff)
  290.  
  291. {
  292.     ED *ed;
  293.  
  294.     for (ed = (ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc((struct Node *)ed))
  295.     {
  296.     if (strlen (ed->name) >= doff && stricmp (str, ed->name+doff) == 0)
  297.         return (ed);
  298.     }
  299.  
  300.     return (NULL);
  301. } /* finded */
  302.  
  303.  
  304. void mountrequest (int bool)
  305. {
  306.     static APTR     original_pr_WindowPtr = NULL;
  307.     register PROC * proc;
  308.  
  309.     proc = (PROC *)FindTask (0);
  310.  
  311.     if (!bool && proc->pr_WindowPtr != (APTR)-1)
  312.     {
  313.     original_pr_WindowPtr = proc->pr_WindowPtr;
  314.     proc->pr_WindowPtr    = (APTR)-1;
  315.     }
  316.  
  317.     if (bool && proc->pr_WindowPtr == (APTR)-1)
  318.     proc->pr_WindowPtr = original_pr_WindowPtr;
  319. } /* mountrequest */
  320.  
  321.  
  322. /*
  323.  *  GETFONT()
  324.  *
  325.  *  This function properly searches resident and disk fonts for the
  326.  *  font.
  327.  */
  328.  
  329. struct Library * DiskfontBase;
  330.  
  331. FONT * GetFont (char * name, short size)
  332. {
  333.     FONT * font1;
  334.     TA       Ta;
  335.     USHORT pos;
  336.  
  337.     strcpy (tmp_buffer, name);
  338.     pos = strlen (tmp_buffer);
  339.  
  340.     if (pos < 6 || (pos > 5 && stricmp (tmp_buffer + pos - 5, ".font")))
  341.     strcpy (tmp_buffer + pos, ".font");
  342.  
  343.     Ta.ta_Name    = (UBYTE *)tmp_buffer;
  344.     Ta.ta_YSize = size;
  345.     Ta.ta_Style = 0;
  346.     Ta.ta_Flags = 0;
  347.  
  348.     font1 = OpenFont (&Ta);
  349.  
  350.     if (!font1 || font1->tf_YSize != Ta.ta_YSize)
  351.     {
  352.     FONT * font2;
  353.  
  354.     if (DiskfontBase = OpenLibrary ("diskfont.library", 0L))
  355.     {
  356.         if (font2 = OpenDiskFont (&Ta))
  357.         {
  358.         if (font1)
  359.             CloseFont (font1);
  360.  
  361.         font1 = font2;
  362.  
  363.         CloseLibrary (DiskfontBase);
  364.         }
  365.     }
  366.     } /* if !font1 || Wrong_Font_Size */
  367.  
  368.     return (font1);
  369. } /* GetFont */
  370.  
  371.  
  372. void movetocursor (void)
  373. {
  374.     Move (Ep->win->RPort, COLT(Ep->column - Ep->topcolumn),
  375.       ROWT(Ep->line - Ep->topline));
  376. } /* movetocursor */
  377.  
  378.  
  379. int extend (ED * ep, int lines)
  380. {
  381.     long   extra = ep->maxlines - ep->lines;
  382.     LINE * list;
  383.  
  384.     if (lines > extra)
  385.     {
  386.     lines += ep->lines;
  387.  
  388.     if (list = (LINE *)alloclptr(lines))
  389.     {
  390.         bmovl (ep->list, list, ep->lines);
  391.         FreeMem (ep->list, sizeof(LINE) * ep->maxlines);
  392.  
  393.         ep->maxlines = lines;
  394.         ep->list     = list;
  395.  
  396.         return (1);
  397.     }
  398.  
  399.     nomemory ();
  400.     return (0);
  401.     }
  402.  
  403.     return (1);
  404. } /* extend */
  405.  
  406.  
  407. int makeroom (int n)
  408. {
  409.     ED * ep = Ep;
  410.  
  411.     if (ep->lines >= ep->maxlines)
  412.     return (extend (ep, n));
  413.  
  414.     return (1);
  415. } /* makeroom */
  416.  
  417.  
  418. void freelist (LINE * list, int n)
  419. {
  420.     while (n)
  421.     {
  422.     freeline (list[0]);
  423.     list ++;
  424.     n --;
  425.     }
  426. } /* freelist */
  427.  
  428.  
  429. void do_undo (void)
  430. {
  431.     text_load ();
  432.     text_redisplaycurrline ();
  433. } /* do_undo */
  434.  
  435.  
  436. long lineflags (int line)
  437. {
  438.     long flags;
  439.  
  440.     if (line < Ep->topline)
  441.     flags = LINE_ABOVE;
  442.     else if (line < Ep->topline + Lines)
  443.     flags = LINE_VISIBLE;
  444.     else
  445.     flags = LINE_BELOW;
  446.  
  447.     return (flags);
  448. } /* lineflags */
  449.  
  450.  
  451. void scroll_display (short dx, short dy, Column lc, Line tl, Column rc, Line bl)
  452. {
  453.     ushort width, height;
  454.     Line lines, rest;
  455.     ushort x1, y1, x2, y2, t;
  456.     Line bottom;
  457.     Column right;
  458.     RP * rp;
  459.  
  460.     /* don't do anything if we are not allowed */
  461.     if (Ep->iconmode || Nsu || (!dx && !dy)) return;
  462.  
  463.     /* clip coords */
  464.     if (tl < Ep->topline)
  465.     tl = Ep->topline;
  466.  
  467.     if (bl >= Ep->topline+Lines)
  468.     bl = Ep->topline + Lines - 1;
  469.  
  470.     if (lc < Ep->topcolumn)
  471.     lc = Ep->topcolumn;
  472.  
  473.     if (rc >= Ep->topcolumn+Columns)
  474.     rc = Ep->topcolumn + Columns - 1;
  475.  
  476.     /* check if area is visible */
  477.     if (bl < tl || rc < lc) return;
  478.  
  479.     /* is there something below the text */
  480.     if (bl > Ep->lines)
  481.     {
  482.     bottom = bl - Ep->lines + 1;
  483.     } else
  484.     {
  485.     bottom = 0;
  486.     }
  487.  
  488.     /* is there something to the right */
  489.     if (rc > MAXLINELEN)
  490.     {
  491.     right = rc - MAXLINELEN + 1;
  492.     } else
  493.     {
  494.     right = 0;
  495.     }
  496.  
  497.     /* get size of real text */
  498.     width  = rc - lc + 1 - right;
  499.     height = bl - tl + 1 - bottom;
  500.  
  501.     if (dx)
  502.     {
  503.     lines = ABS(dx);    /* number of columns to draw */
  504.  
  505.     if (lines >= width)
  506.          rest = 0;
  507.     else rest = width - lines;
  508.  
  509.     dx *= Xsize;
  510.     } else
  511.     {
  512.     lines = ABS(dy);    /* number of lines to draw */
  513.  
  514.     /* if the number of new lines is bigger than the height of the
  515.        remaining text, we have to erase the empty lines. Otherwise
  516.        we store the first line of the area that is to update in rest. */
  517.  
  518.     if (lines >= height)
  519.          rest = 0;
  520.     else rest = height - lines;
  521.  
  522.     dy *= Ysize;
  523.     }
  524.  
  525.     x1 = lc - Ep->topcolumn;
  526.     x2 = rc - Ep->topcolumn;
  527.     y1 = tl - Ep->topline;
  528.     y2 = bl - Ep->topline;
  529.  
  530.     t = y1;
  531.  
  532.     x1 = COL(x1);
  533.     x2 = COL(x2+1)-1;
  534.     y1 = ROW(y1);
  535.     y2 = ROW(y2+1)-1;
  536.  
  537.     rp = Ep->win->RPort;
  538.  
  539. #ifdef MYDEBUG
  540.     D(bug("scroll_display: rest %ld  height %ld  lines %ld  t %ld (%ld,%ld)-(%ld,%ld)\n",
  541.       rest, height, lines, t, x1, y1, x2, y2));
  542. #endif
  543.  
  544.     SetWrMsk (rp, -1);
  545.     SetBPen (rp, TEXT_BPEN);
  546.  
  547.     if (rest)
  548.     {
  549.     ScrollRaster (rp, dx, dy, x1, y1, x2, y2);
  550.  
  551.     if (dx)
  552.     {
  553.         Line   line;
  554.         Column col;
  555.  
  556.         line = tl;
  557.         col  = lc;
  558.  
  559.         if (dx > 0)
  560.         col += rest;
  561.  
  562.         redraw_block (TRUE, line, col, line + height, col + lines - 1);
  563.     } else
  564.     {
  565.         if (dy < 0)
  566.         {
  567.         text_displayseg (t, lines);
  568.         } else
  569.         {
  570.         text_displayseg (t+rest, lines);
  571.         }
  572.     }
  573.     } else
  574.     {
  575.     SetAPen (rp, TEXT_BPEN);
  576.     RectFill (rp, x1, y1, x2, y2);
  577.  
  578.     text_displayseg (t, height);
  579.     }
  580. } /* scroll_display */
  581.  
  582.  
  583. char * skip_whitespace (char * ptr)
  584. {
  585.     while (isspace (*ptr)) ptr ++;
  586.  
  587.     return (ptr);
  588. } /* skip_whitespace */
  589.  
  590.  
  591. /*
  592.  *  IS_NUMBER
  593.  *  tests if a string represents a valid number, i.e.
  594.  *  if there are only numbers in it ( what about spaces around,
  595.  *  and + before a number, do they disturb atol??? )
  596.  */
  597.  
  598. char is_number (char * str)           /* represents a string a number? */
  599. {
  600.     while (*str==' ')           /* ignore leading spaces */
  601.     {
  602.     str++;
  603.     } /* while */
  604.  
  605.     if ((*str=='-')||(*str=='+'))  /* dont worry about +/- */
  606.     {
  607.     str++;
  608.     } /* if */
  609.  
  610.     while (isdigit(*str))     /* if there are only numbers in str: ok */
  611.     {
  612.     str++;
  613.     } /* while */
  614.  
  615.     while (*str==' ')          /* ignore ending spaces */
  616.     {
  617.     str++;
  618.     } /* while */
  619.  
  620.     return (!*str);
  621. } /* is_number */
  622.  
  623.  
  624. char * getnextcomline (FILE* fi, int * lineno)
  625. {
  626.     /* skipps comments and emptylines */
  627.     char* buf;
  628.     char* ptr;
  629.     do
  630.     {
  631.     if (lineno)
  632.     {
  633.         (*lineno)++; /* Welches hat Priortaet?? */
  634.     } /* if */
  635.  
  636.     buf = tmp_buffer;
  637.     if ((xefgets(fi, tmp_buffer, LINE_LENGTH))<0)
  638.     /* buf = fgets(tmp_buffer, LINE_LENGTH, fi); */
  639.     if (!buf)
  640.     {
  641.         error ("%s:\nUnexpected End Of File Encountered", av[0]);
  642.         return(NULL);
  643.     } /* if */
  644.     buf[255] = 0; /* marker for eol */
  645.     while (*buf<33 && *buf)
  646.     {
  647.         buf++;
  648.     } /* while */
  649.     } while (buf[0] == 0 || buf[0] == '#');
  650.     for (ptr = buf; *ptr;ptr++)
  651.     {
  652.     if (*ptr == 10)
  653.     {
  654.         *ptr = 0;
  655.     } /* if */
  656.     } /* for */
  657.     return(buf);
  658. } /* getnextcomline */
  659.  
  660.  
  661. /*
  662.  *  fname
  663.  *
  664.  *  instead of a macro: sets a ptr to the filename of a full path&filename
  665.  *  (returniert einen Zeiger auf den namensteil eines pfades)
  666.  *
  667.  * SHOULD BE PUT INTO SUBS.C
  668.  */
  669.  
  670. char * fname (char * fullpath)
  671. {
  672.     return (FilePart (fullpath));
  673. } /* fname */
  674.  
  675.  
  676. Bool switch_ed (ED * newed)
  677. {
  678.     Bool success;
  679.  
  680.     if (newed)
  681.     {
  682.     if (Ep)
  683.         text_sync ();
  684.  
  685.     Ep = newed;
  686.  
  687.     text_load ();
  688.  
  689.     if (!Ep->iconmode)
  690.     {
  691.         set_window_params ();
  692.         window_title ();
  693.     }
  694.  
  695.     text_cursor (1);
  696.  
  697.     success = TRUE;
  698.     } else
  699.     success = FALSE;
  700.  
  701.     return (success);
  702. } /* switch_ed */
  703.  
  704.  
  705. void do_makecursorvisible (void)
  706. {
  707.     if ((Ep->win->Flags & WFLG_WINDOWACTIVE) && !Ep->iconmode)
  708.     {
  709.     USHORT x1 = COL(Ep->column - Ep->topcolumn) + Ep->win->LeftEdge;
  710.     USHORT y1 = ROW(Ep->line   - Ep->topline)   + Ep->win->TopEdge;
  711.     USHORT x2, y2;
  712.  
  713.     x2 = x1 + (Xsize << 2) + Xsize;
  714.     y2 = y1 + (Ysize << 2) + Ysize;
  715.  
  716.     if (x1 < (Xsize << 2))
  717.         x1 = 0;
  718.     else
  719.         x1 -= Xsize << 2;
  720.  
  721.     if (y1 < (Ysize << 2))
  722.         y1 = 0;
  723.     else
  724.         y1 -= Ysize << 2;
  725.  
  726.     MakeRectVisible (Ep->win, x1, y1, x2, y2);
  727.     }
  728. } /* do_makecursorvisible */
  729.  
  730.  
  731. void MakeRectVisible (WIN * win, USHORT minx, USHORT miny, USHORT maxx,
  732.                                    USHORT maxy)
  733. {
  734.     struct DimensionInfo diminfo;
  735.     struct Screen      * screen        = win->WScreen;
  736.     ULONG         Width, Height;
  737.     WORD         dx, dy;
  738.  
  739.     GetDisplayInfoData (NULL,
  740.             (UBYTE *)&diminfo,
  741.             sizeof(diminfo),
  742.             DTAG_DIMS,
  743.             GetVPModeID (&screen->ViewPort)
  744.     );
  745.  
  746.     Width  = diminfo.TxtOScan.MaxX - diminfo.TxtOScan.MinX;
  747.     Height = diminfo.TxtOScan.MaxY - diminfo.TxtOScan.MinY;
  748.  
  749.     if (Width > screen->Width)
  750.     Width = screen->Width;
  751.  
  752.     if (Height > screen->Height)
  753.     Height = screen->Height;
  754.  
  755.     if (minx < win->LeftEdge)
  756.     minx = win->LeftEdge;
  757.  
  758.     if (miny < win->TopEdge)
  759.     miny = win->TopEdge;
  760.  
  761.     if (maxx > win->LeftEdge + win->Width)
  762.     maxx = win->LeftEdge + win->Width;
  763.  
  764.     if (maxy > win->TopEdge + win->Height)
  765.     maxy = win->TopEdge + win->Height;
  766.  
  767.     dx = (Width - screen->LeftEdge) - maxx + 1;
  768.  
  769.     if (dx > 0)
  770.     {
  771.     dx = minx + screen->LeftEdge;
  772.  
  773.     if (dx > 0)
  774.         dx = 0;
  775.     else
  776.         dx = -dx;
  777.     }
  778.  
  779.     dy = (Height - screen->TopEdge) - maxy + 1;
  780.  
  781.     if (dy > 0)
  782.     {
  783.     dy = miny + screen->TopEdge;
  784.  
  785.     if (dy >= 0)
  786.         dy = 0;
  787.     else
  788.         dy = -dy;
  789.     }
  790.  
  791.     MoveScreen (screen, dx, dy);
  792. } /* MakeRectVisible */
  793.  
  794.  
  795. int LINELEN (ED * ep, Line nr)
  796. {
  797.     int len;
  798.  
  799.     if (nr == ep->line)
  800.     {
  801.     /* line is in Current */
  802.  
  803.     if ((len = lastns ((char *)Current)) || (*Current && *Current != ' '))
  804.         len ++;
  805.     }
  806.     else
  807.     len = strlen (GETTEXT(ep,nr));
  808.  
  809.     return (len);
  810. } /* LINELEN */
  811.  
  812.  
  813. /******************************************************************************
  814. *****  ENDE subs.c
  815. ******************************************************************************/
  816.