home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1820.lha
/
XDME
/
subs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-09
|
16KB
|
816 lines
/******************************************************************************
MODUL
subs.c
DESCRIPTION
General subroutines.
NOTES
BUGS
TODO
EXAMPLES
SEE ALSO
INDEX
HISTORY
16. Jan 1993 ada created
******************************************************************************/
/**************************************
Includes
**************************************/
#include "defs.h"
#include <clib/macros.h>
#include <graphics/display.h>
#define MYDEBUG 0
#include "debug.h"
/**************************************
Globale Variable
**************************************/
Prototype void makemygadget (struct Gadget *);
Prototype int firstns (char *);
Prototype int lastns (char *);
Prototype int wordlen (char *);
Prototype Bool getpathto (BPTR, char *, char *);
Prototype void * allocline (long);
Prototype int detab (char *, char *, int);
Prototype int xefgets (FILE *, char *, int);
Prototype ED * finded (char *, int);
Prototype void mountrequest (int);
Prototype FONT * GetFont (char *, short);
Prototype void freeline (LINE);
Prototype void movetocursor (void);
Prototype int extend (ED *, int);
Prototype int makeroom (int);
Prototype void freelist (LINE *, int);
Prototype long lineflags (int);
Prototype void scroll_display (short, short, Column, Line, Column, Line);
Prototype char * skip_whitespace (char *);
Prototype char is_number (char *);
Prototype char * getnextcomline (FILE *, int *);
Prototype char * fname (char *);
Prototype Bool switch_ed (ED *);
Prototype void do_makecursorvisible (void);
Prototype void MakeRectVisible (WIN *, USHORT, USHORT, USHORT, USHORT);
Prototype int LINELEN (ED *, Line);
/* Assembler */
Prototype void swapmem (void *, void *, ULONG);
/**************************************
Interne Defines & Strukturen
**************************************/
typedef struct FileInfoBlock FIB;
/**************************************
Interne Variable
**************************************/
/**************************************
Interne Prototypes
**************************************/
/*
* Create XDME's text icon.
*/
void makemygadget (struct Gadget *gad)
{
const static unsigned short ga[] =
{
/* Plane 0 */
0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0C00,
0x0000,0x0000,0x0000,0x0C00,0x0FFF,0xFFFF,0xFFFF,0x8C00,
0x0C00,0x0000,0x0000,0x0C00,0x0C1F,0xFFFF,0xFFE0,0x0C00,
0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x08BF,0xFFE0,0x0C00,
0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x25FF,0xFFE0,0x0C00,
0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x0BFF,0xFFE0,0x0C00,
0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x1FFF,0xFFE0,0x0C00,
0x0C16,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x7FFF,0xFFE0,0x0C00,
0x0C17,0xFFFF,0xFFA0,0x0C00,0x0800,0x0000,0x0000,0x0C00,
0x0000,0x0000,0x0000,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
0x0031,0x98CE,0x7318,0x0C00,0x001B,0x186F,0xF318,0x0C00,
0x001B,0x186F,0xF360,0x0C00,0x000E,0x186D,0xB3E0,0x0C00,
0x001B,0x186D,0xB360,0x0C00,0x001B,0x186C,0x3318,0x0C00,
0x0031,0x98CC,0x3318,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
/* Plane 1 */
0xFFFF,0xFFFF,0xFFFF,0xF800,0xD555,0x5555,0x5555,0x5000,
0xD555,0x5555,0x5555,0x5000,0xD000,0x0000,0x0000,0x5000,
0xD000,0x0000,0x0000,0xD000,0xD000,0x0000,0x0000,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
0xD003,0xFFFF,0xFF00,0xD000,0xD7FF,0xFFFF,0xFFFF,0xD000,
0xD555,0x5555,0x5555,0x5000,0xD504,0x0041,0x0005,0x5000,
0xD544,0x4511,0x0445,0x5000,0xD544,0x4510,0x0445,0x5000,
0xD544,0x4510,0x0415,0x5000,0xD551,0x4510,0x4415,0x5000,
0xD544,0x4510,0x4415,0x5000,0xD544,0x4511,0x4445,0x5000,
0xD544,0x4511,0x4445,0x5000,0xD504,0x0041,0x0005,0x5000,
0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000
};
const static struct Image image =
{
0, 0, 54, 30, 2, (unsigned short *)ga, 3, 0, NULL
};
clrmem (gad, sizeof(struct Gadget));
gad->Width = 54;
gad->Height = 31; /* Blank line between Image and Text ! */
gad->Flags = GADGIMAGE|GADGHCOMP;
gad->GadgetType = BOOLGADGET;
gad->Activation = RELVERIFY|GADGIMMEDIATE;
gad->GadgetRender = (APTR)ℑ
} /* makemygadget */
/*
* return index of first non space. Returns 0 if no spaces found.
*/
int firstns (char * str)
{
short i;
for (i = 0; str[i] && str[i] == ' '; i ++);
if (str[i] == 0)
i = 0;
return (i);
} /* firstns */
/*
* Return index of last non-space, 0 if no spaces.
*/
int lastns (char * str)
{
short i;
/* get last char of string (i might be -1 after that !).
now walk left until a char != ' ' is found or i == 0. */
for (i = strlen(str) - 1; i > 0 && str[i] == ' '; i --);
if (i < 0) /* string empty */
i = 0;
return (i);
} /* lastns */
/*
* Return length of word under cursor
*/
int wordlen (char * str)
{
short i;
for (i = 0; *str && *str != ' '; ++i, ++str);
return(i);
} /* wordlen */
/*
* Backtracks the program lock, 0 on failure, 1 on success.
* The filename is appended to the lock, if it exists.
*/
Bool getpathto (BPTR lock, char * filename, char * buf)
{
if (!NameFromLock (lock, buf, PATHSIZE))
return (FALSE);
if (filename)
AddPart (buf, filename, PATHSIZE);
return (TRUE);
}
/*
* Allocation routines and other shortcuts
*/
static LINE empty_line = "";
void * allocline (long size)
{
if (size <= 1) return (empty_line); /* no more tiny empty blocks */
/* Make sure we always get a padded block */
size += 7;
size &= ~7;
return (AllocMem (size, 0));
} /* allocline */
void freeline (LINE line)
{
short size;
if (line && line != empty_line)
{
size = strlen (line) + 8;
size &= ~7;
FreeMem (line, size);
}
} /* freeline */
/*
* Remove tabs in a buffer
*/
int detab (char * ibuf, char * obuf, int maxlen)
{
short i, j;
maxlen -= 1;
for (i = j = 0; ibuf[i] && j < maxlen; ++i)
{
if (ibuf[i] == 9)
{
do
{
obuf[j++] = ' ';
} while ((j & 7) && j < maxlen);
} else
{
obuf[j++] = ibuf[i];
}
}
if (j && obuf[j-1] == '\n')
--j;
while (j && obuf[j-1] == ' ')
--j;
obuf[j] = 0;
return (j);
} /* detab */
int xefgets (FILE * fi, char * buf, int max)
{
char ebuf[MAXLINELEN];
if (fgets (ebuf, max, fi))
return (detab (ebuf, buf, max));
return (-1);
} /* xefgets */
ED * finded (char * str, int doff)
{
ED *ed;
for (ed = (ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc((struct Node *)ed))
{
if (strlen (ed->name) >= doff && stricmp (str, ed->name+doff) == 0)
return (ed);
}
return (NULL);
} /* finded */
void mountrequest (int bool)
{
static APTR original_pr_WindowPtr = NULL;
register PROC * proc;
proc = (PROC *)FindTask (0);
if (!bool && proc->pr_WindowPtr != (APTR)-1)
{
original_pr_WindowPtr = proc->pr_WindowPtr;
proc->pr_WindowPtr = (APTR)-1;
}
if (bool && proc->pr_WindowPtr == (APTR)-1)
proc->pr_WindowPtr = original_pr_WindowPtr;
} /* mountrequest */
/*
* GETFONT()
*
* This function properly searches resident and disk fonts for the
* font.
*/
struct Library * DiskfontBase;
FONT * GetFont (char * name, short size)
{
FONT * font1;
TA Ta;
USHORT pos;
strcpy (tmp_buffer, name);
pos = strlen (tmp_buffer);
if (pos < 6 || (pos > 5 && stricmp (tmp_buffer + pos - 5, ".font")))
strcpy (tmp_buffer + pos, ".font");
Ta.ta_Name = (UBYTE *)tmp_buffer;
Ta.ta_YSize = size;
Ta.ta_Style = 0;
Ta.ta_Flags = 0;
font1 = OpenFont (&Ta);
if (!font1 || font1->tf_YSize != Ta.ta_YSize)
{
FONT * font2;
if (DiskfontBase = OpenLibrary ("diskfont.library", 0L))
{
if (font2 = OpenDiskFont (&Ta))
{
if (font1)
CloseFont (font1);
font1 = font2;
CloseLibrary (DiskfontBase);
}
}
} /* if !font1 || Wrong_Font_Size */
return (font1);
} /* GetFont */
void movetocursor (void)
{
Move (Ep->win->RPort, COLT(Ep->column - Ep->topcolumn),
ROWT(Ep->line - Ep->topline));
} /* movetocursor */
int extend (ED * ep, int lines)
{
long extra = ep->maxlines - ep->lines;
LINE * list;
if (lines > extra)
{
lines += ep->lines;
if (list = (LINE *)alloclptr(lines))
{
bmovl (ep->list, list, ep->lines);
FreeMem (ep->list, sizeof(LINE) * ep->maxlines);
ep->maxlines = lines;
ep->list = list;
return (1);
}
nomemory ();
return (0);
}
return (1);
} /* extend */
int makeroom (int n)
{
ED * ep = Ep;
if (ep->lines >= ep->maxlines)
return (extend (ep, n));
return (1);
} /* makeroom */
void freelist (LINE * list, int n)
{
while (n)
{
freeline (list[0]);
list ++;
n --;
}
} /* freelist */
void do_undo (void)
{
text_load ();
text_redisplaycurrline ();
} /* do_undo */
long lineflags (int line)
{
long flags;
if (line < Ep->topline)
flags = LINE_ABOVE;
else if (line < Ep->topline + Lines)
flags = LINE_VISIBLE;
else
flags = LINE_BELOW;
return (flags);
} /* lineflags */
void scroll_display (short dx, short dy, Column lc, Line tl, Column rc, Line bl)
{
ushort width, height;
Line lines, rest;
ushort x1, y1, x2, y2, t;
Line bottom;
Column right;
RP * rp;
/* don't do anything if we are not allowed */
if (Ep->iconmode || Nsu || (!dx && !dy)) return;
/* clip coords */
if (tl < Ep->topline)
tl = Ep->topline;
if (bl >= Ep->topline+Lines)
bl = Ep->topline + Lines - 1;
if (lc < Ep->topcolumn)
lc = Ep->topcolumn;
if (rc >= Ep->topcolumn+Columns)
rc = Ep->topcolumn + Columns - 1;
/* check if area is visible */
if (bl < tl || rc < lc) return;
/* is there something below the text */
if (bl > Ep->lines)
{
bottom = bl - Ep->lines + 1;
} else
{
bottom = 0;
}
/* is there something to the right */
if (rc > MAXLINELEN)
{
right = rc - MAXLINELEN + 1;
} else
{
right = 0;
}
/* get size of real text */
width = rc - lc + 1 - right;
height = bl - tl + 1 - bottom;
if (dx)
{
lines = ABS(dx); /* number of columns to draw */
if (lines >= width)
rest = 0;
else rest = width - lines;
dx *= Xsize;
} else
{
lines = ABS(dy); /* number of lines to draw */
/* if the number of new lines is bigger than the height of the
remaining text, we have to erase the empty lines. Otherwise
we store the first line of the area that is to update in rest. */
if (lines >= height)
rest = 0;
else rest = height - lines;
dy *= Ysize;
}
x1 = lc - Ep->topcolumn;
x2 = rc - Ep->topcolumn;
y1 = tl - Ep->topline;
y2 = bl - Ep->topline;
t = y1;
x1 = COL(x1);
x2 = COL(x2+1)-1;
y1 = ROW(y1);
y2 = ROW(y2+1)-1;
rp = Ep->win->RPort;
#ifdef MYDEBUG
D(bug("scroll_display: rest %ld height %ld lines %ld t %ld (%ld,%ld)-(%ld,%ld)\n",
rest, height, lines, t, x1, y1, x2, y2));
#endif
SetWrMsk (rp, -1);
SetBPen (rp, TEXT_BPEN);
if (rest)
{
ScrollRaster (rp, dx, dy, x1, y1, x2, y2);
if (dx)
{
Line line;
Column col;
line = tl;
col = lc;
if (dx > 0)
col += rest;
redraw_block (TRUE, line, col, line + height, col + lines - 1);
} else
{
if (dy < 0)
{
text_displayseg (t, lines);
} else
{
text_displayseg (t+rest, lines);
}
}
} else
{
SetAPen (rp, TEXT_BPEN);
RectFill (rp, x1, y1, x2, y2);
text_displayseg (t, height);
}
} /* scroll_display */
char * skip_whitespace (char * ptr)
{
while (isspace (*ptr)) ptr ++;
return (ptr);
} /* skip_whitespace */
/*
* IS_NUMBER
* tests if a string represents a valid number, i.e.
* if there are only numbers in it ( what about spaces around,
* and + before a number, do they disturb atol??? )
*/
char is_number (char * str) /* represents a string a number? */
{
while (*str==' ') /* ignore leading spaces */
{
str++;
} /* while */
if ((*str=='-')||(*str=='+')) /* dont worry about +/- */
{
str++;
} /* if */
while (isdigit(*str)) /* if there are only numbers in str: ok */
{
str++;
} /* while */
while (*str==' ') /* ignore ending spaces */
{
str++;
} /* while */
return (!*str);
} /* is_number */
char * getnextcomline (FILE* fi, int * lineno)
{
/* skipps comments and emptylines */
char* buf;
char* ptr;
do
{
if (lineno)
{
(*lineno)++; /* Welches hat Priortaet?? */
} /* if */
buf = tmp_buffer;
if ((xefgets(fi, tmp_buffer, LINE_LENGTH))<0)
/* buf = fgets(tmp_buffer, LINE_LENGTH, fi); */
if (!buf)
{
error ("%s:\nUnexpected End Of File Encountered", av[0]);
return(NULL);
} /* if */
buf[255] = 0; /* marker for eol */
while (*buf<33 && *buf)
{
buf++;
} /* while */
} while (buf[0] == 0 || buf[0] == '#');
for (ptr = buf; *ptr;ptr++)
{
if (*ptr == 10)
{
*ptr = 0;
} /* if */
} /* for */
return(buf);
} /* getnextcomline */
/*
* fname
*
* instead of a macro: sets a ptr to the filename of a full path&filename
* (returniert einen Zeiger auf den namensteil eines pfades)
*
* SHOULD BE PUT INTO SUBS.C
*/
char * fname (char * fullpath)
{
return (FilePart (fullpath));
} /* fname */
Bool switch_ed (ED * newed)
{
Bool success;
if (newed)
{
if (Ep)
text_sync ();
Ep = newed;
text_load ();
if (!Ep->iconmode)
{
set_window_params ();
window_title ();
}
text_cursor (1);
success = TRUE;
} else
success = FALSE;
return (success);
} /* switch_ed */
void do_makecursorvisible (void)
{
if ((Ep->win->Flags & WFLG_WINDOWACTIVE) && !Ep->iconmode)
{
USHORT x1 = COL(Ep->column - Ep->topcolumn) + Ep->win->LeftEdge;
USHORT y1 = ROW(Ep->line - Ep->topline) + Ep->win->TopEdge;
USHORT x2, y2;
x2 = x1 + (Xsize << 2) + Xsize;
y2 = y1 + (Ysize << 2) + Ysize;
if (x1 < (Xsize << 2))
x1 = 0;
else
x1 -= Xsize << 2;
if (y1 < (Ysize << 2))
y1 = 0;
else
y1 -= Ysize << 2;
MakeRectVisible (Ep->win, x1, y1, x2, y2);
}
} /* do_makecursorvisible */
void MakeRectVisible (WIN * win, USHORT minx, USHORT miny, USHORT maxx,
USHORT maxy)
{
struct DimensionInfo diminfo;
struct Screen * screen = win->WScreen;
ULONG Width, Height;
WORD dx, dy;
GetDisplayInfoData (NULL,
(UBYTE *)&diminfo,
sizeof(diminfo),
DTAG_DIMS,
GetVPModeID (&screen->ViewPort)
);
Width = diminfo.TxtOScan.MaxX - diminfo.TxtOScan.MinX;
Height = diminfo.TxtOScan.MaxY - diminfo.TxtOScan.MinY;
if (Width > screen->Width)
Width = screen->Width;
if (Height > screen->Height)
Height = screen->Height;
if (minx < win->LeftEdge)
minx = win->LeftEdge;
if (miny < win->TopEdge)
miny = win->TopEdge;
if (maxx > win->LeftEdge + win->Width)
maxx = win->LeftEdge + win->Width;
if (maxy > win->TopEdge + win->Height)
maxy = win->TopEdge + win->Height;
dx = (Width - screen->LeftEdge) - maxx + 1;
if (dx > 0)
{
dx = minx + screen->LeftEdge;
if (dx > 0)
dx = 0;
else
dx = -dx;
}
dy = (Height - screen->TopEdge) - maxy + 1;
if (dy > 0)
{
dy = miny + screen->TopEdge;
if (dy >= 0)
dy = 0;
else
dy = -dy;
}
MoveScreen (screen, dx, dy);
} /* MakeRectVisible */
int LINELEN (ED * ep, Line nr)
{
int len;
if (nr == ep->line)
{
/* line is in Current */
if ((len = lastns ((char *)Current)) || (*Current && *Current != ' '))
len ++;
}
else
len = strlen (GETTEXT(ep,nr));
return (len);
} /* LINELEN */
/******************************************************************************
***** ENDE subs.c
******************************************************************************/