home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / subs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-22  |  21.4 KB  |  1,027 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: subs.c 1.4 1994/09/09 12:31:30 digulla Exp digulla $
  5.  
  6.     DESCRIPTION
  7.     General subroutines.
  8.  
  9.     HISTORY
  10.     16. Jan 1993    ada created
  11.     $Log: subs.c $
  12.  * Revision 1.4  1994/09/09  12:31:30  digulla
  13.  * added new style Prototypes, DEFCMD and DEFHELP
  14.  *
  15.  * Revision 1.3  1994/08/30  11:09:04  digulla
  16.  * use BLOCK_MASK for scrolling (faster than ALL_MASK)
  17.  *
  18.  * Revision 1.2  1994/08/19  14:08:06  digulla
  19.  * fixed SetWrMsk()
  20.  *
  21.  * Revision 1.1  1994/08/13  16:38:21  digulla
  22.  * Initial revision
  23.  *
  24.  
  25. ******************************************************************************/
  26.  
  27. /**************************************
  28.         Includes
  29. **************************************/
  30.  
  31. #include "defs.h"
  32. #include <clib/macros.h>
  33. #include <graphics/display.h>
  34. #include <proto/diskfont.h>
  35. #define MYDEBUG     0
  36. #include "debug.h"
  37.  
  38.  
  39. /**************************************
  40.         Globale Variable
  41. **************************************/
  42.  
  43. /* Assembler */
  44. Prototype void swapmem (void *, void *, ULONG);
  45.  
  46.  
  47. /**************************************
  48.       Interne Defines & Strukturen
  49. **************************************/
  50. typedef struct FileInfoBlock FIB;
  51.  
  52.  
  53. /**************************************
  54.         Interne Variable
  55. **************************************/
  56.  
  57.  
  58. /**************************************
  59.        Interne Prototypes
  60. **************************************/
  61.  
  62.  
  63. /*
  64.  *  Create XDME's text icon.
  65.  */
  66.  
  67. Prototype void makemygadget (struct Gadget *gad);
  68.  
  69. #if 1 /* alternate icon */
  70. void makemygadget (struct Gadget *gad)
  71. {
  72.     static UWORD IconI1Data[] =
  73.     {
  74.     /* Plane 0 */
  75.       0x0000,0x0800,0x1542,0x4800,0x1282,0x4800,0x7FFF,0xF800,
  76.       0x4000,0x0800,0x5C80,0x0800,0x4000,0x0800,0x5BDB,0x8800,
  77.       0x4000,0x0800,0x57CE,0x8800,0x4000,0x0800,0x5FDF,0x8800,
  78.       0x4000,0x3800,0x5B75,0x8800,0x4000,0x3800,0x0000,0x0800,
  79.       0xFFFF,0xF800,
  80.     /* Plane 1 */
  81.       0xFFFF,0xF000,0x8000,0x0000,0x8000,0x0000,0x8000,0x0000,
  82.       0x8000,0x4000,0x8000,0x4000,0x8000,0x4000,0x8000,0x4000,
  83.       0x8000,0x7000,0x8000,0x4000,0x8000,0x4000,0x8000,0x4000,
  84.       0x8000,0x4000,0x8000,0x4000,0x8000,0x4000,0xFFFF,0xC000,
  85.       0x0000,0x0000,
  86.     };
  87.  
  88.     static struct Image IconI1 =
  89.     {
  90.       0, 0, 21, 17, 2, IconI1Data, 0x0003, 0x0000, NULL
  91.     };
  92.  
  93.     static UWORD IconI2Data[] =
  94.     {
  95.     /* Plane 0 */
  96.       0x0000,0x0800,0x755F,0xF800,0x729F,0xF800,0x7FFF,0xF800,
  97.       0x4000,0x0800,0x5C80,0x0800,0x4000,0x0800,0x5BDB,0x8800,
  98.       0x4000,0x3800,0x57CE,0xB800,0x4000,0x3800,0x5FDF,0xB800,
  99.       0x4000,0x3800,0x5B75,0xB800,0x4000,0x3800,0x0000,0x3800,
  100.       0xFFFF,0xF800,
  101.     /* Plane 1 */
  102.       0xFFFF,0xF000,0xE01D,0xB000,0xE01D,0xB000,0x8000,0x0000,
  103.       0x8000,0x5000,0x8000,0x5000,0x8000,0x5000,0x8000,0x5000,
  104.       0x8000,0x7000,0x8030,0x7000,0x8030,0x7000,0x8000,0x7000,
  105.       0x8000,0x4000,0x8000,0x7000,0x8000,0x4000,0xFFFF,0xF000,
  106.       0x0000,0x0000,
  107.     };
  108.  
  109.     static struct Image IconI2 =
  110.     {
  111.       0, 0, 21, 17, 2, IconI2Data, 0x0003, 0x0000, NULL
  112.     };
  113.  
  114.     memset (gad, 0, sizeof(struct Gadget));
  115.  
  116.     gad->Width          = 21;
  117.     gad->Height       = 18;
  118.     gad->Flags          = GFLG_GADGIMAGE | GFLG_GADGHIMAGE;
  119.     gad->GadgetType   = BOOLGADGET;
  120.     gad->Activation   = GACT_RELVERIFY | GACT_IMMEDIATE;
  121.     gad->GadgetRender = (APTR)&IconI1;
  122.     gad->SelectRender = (APTR)&IconI2;
  123. } /* makemygadget */
  124. #else
  125. void makemygadget (struct Gadget *gad)
  126. {
  127.     static const UWORD ga[] =
  128.     {
  129.      /* Plane 0 */
  130.      0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0C00,
  131.      0x0000,0x0000,0x0000,0x0C00,0x0FFF,0xFFFF,0xFFFF,0x8C00,
  132.      0x0C00,0x0000,0x0000,0x0C00,0x0C1F,0xFFFF,0xFFE0,0x0C00,
  133.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x08BF,0xFFE0,0x0C00,
  134.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x25FF,0xFFE0,0x0C00,
  135.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x0BFF,0xFFE0,0x0C00,
  136.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x1FFF,0xFFE0,0x0C00,
  137.      0x0C16,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x7FFF,0xFFE0,0x0C00,
  138.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0800,0x0000,0x0000,0x0C00,
  139.      0x0000,0x0000,0x0000,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  140.      0x0031,0x98CE,0x7318,0x0C00,0x001B,0x186F,0xF318,0x0C00,
  141.      0x001B,0x186F,0xF360,0x0C00,0x000E,0x186D,0xB3E0,0x0C00,
  142.      0x001B,0x186D,0xB360,0x0C00,0x001B,0x186C,0x3318,0x0C00,
  143.      0x0031,0x98CC,0x3318,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  144.      0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
  145.      /* Plane 1 */
  146.      0xFFFF,0xFFFF,0xFFFF,0xF800,0xD555,0x5555,0x5555,0x5000,
  147.      0xD555,0x5555,0x5555,0x5000,0xD000,0x0000,0x0000,0x5000,
  148.      0xD000,0x0000,0x0000,0xD000,0xD000,0x0000,0x0000,0xD000,
  149.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  150.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  151.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  152.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  153.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  154.      0xD003,0xFFFF,0xFF00,0xD000,0xD7FF,0xFFFF,0xFFFF,0xD000,
  155.      0xD555,0x5555,0x5555,0x5000,0xD504,0x0041,0x0005,0x5000,
  156.      0xD544,0x4511,0x0445,0x5000,0xD544,0x4510,0x0445,0x5000,
  157.      0xD544,0x4510,0x0415,0x5000,0xD551,0x4510,0x4415,0x5000,
  158.      0xD544,0x4510,0x4415,0x5000,0xD544,0x4511,0x4445,0x5000,
  159.      0xD544,0x4511,0x4445,0x5000,0xD504,0x0041,0x0005,0x5000,
  160.      0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000
  161.     };
  162.     static const struct Image image =
  163.     {
  164.      0, 0, 54, 30, 2, (UWORD *)ga, 3, 0, NULL
  165.     };
  166.  
  167.     memset (gad, 0, sizeof(struct Gadget));
  168.  
  169.     gad->Width          = 54;
  170.     gad->Height       = 31; /* Blank line between Image and Text ! */
  171.     gad->Flags          = GADGIMAGE|GADGHCOMP;
  172.     gad->GadgetType   = BOOLGADGET;
  173.     gad->Activation   = RELVERIFY|GADGIMMEDIATE;
  174.     gad->GadgetRender = (APTR)ℑ
  175. } /* makemygadget */
  176. #endif
  177.  
  178.  
  179. /*
  180.  * return index of first non space.  Returns 0 if no spaces found.
  181.  */
  182.  
  183. Prototype int firstns (char * str);
  184.  
  185. int firstns (char * str)
  186. {
  187.     WORD  i;
  188.  
  189.     for (i = 0; str[i] && str[i] == ' '; i ++);
  190.  
  191.     if (str[i] == 0)
  192.     i = 0;
  193.  
  194.     return (i);
  195. } /* firstns */
  196.  
  197.  
  198. /*
  199.  *  Return index of last non-space, 0 if no spaces.
  200.  */
  201.  
  202. Prototype int lastns (char * str);
  203.  
  204. int lastns (char * str)
  205. {
  206.     WORD  i;
  207.  
  208.     /* get last char of string (i might be -1 after that !).
  209.        now walk left until a char != ' ' is found or i == 0. */
  210.     for (i = strlen(str) - 1; i > 0 && str[i] == ' '; i --);
  211.  
  212.     if (i < 0)  /* string empty */
  213.     i = 0;
  214.  
  215.     return (i);
  216. } /* lastns */
  217.  
  218.  
  219. /*
  220.  *  Return length of word under cursor
  221.  */
  222.  
  223. Prototype int wordlen (char * str);
  224.  
  225. int wordlen (char * str)
  226. {
  227.     WORD  i;
  228.  
  229.     for (i = 0; *str && *str != ' '; ++i, ++str);
  230.  
  231.     return(i);
  232. } /* wordlen */
  233.  
  234.  
  235. /*
  236.  *  Backtracks the program lock, 0 on failure, 1 on success.
  237.  *  The filename is appended to the lock, if it exists.
  238.  */
  239.  
  240. Prototype BOOL getpathto (BPTR lock, char * filename, char * buf);
  241.  
  242. BOOL getpathto (BPTR lock, char * filename, char * buf)
  243. {
  244.     if (!NameFromLock (lock, buf, PATHSIZE))
  245.     return (FALSE);
  246.  
  247.     if (filename)
  248.     AddPart (buf, filename, PATHSIZE);
  249.  
  250.     return (TRUE);
  251. }
  252.  
  253.  
  254. /*
  255.  *  Allocation routines and other shortcuts
  256.  */
  257.  
  258. static LINE empty_line = "";
  259. static APTR LINE_Pool = NULL;
  260.  
  261. #ifndef ONLY_V39
  262.     void * __asm AsmAllocPooled(register __a0 void *,
  263.                     register __d0 ULONG,
  264.                     register __a6 struct ExecBase *);
  265.     void __asm AsmFreePooled(register __a0 void *,
  266.                  register __a1 void *,
  267.                  register __d0 ULONG,
  268.                  register __a6 struct ExecBase *);
  269.     void * __asm AsmCreatePool(register __d0 ULONG,
  270.                    register __d1 ULONG,
  271.                    register __d2 ULONG,
  272.                    register __a6 struct ExecBase *);
  273.     void __asm AsmDeletePool(register __a0 void *,
  274.                  register __a6 struct ExecBase *);
  275.  
  276. extern struct ExecBase *SysBase;
  277. #define LibAllocPooled(p,s)   AsmAllocPooled(p,s,SysBase)
  278. #define LibFreePooled(p,x,s)  AsmFreePooled(p,x,s,SysBase)
  279. #define LibCreatePool(f,s,t)  AsmCreatePool(f,s,t,SysBase)
  280. #define LibDeletePool(p)      AsmDeletePool(p,SysBase)
  281. #else
  282. #define LibAllocPooled(p,s)   AllocPooled(p,s)
  283. #define LibFreePooled(p,x,s)  FreePooled(p,x,s)
  284. #define LibCreatePool(f,s,t)  CreatePool(f,s,t)
  285. #define LibDeletePool(p)      DeletePool(p)
  286. #endif
  287.  
  288. Prototype LINE allocline (long size);
  289.  
  290. LINE allocline (long size)
  291. {
  292.      if (size <= 1) return (empty_line);     /* no more tiny empty blocks */
  293.  
  294.      /* Make sure we always get a padded block */
  295.      size += 7;
  296.      size &= ~7;
  297.  
  298.      /* return (AllocMem (size, 0)); */
  299.      return (LibAllocPooled (LINE_Pool, size));
  300. } /* allocline */
  301.  
  302.  
  303. Prototype void freeline (LINE line);
  304.  
  305. void freeline (LINE line)
  306. {
  307.     WORD  size;
  308.  
  309.     if (line && line != empty_line)
  310.     {
  311.     size = strlen (line) + 8;
  312.     size &= ~7;
  313.  
  314.     /* FreeMem (line, size); */
  315.     LibFreePooled (LINE_Pool, line, size);
  316.     }
  317. } /* freeline */
  318.  
  319. DEFAUTOINIT( LINE_Initialize )
  320. {
  321.     LINE_Pool = LibCreatePool (0, 4096, 4096);
  322. }
  323.  
  324. DEFAUTOEXIT( LINE_Terminate )
  325. {
  326.     if (LINE_Pool)
  327.     LibDeletePool(LINE_Pool);
  328.     LINE_Pool = NULL;
  329. }
  330.  
  331.  
  332. /*
  333.  *  Remove tabs in a buffer
  334.  */
  335.  
  336. Prototype int detab (char * ibuf, char * obuf, int maxlen);
  337.  
  338. int detab (char * ibuf, char * obuf, int maxlen)
  339. {
  340.     WORD  i, j;
  341.  
  342.     maxlen -= 1;
  343.  
  344.     for (i = j = 0; ibuf[i] && j < maxlen; ++i)
  345.     {
  346.     if (ibuf[i] == 9)
  347.     {
  348.         do
  349.         {
  350.         obuf[j++] = ' ';
  351.         } while ((j & 7) && j < maxlen);
  352.     } else
  353.     {
  354.         obuf[j++] = ibuf[i];
  355.     }
  356.     }
  357.  
  358.     if (j && obuf[j-1] == '\n')
  359.     --j;
  360.  
  361.     while (j && obuf[j-1] == ' ')
  362.     --j;
  363.  
  364.     obuf[j] = 0;
  365.  
  366.     return (j);
  367. } /* detab */
  368.  
  369.  
  370. Prototype int xefgets (FILE * fi, char * buf, int max);
  371.  
  372. int xefgets (FILE * fi, char * buf, int max)
  373. {
  374.     char ebuf[MAXLINELEN];
  375.  
  376.     if (breakcheck())   /* PATCH_NULL  20-07-94 added */
  377.     return -1;    /* PATCH_NULL  20-07-94 added */
  378.  
  379.     if (fgets (ebuf, max, fi))
  380.     return (detab (ebuf, buf, max));
  381.  
  382.     return (-1);
  383. } /* xefgets */
  384.  
  385.  
  386. Prototype ED * finded (char * str, int doff);
  387.  
  388. ED * finded (char * str, int doff)
  389. {
  390.     ED *ed;
  391.  
  392.     /* PATCH_NULL 05-11-94 : at least _IGNORE_    paths (we'd better scan them) */
  393.     char *fp;
  394.     if (!doff && (fp = FilePart(str)))
  395.     {
  396.     ULONG diff = (ULONG)fp - (ULONG)str;
  397.     str += diff;
  398.     }
  399.  
  400.  
  401.     for (ed = (ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc((struct Node *)ed))
  402.     {
  403.     if (strlen (ed->name) >= doff && stricmp (str, ed->name+doff) == 0)
  404.         break;
  405.     }
  406.  
  407.     return ed;
  408. } /* finded */
  409.  
  410.  
  411. Prototype void mountrequest (int bool);
  412.  
  413. void mountrequest (int bool)
  414. {
  415.     static APTR     original_pr_WindowPtr = NULL;
  416.     register PROC * proc;
  417.  
  418.     proc = (PROC *)FindTask (0);
  419.  
  420.     if (!bool && proc->pr_WindowPtr != (APTR)-1)
  421.     {
  422.     original_pr_WindowPtr = proc->pr_WindowPtr;
  423.     proc->pr_WindowPtr    = (APTR)-1;
  424.     }
  425.  
  426.     if (bool && proc->pr_WindowPtr == (APTR)-1)
  427.     proc->pr_WindowPtr = original_pr_WindowPtr;
  428. } /* mountrequest */
  429.  
  430.  
  431. /*
  432.  *  GETFONT()
  433.  *
  434.  *  This function properly searches resident and disk fonts for the
  435.  *  font.
  436.  */
  437.  
  438. struct Library * DiskfontBase;
  439.  
  440. Prototype FONT * GetFont (char * name, WORD  size);
  441.  
  442. FONT * GetFont (char * name, WORD  size)
  443. {
  444.     FONT * font1;
  445.     TA       Ta;
  446.     UWORD pos;
  447.  
  448.     strcpy (tmp_buffer, name);
  449.     pos = strlen (tmp_buffer);
  450.  
  451.     if (pos < 6 || (pos > 5 && stricmp (tmp_buffer + pos - 5, ".font")))
  452.     strcpy (tmp_buffer + pos, ".font");
  453.  
  454.     Ta.ta_Name    = (UBYTE *)tmp_buffer;
  455.     Ta.ta_YSize = size;
  456.     Ta.ta_Style = 0;
  457.     Ta.ta_Flags = 0;
  458.  
  459.     font1 = OpenFont (&Ta);
  460.  
  461.     if (!font1 || font1->tf_YSize != Ta.ta_YSize)
  462.     {
  463.     FONT * font2;
  464.  
  465.     if (DiskfontBase = OpenLibrary ("diskfont.library", 0L))
  466.     {
  467.         if (font2 = OpenDiskFont (&Ta))
  468.         {
  469.         if (font1)
  470.             CloseFont (font1);
  471.  
  472.         font1 = font2;
  473.  
  474.         CloseLibrary (DiskfontBase);
  475.         }
  476.     }
  477.     } /* if !font1 || Wrong_Font_Size */
  478.  
  479.     return (font1);
  480. } /* GetFont */
  481.  
  482.  
  483. Prototype void movetocursor (void);
  484.  
  485. void movetocursor (void)
  486. {
  487.     Move (Ep->win->RPort, COLT(Ep->column - Ep->topcolumn),
  488.       ROWT(Ep->line - Ep->topline));
  489. } /* movetocursor */
  490.  
  491.  
  492. Prototype int extend (ED * ep, int lines);
  493.  
  494. int extend (ED * ep, int lines)
  495. {
  496.     long   extra = ep->maxlines - ep->lines;
  497.     LINE * list;
  498.  
  499.     if (lines > extra)
  500.     {
  501.     lines += ep->lines;
  502.  
  503.     if (list = (LINE *)alloclptr(lines))
  504.     {
  505.         bmovl (ep->list, list, ep->lines);
  506.         FreeMem (ep->list, sizeof(LINE) * ep->maxlines);
  507.  
  508.         ep->maxlines = lines;
  509.         ep->list     = list;
  510.  
  511.         return (1);
  512.     }
  513.  
  514.     nomemory ();
  515.     return (0);
  516.     }
  517.  
  518.     return (1);
  519. } /* extend */
  520.  
  521.  
  522. Prototype int makeroom (int n);
  523.  
  524. int makeroom (int n)
  525. {
  526.     ED * ep = Ep;
  527.  
  528.     if (ep->lines >= ep->maxlines)
  529.     return (extend (ep, n));
  530.  
  531.     return (1);
  532. } /* makeroom */
  533.  
  534.  
  535. Prototype void freelist (LINE * list, int n);
  536.  
  537. void freelist (LINE * list, int n)
  538. {
  539.     while (n)
  540.     {
  541.     freeline (list[0]);
  542.     list ++;
  543.     n --;
  544.     }
  545. } /* freelist */
  546.  
  547.  
  548. /*DEFHELP #cmd misc UNDO - undo current line (must be mapped to a key to work) */
  549.  
  550. DEFUSERCMD("undo", 0, 0, void, do_undo, (void),)
  551. {
  552.     text_load ();
  553.     text_redisplaycurrline ();
  554. } /* do_undo */
  555.  
  556.  
  557. Prototype long lineflags (int line);
  558.  
  559. long lineflags (int line)
  560. {
  561.     long flags;
  562.  
  563.     if (line < Ep->topline)
  564.     flags = LINE_ABOVE;
  565.     else if (line < Ep->topline + Lines)
  566.     flags = LINE_VISIBLE;
  567.     else
  568.     flags = LINE_BELOW;
  569.  
  570.     return (flags);
  571. } /* lineflags */
  572.  
  573.  
  574. Prototype void scroll_display (WORD dx, WORD dy, Column lc, Line tl, Column rc, Line bl);
  575.  
  576. void scroll_display (WORD dx, WORD dy, Column lc, Line tl, Column rc, Line bl)
  577. {
  578.     UWORD width, height;
  579.     Line lines, rest;
  580.     UWORD x1, y1, x2, y2, t;
  581.     Line bottom;
  582.     Column right;
  583.     RP * rp;
  584.  
  585.     /* don't do anything if we are not allowed */
  586.     if (GETF_ICONMODE(Ep) || Nsu || (!dx && !dy)) return;
  587.  
  588.     /* clip coords */
  589.     if (tl < Ep->topline)
  590.     tl = Ep->topline;
  591.  
  592.     if (bl >= Ep->topline+Lines)
  593.     bl = Ep->topline + Lines - 1;
  594.  
  595.     if (lc < Ep->topcolumn)
  596.     lc = Ep->topcolumn;
  597.  
  598.     if (rc >= Ep->topcolumn+Columns)
  599.     rc = Ep->topcolumn + Columns - 1;
  600.  
  601.     /* check if area is visible */
  602.     if (bl < tl || rc < lc) return;
  603.  
  604.     /* is there something below the text */
  605.     if (bl > Ep->lines)
  606.     {
  607.     bottom = bl - Ep->lines + 1;
  608.     } else
  609.     {
  610.     bottom = 0;
  611.     }
  612.  
  613.     /* is there something to the right */
  614.     if (rc > MAXLINELEN)
  615.     {
  616.     right = rc - MAXLINELEN + 1;
  617.     } else
  618.     {
  619.     right = 0;
  620.     }
  621.  
  622.     /* get size of real text */
  623.     width  = rc - lc + 1 - right;
  624.     height = bl - tl + 1 - bottom;
  625.  
  626.     if (dx)
  627.     {
  628.     lines = ABS(dx);    /* number of columns to draw */
  629.  
  630.     if (lines >= width)
  631.          rest = 0;
  632.     else rest = width - lines;
  633.  
  634.     dx *= Xsize;
  635.     } else
  636.     {
  637.     lines = ABS(dy);    /* number of lines to draw */
  638.  
  639.     /* if the number of new lines is bigger than the height of the
  640.        remaining text, we have to erase the empty lines. Otherwise
  641.        we store the first line of the area that is to update in rest. */
  642.  
  643.     if (lines >= height)
  644.          rest = 0;
  645.     else rest = height - lines;
  646.  
  647.     dy *= Ysize;
  648.     }
  649.  
  650.     x1 = lc - Ep->topcolumn;
  651.     x2 = rc - Ep->topcolumn;
  652.     y1 = tl - Ep->topline;
  653.     y2 = bl - Ep->topline;
  654.  
  655.     t = y1;
  656.  
  657.     x1 = COL(x1);
  658.     x2 = COL(x2+1)-1;
  659.     y1 = ROW(y1);
  660.     y2 = ROW(y2+1)-1;
  661.  
  662.     rp = Ep->win->RPort;
  663.  
  664. #ifdef MYDEBUG
  665.     D(bug("scroll_display: rest %ld  height %ld  lines %ld  t %ld (%ld,%ld)-(%ld,%ld)\n",
  666.       rest, height, lines, t, x1, y1, x2, y2));
  667. #endif
  668.  
  669.     SetWrMsk (rp, BLOCK_MASK(Ep));
  670.     SetBPen (rp, TEXT_BPEN(Ep));
  671.  
  672.     if (rest)
  673.     {
  674.     ScrollRaster (rp, dx, dy, x1, y1, x2, y2);
  675.  
  676.     if (dx)
  677.     {
  678.         Line   line;
  679.         Column col;
  680.  
  681.         line = tl;
  682.         col  = lc;
  683.  
  684.         if (dx > 0)
  685.         col += rest;
  686.  
  687.         redraw_block (TRUE, line, col, line + height, col + lines - 1);
  688.     } else
  689.     {
  690.         if (dy < 0)
  691.         {
  692.         text_displayseg (t, lines);
  693.         } else
  694.         {
  695.         text_displayseg (t+rest, lines);
  696.         }
  697.     }
  698.  
  699.     if (Ep->win->WLayer->Flags & LAYERREFRESH)
  700.         OptimizedRefresh (Ep);
  701.     }
  702.     else
  703.     {
  704.     SetAPen (rp, TEXT_BPEN(Ep));
  705.     RectFill (rp, x1, y1, x2, y2);
  706.  
  707.     text_displayseg (t, height);
  708.     }
  709.  
  710.     SetWrMsk (rp, ALL_MASK);
  711. } /* scroll_display */
  712.  
  713.  
  714. Prototype void ScrollAndUpdate (int dx, int dy);
  715.  
  716. void ScrollAndUpdate (int dx, int dy)
  717. {
  718.     RP * rp = Ep->win->RPort;
  719.     Line line;
  720.  
  721.     SetWrMsk (rp, IsBlockVisible () ? BLOCK_MASK(Ep) : TEXT_MASK(Ep));
  722.  
  723.     Ep->topcolumn += dx;
  724.     line = (Ep->topline += dy);
  725.  
  726.     /* if block WAS visible or it is NOW, use blockmask */
  727.     if (IsBlockVisible ())
  728.     SetWrMsk (rp, BLOCK_MASK(Ep));
  729.  
  730.     SetBPen (rp, TEXT_BPEN(Ep));
  731.  
  732.     if (dx < Columns && dy < Lines)
  733.     {
  734.     ScrollRaster (rp, dx*Xsize, dy*Ysize, Xbase, Ybase, Xpixs, Ypixs);
  735.  
  736.     if (dx)
  737.     {
  738.         Column col;
  739.  
  740.         col  = Ep->topcolumn;
  741.  
  742.         if (dx > 0)
  743.         {
  744.         col += Columns - dx;
  745.         dx = Columns;
  746.         }
  747.         else
  748.         dx = -dx;
  749.  
  750.         redraw_block (TRUE, line, col, line + Lines-1, col + dx-1);
  751.     } else
  752.     {
  753.         line = 0;
  754.  
  755.         if (dy < 0)
  756.         dy = -dy;
  757.         else
  758.         line += Lines-dy;
  759.  
  760.         text_displayseg (line, dy);
  761.     }
  762.  
  763.     if (Ep->win->WLayer->Flags & LAYERREFRESH)
  764.         OptimizedRefresh (Ep);
  765.     }
  766.     else
  767.     {
  768.     SetAPen (rp, TEXT_BPEN(Ep));
  769.     RectFill (rp, Xbase, Ybase, Xpixs, Ypixs);
  770.  
  771.     text_displayseg (line, Lines);
  772.     }
  773.  
  774.     SetWrMsk (rp, ALL_MASK);
  775. } /* ScrollAndUpdate */
  776.  
  777.  
  778. Prototype char * skip_whitespace (char * ptr);
  779.  
  780. char * skip_whitespace (char * ptr)
  781. {
  782.     while (isspace (*ptr)) ptr ++;
  783.  
  784.     return (ptr);
  785. } /* skip_whitespace */
  786.  
  787.  
  788. /*
  789.  *  IS_NUMBER
  790.  *  tests if a string represents a valid number, i.e.
  791.  *  if there are only numbers in it ( what about spaces around,
  792.  *  and + before a number, do they disturb atol??? )
  793.  */
  794.  
  795. Prototype char is_number (char * str);
  796.  
  797. char is_number (char * str)
  798. {
  799.     while (*str==' ')           /* ignore leading spaces */
  800.     {
  801.     str++;
  802.     } /* while */
  803.  
  804.     if ((*str=='-')||(*str=='+'))  /* dont worry about +/- */
  805.     {
  806.     str++;
  807.     } /* if */
  808.  
  809.     while (isdigit(*str))     /* if there are only numbers in str: ok */
  810.     {
  811.     str++;
  812.     } /* while */
  813.  
  814.     while (*str==' ')          /* ignore ending spaces */
  815.     {
  816.     str++;
  817.     } /* while */
  818.  
  819.     return ((char)(!*str));
  820. } /* is_number */
  821.  
  822.  
  823. Prototype char * getnextcomline (FILE* fi, int * lineno);
  824.  
  825. char * getnextcomline (FILE* fi, int * lineno)
  826. {
  827.     /* skipps comments and emptylines */
  828.     char* buf;
  829.     char* ptr;
  830.     do
  831.     {
  832.     if (lineno)
  833.     {
  834.         (*lineno)++; /* Welches hat Priortaet?? */
  835.     } /* if */
  836.  
  837.     buf = tmp_buffer;
  838.     if ((xefgets(fi, tmp_buffer, sizeof(tmp_buffer)))<0)
  839.     /* buf = fgets(tmp_buffer, sizeof(tmp_buffer), fi); */
  840.     if (!buf)
  841.     {
  842. DEFMESSAGE( __unexpected_eof, "%s:\nUnexpected End Of File Encountered" )
  843.         error (__unexpected_eof, av[0]);
  844.         return(NULL);
  845.     } /* if */
  846.     buf[sizeof (tmp_buffer)-1] = 0; /* marker for eol */
  847.     while (*buf<33 && *buf)
  848.     {
  849.         buf++;
  850.     } /* while */
  851.     } while (buf[0] == 0 || buf[0] == '#');
  852.     for (ptr = buf; *ptr;ptr++)
  853.     {
  854.     if (*ptr == 10)
  855.     {
  856.         *ptr = 0;
  857.     } /* if */
  858.     } /* for */
  859.     return(buf);
  860. } /* getnextcomline */
  861.  
  862.  
  863. /*
  864.  *  fname
  865.  *
  866.  *  instead of a macro: sets a ptr to the filename of a full path&filename
  867.  *  (returniert einen Zeiger auf den namensteil eines pfades)
  868.  *
  869.  * SHOULD BE PUT INTO SUBS.C
  870.  */
  871.  
  872. Prototype char * fname (char * fullpath);
  873.  
  874. char * fname (char * fullpath)
  875. {
  876.     return ((char *)FilePart (fullpath));
  877. } /* fname */
  878.  
  879.  
  880. Prototype BOOL switch_ed (ED * newed);
  881.  
  882. BOOL switch_ed (ED * newed)
  883. {
  884.     BOOL success;
  885.  
  886.     if (newed)
  887.     {
  888.     if (Ep)
  889.         text_sync ();
  890.  
  891.     Ep = newed;
  892.  
  893.     text_load ();
  894.  
  895.     if (!GETF_ICONMODE(Ep))
  896.     {
  897.         set_window_params ();
  898.         window_title ();
  899.     }
  900.  
  901.     text_cursor (1);
  902.  
  903.     success = TRUE;
  904.     } else
  905.     success = FALSE;
  906.  
  907.     return (success);
  908. } /* switch_ed */
  909.  
  910.  
  911. /*DEFHELP #cmd movement MAKECURSORVISIBLE - Scrolls an oversized screen so the cursor will become visible. */
  912.  
  913. DEFUSERCMD("makecursorvisible", 0, CF_VWM|CF_COK, void, do_makecursorvisible, (void),)
  914. {
  915.     if ((Ep->win->Flags & WFLG_WINDOWACTIVE) && !GETF_ICONMODE(Ep))
  916.     {
  917.     UWORD x1 = COL(Ep->column - Ep->topcolumn) + Ep->win->LeftEdge;
  918.     UWORD y1 = ROW(Ep->line   - Ep->topline)   + Ep->win->TopEdge;
  919.     UWORD x2, y2;
  920.  
  921.     x2 = x1 + (Xsize << 2) + Xsize;
  922.     y2 = y1 + (Ysize << 2) + Ysize;
  923.  
  924.     if (x1 < (Xsize << 2))
  925.         x1 = 0;
  926.     else
  927.         x1 -= Xsize << 2;
  928.  
  929.     if (y1 < (Ysize << 2))
  930.         y1 = 0;
  931.     else
  932.         y1 -= Ysize << 2;
  933.  
  934.     MakeRectVisible (Ep->win, x1, y1, x2, y2);
  935.     }
  936. } /* do_makecursorvisible */
  937.  
  938.  
  939. Prototype void MakeRectVisible (WIN * win, UWORD minx, UWORD miny, UWORD maxx, UWORD maxy);
  940.  
  941. void MakeRectVisible (WIN * win, UWORD minx, UWORD miny, UWORD maxx, UWORD maxy)
  942. {
  943.     struct DimensionInfo diminfo;
  944.     struct Screen      * screen        = win->WScreen;
  945.     ULONG         Width, Height;
  946.     WORD         dx, dy;
  947.  
  948.     GetDisplayInfoData (NULL,
  949.             (UBYTE *)&diminfo,
  950.             sizeof(diminfo),
  951.             DTAG_DIMS,
  952.             GetVPModeID (&screen->ViewPort)
  953.     );
  954.  
  955.     Width  = diminfo.TxtOScan.MaxX - diminfo.TxtOScan.MinX;
  956.     Height = diminfo.TxtOScan.MaxY - diminfo.TxtOScan.MinY;
  957.  
  958.     if (Width > screen->Width)
  959.     Width = screen->Width;
  960.  
  961.     if (Height > screen->Height)
  962.     Height = screen->Height;
  963.  
  964.     if (minx < win->LeftEdge)
  965.     minx = win->LeftEdge;
  966.  
  967.     if (miny < win->TopEdge)
  968.     miny = win->TopEdge;
  969.  
  970.     if (maxx > win->LeftEdge + win->Width)
  971.     maxx = win->LeftEdge + win->Width;
  972.  
  973.     if (maxy > win->TopEdge + win->Height)
  974.     maxy = win->TopEdge + win->Height;
  975.  
  976.     dx = (Width - screen->LeftEdge) - maxx + 1;
  977.  
  978.     if (dx > 0)
  979.     {
  980.     dx = minx + screen->LeftEdge;
  981.  
  982.     if (dx > 0)
  983.         dx = 0;
  984.     else
  985.         dx = -dx;
  986.     }
  987.  
  988.     dy = (Height - screen->TopEdge) - maxy + 1;
  989.  
  990.     if (dy > 0)
  991.     {
  992.     dy = miny + screen->TopEdge;
  993.  
  994.     if (dy >= 0)
  995.         dy = 0;
  996.     else
  997.         dy = -dy;
  998.     }
  999.  
  1000.     MoveScreen (screen, dx, dy);
  1001. } /* MakeRectVisible */
  1002.  
  1003.  
  1004. Prototype int LINELEN (ED * ep, Line nr);
  1005.  
  1006. int LINELEN (ED * ep, Line nr)
  1007. {
  1008.     int len;
  1009.  
  1010.     if (nr == ep->line)
  1011.     {
  1012.     /* line is in Current */
  1013.  
  1014.     if ((len = lastns ((char *)Current)) || (*Current && *Current != ' '))
  1015.         len ++;
  1016.     }
  1017.     else
  1018.     len = strlen (GETTEXT(ep,nr));
  1019.  
  1020.     return (len);
  1021. } /* LINELEN */
  1022.  
  1023.  
  1024. /******************************************************************************
  1025. *****  ENDE subs.c
  1026. ******************************************************************************/
  1027.