home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1820.lha
/
XDME
/
cursor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-08
|
21KB
|
1,217 lines
/******************************************************************************
MODUL
cursor.c
DESCRIPTION
All routines that only move the cursor.
NOTES
BUGS
TODO
EXAMPLES
SEE ALSO
INDEX
HISTORY
04. Oct 1992 ada created
******************************************************************************/
/**************************************
Includes
**************************************/
#include <defs.h>
/**************************************
Globale Variable
**************************************/
Prototype void do_up (void);
Prototype void do_scrolldown (void);
Prototype void do_scrollup (void);
Prototype void do_down (void);
Prototype void do_page (void);
Prototype void do_downadd (void);
Prototype void do_left (void);
Prototype void do_right (void);
Prototype void do_tab (void);
Prototype void do_backtab (void);
Prototype void do_top (void);
Prototype void do_bottom (void);
Prototype void do_firstcolumn (void);
Prototype void do_firstnb (void);
Prototype void do_lastcolumn (void);
Prototype void do_goto (void);
Prototype void do_screentop (void);
Prototype void do_screenbottom (void);
Prototype void do_wleft (void);
Prototype void do_wright (void);
Prototype void do_col (void);
Prototype void do_scroll (int);
Prototype void do_match (void);
Prototype void do_ping (void);
Prototype void do_pong (void);
Prototype void do_undo (void);
Prototype int get_pong (int);
Prototype void escapecomlinemode (void);
Prototype void do_esc (void);
Prototype void do_recall (void);
Prototype void markerkill (ED *);
Prototype char * HistoBuff[];
Prototype short NumHistoLines;
Prototype short HistoLine;
/**************************************
Interne Defines & Strukturen
**************************************/
/**************************************
Interne Variable
**************************************/
static struct TextMarker marker[PINGDEPTH];
/* TODO: replace define by function for infinite history */
#define MaxHistoLines 40
/* HistoBuff is filled [0..NumHistoLines-1], NumHistoLines is in
[0..MaxHistoLines], HistoLine is in [0..NumHistoLines]. If NumHistoLines
is 0, then the HistoryBuffer is empty. */
char * HistoBuff[MaxHistoLines];
short NumHistoLines;
short HistoLine;
/**************************************
Interne Prototypes
**************************************/
void do_up (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
if (!globalflags.Comlinemode)
{
if (ep->line)
{
text_sync ();
ep->line --;
text_load ();
if (Ep->line < Ep->topline)
{
ep->topline --;
scroll_display (0, -1, ep->topcolumn, ep->topline,
ep->topcolumn + Columns, ep->topline + Lines);
}
} else
{
globalflags.Abortcommand = 1;
}
} else
{
if (HistoLine)
{
HistoLine --;
strcpy (Current, HistoBuff[HistoLine]);
ep->column = Clen = strlen (Current);
text_redisplaycurrline ();
}
}
} /* do_up */
void do_scrolldown (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
if (ep->topline + Lines < ep->lines)
{
text_sync ();
ep->topline ++;
ep->line ++;
text_load ();
scroll_display (0, 1, ep->topcolumn, ep->topline,
ep->topcolumn + Columns - 1, ep->topline + Lines - 1);
} else
globalflags.Abortcommand = 1;
} /* do_scrolldown */
void do_scrollup (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
if (ep->topline)
{
text_sync ();
ep->topline --;
ep->line --;
text_load ();
scroll_display (0, -1, ep->topcolumn, ep->topline,
ep->topcolumn + Columns - 1, ep->topline + Lines - 1);
} else
globalflags.Abortcommand = 1;
} /* do_scrollup */
void do_down (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
if (!globalflags.Comlinemode)
{
if (ep->line + 1 < ep->lines)
{
text_sync ();
ep->line ++;
text_load ();
if (ep->line - ep->topline >= Lines)
{
ep->topline ++;
scroll_display (0, 1, ep->topcolumn, ep->topline,
ep->topcolumn + Columns, ep->topline + Lines);
}
} else
globalflags.Abortcommand = 1;
} else
{ /* Comlinemode */
if (HistoLine < NumHistoLines)
{
HistoLine ++;
if (HistoLine != NumHistoLines)
strcpy (Current, HistoBuff[HistoLine]);
else
*Current = 0;
ep->column = Clen = strlen (Current);
text_redisplaycurrline ();
}
} /* if (!Comlinemode) */
} /* do_down */
/*
PAGEUP
PAGEDOWN
PAGELEFT
PAGERIGHT
PAGESET n (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
can be > 100.
*/
void do_page (void)
{
ED * ep = Ep;
ushort n,
t;
switch(av[0][4])
{
case 'u':
if (!ep->topline && !ep->line) return;
text_sync ();
if (ep->line != ep->topline)
{
ep->line = ep->topline;
text_load ();
return;
}
n = Lines * PageJump / 100;
if (ep->topline < n)
n = ep->topline;
ep->line -= n;
ep->topline -= n;
text_load ();
if (!Nsu)
scroll_display (0, -n, 0, ep->topline, MAXLINELEN,
ep->topline + Lines);
break;
case 'd':
if (ep->topline + Lines >= ep->lines &&
ep->line == ep->lines -1)
return;
text_sync ();
if (ep->line != ep->topline + Lines -1)
{
ep->line = ep->topline + Lines -1;
if (ep->line >= ep->lines)
ep->line = ep->lines -1;
text_load ();
return;
}
n = Lines * PageJump / 100;
ep->line += n;
ep->topline += n;
if (ep->line >= ep->lines)
ep->line = ep->lines - 1;
text_load ();
if (!Nsu)
scroll_display (0, n, 0, ep->topline, MAXLINELEN,
ep->topline + Lines);
break;
case 'l':
if (!ep->topcolumn && !ep->column) return;
t = firstns (Current);
if (ep->column != ep->topcolumn)
{
if (t > ep->topcolumn && ep->column != t)
ep->column = t;
else
ep->column = ep->topcolumn;
text_sync ();
return;
}
n = Columns * PageJump / 100;
if (ep->topcolumn < n)
n = ep->topcolumn;
if (t < ep->column && t > ep->column - n)
ep->column = t;
else
ep->column -= n;
ep->topcolumn -= n;
text_sync ();
if (!Nsu)
scroll_display (-n, 0, 0, ep->topline, MAXLINELEN,
ep->topline + Lines);
break;
case 'r':
if (ep->topcolumn + Columns >= MAXLINELEN &&
ep->column == MAXLINELEN-1)
return;
text_sync ();
t = LINELEN(ep,ep->line);
if (ep->column != ep->topcolumn + Columns -1)
{
if (t < ep->topcolumn + Columns && t != ep->column)
ep->column = t;
else
ep->column = ep->topcolumn + Columns -1;
if (ep->column >= MAXLINELEN)
ep->column = MAXLINELEN - 1;
text_sync ();
return;
}
n = Columns * PageJump / 100;
if (t > ep->column && t < ep->column + n)
ep->column = t;
else
ep->column += n;
ep->topcolumn += n;
if (ep->column >= MAXLINELEN)
ep->column = MAXLINELEN - 1;
text_sync ();
if (!Nsu)
scroll_display (n, 0, 0, ep->topline, MAXLINELEN,
ep->topline + Lines);
break;
case 's':
PageJump = atoi ((char *)av[1]);
if (PageJump > 100)
PageJump = 100;
else if (PageJump < 1)
PageJump = 1;
break;
}
} /* do_page */
void do_downadd (void)
{
ED * ep = Ep;
ubyte * ptr;
if (ep->line + 1 == ep->lines)
{
ep->modified = 1;
if (makeroom (32))
{
ptr = allocline (1);
SETLINE(ep,ep->lines) = ptr;
ep->lines ++;
} else
{
nomemory ();
}
}
do_down ();
} /* do_downadd */
void do_left (void)
{
ED * ep = Ep;
if (ep->column)
{
ep->column --;
if (ep->column < ep->topcolumn)
text_adjust (FALSE);
} else
globalflags.Abortcommand = 1;
} /* do_left */
void do_right (void)
{
ED * ep = Ep;
if (ep->column != 254)
{
if (Current[ep->column] == 0)
{
Current[ep->column] = ' ';
Current[ep->column+1]= '\0';
Clen ++;
}
ep->column ++;
if (ep->column - ep->topcolumn >= Columns)
text_adjust (FALSE);
} else
globalflags.Abortcommand = 1;
} /* do_right */
void do_tab (void)
{
short n;
ED * ep = Ep;
/* TODO */
for (n=ep->config.tabstop-(ep->column % ep->config.tabstop); n>0; n--)
do_right ();
} /* do_tab */
void do_backtab (void)
{
short n;
ED * ep = Ep;
n = ep->column % ep->config.tabstop;
if (!n)
n = ep->config.tabstop;
/* TODO */
for (; n > 0; --n)
do_left ();
} /* do_backtab */
void do_top (void)
{
text_sync ();
Ep->line = 0;
text_load ();
text_adjust (FALSE);
} /* do_top */
void do_bottom (void)
{
text_sync ();
Ep->line = Ep->lines - 1;
text_load ();
text_adjust (FALSE);
} /* do_bottom */
void do_firstcolumn (void)
{
if (Ep->column)
{
Ep->column = 0;
text_adjust (FALSE);
}
} /* do_firstcolumn */
void do_firstnb (void)
{
for (Ep->column = 0; Current[Ep->column] == ' '; Ep->column ++);
if (Current[Ep->column] == 0)
Ep->column = 0;
text_adjust (FALSE);
} /* do_firstnb */
void do_lastcolumn (void)
{
short i;
text_sync ();
i = (globalflags.Comlinemode) ? Clen : LINELEN(Ep,Ep->line);
if (i != Ep->column)
{
Ep->column = i;
text_adjust (FALSE);
}
} /* do_lastcolumn */
/*
* GOTO [+/-]N
* GOTO BLOCK start of block
* GOTO START start of block
* GOTO END end of block
*/
void do_goto (void)
{
long n,
i;
char * ptr = (char *)av[1];
i = 0;
n = -1;
switch (*ptr)
{
case 'b':
case 's':
n = -1;
if (ActualBlock.type != BT_NONE && Ep == ActualBlock.ep)
n = ActualBlock.start_line;
break;
case 'e':
n = -1;
if (ActualBlock.type != BT_NONE && Ep == ActualBlock.ep)
n = ActualBlock.end_line;
break;
case '+':
i = 1;
case '-':
n = Ep->line;
default:
n += atoi(ptr+i);
} /* switch (*ptr) */
if (n >= Ep->lines)
n = Ep->lines - 1;
if (n < 0)
{
error ("goto:\nCannot go to\nline `%s'", av[1]);
} else
{
text_sync ();
Ep->line = n;
text_load ();
text_adjust (FALSE);
}
} /* do_goto */
void do_screentop (void)
{
text_sync ();
Ep->line = Ep->topline;
text_load ();
text_adjust (FALSE);
} /* do_screentop */
void do_screenbottom (void)
{
text_sync ();
Ep->line = Ep->topline + Lines - 1;
if (Ep->line < 0 || Ep->line >= Ep->lines)
Ep->line = Ep->lines - 1;
text_load ();
text_adjust (FALSE);
} /* do_screenbottom */
void do_wleft ()
{
ED * ep = Ep;
int i;
for (;;)
{
i = ep->column;
if (i == 0)
goto prevline;
i --;
while (i && Current[i] == ' ')
i --;
if (i == 0 && Current[0] == ' ')
{
prevline:
if (globalflags.Comlinemode || ep->line == 0)
{
i = ep->column;
break;
}
text_sync ();
ep->line --;
text_load ();
ep->column = Clen;
continue;
} /* while !SOL && isspace(Current[i]) */
while (i && Current[i] != ' ')
i --;
if (Current[i] == ' ')
i ++;
break;
} /* forever */
ep->column = i;
text_adjust (FALSE);
} /* do_wleft */
void do_wright()
{
ED * ep = Ep;
int i;
for (;;)
{
i = ep->column;
if (i == Clen)
goto nextline;
while (i != Clen && Current[i] != ' ') /* skip past current word */
i ++;
while (i != Clen && Current[i] == ' ') /* to beg. of next word */
i ++;
if (i == Clen)
{
nextline:
if (globalflags.Comlinemode || ep->line == ep->lines - 1)
{
i = ep->column;
break;
}
text_sync ();
ep->line ++;
text_load ();
ep->column = i = 0;
if (Current[0] != ' ')
break;
continue;
}
break;
} /* forever */
ep->column = i;
text_adjust (FALSE);
} /* do_wright() */
void do_col (void)
{
int col;
char * ptr = (char *)av[1];
switch(*ptr)
{
case '+':
col = text_colno() + atoi(ptr + 1);
if (col > 254)
col = 254;
break;
case '-':
col = text_colno() + atoi(ptr);
if (col < 0)
col = 0;
break;
default:
col = atoi(ptr) - 1;
break;
}
if (col > 254 || col < 0)
{
globalflags.Abortcommand = 1;
return;
}
while (Clen < col)
Current[Clen ++] = ' ';
Current[Clen] = 0;
Ep->column = col;
text_adjust (FALSE);
} /* do_col */
void do_scroll (int dir) /* SCROLLLEFT SCROLLRIGHT */
{
ED * ep = Ep;
ushort step = 4;
if (Nsu)
return;
if (dir == -1)
if (av[0][6] == 'l')
dir = SCROLL_LEFT;
else
dir = SCROLL_RIGHT;
if (dir == SCROLL_LEFT)
{
if (!ep->topcolumn)
{
globalflags.Abortcommand = 1;
return;
}
if (ep->topcolumn < step)
step = ep->topcolumn;
} else if (dir == SCROLL_RIGHT)
{
if ((ep->topcolumn + Columns) >= MAXLINELEN)
{
globalflags.Abortcommand = 1;
return;
}
if ((ep->topcolumn + Columns + step) >= MAXLINELEN)
step = MAXLINELEN - (ep->topcolumn + Columns);
}
if (dir == SCROLL_LEFT)
{
ep->topcolumn -= step;
ep->column -= step;
} else
{
ushort end;
/* fill Current with spaces */
end = ep->column + step;
for ( ; Clen<end; Clen++)
Current[Clen] = ' ';
Current[Clen] = 0;
ep->topcolumn += step;
ep->column += step;
}
scroll_display ((dir == SCROLL_LEFT ? -step : step), 0,
ep->topcolumn, ep->topline,
ep->topcolumn + Columns, ep->topline + Lines);
} /* do_scroll */
void do_match (void)
{
char dec, /* char that indicates a "level_down" */
inc; /* -""- "level_up" */
char * line; /* contents of the actual line */
short pos; /* position in that line */
short dir; /* direction of search */
long linnr; /* actual line-number */
short level; /* "level" */
/* set start values */
pos = Ep->column;
line = Current;
linnr = Ep->line;
inc = line[pos];
/* Check for a known paren and select the search-direction accordingly. */
switch (inc)
{
case '{':
dir = 1;
dec = '}';
break;
case '}':
dir = -1;
dec = '{';
break;
case '[':
dir = 1;
dec = ']';
break;
case ']':
dir = -1;
dec = '[';
break;
case '(':
dir = 1;
dec = ')';
break;
case ')':
dir = -1;
dec = '(';
break;
case '`':
dir = 1;
dec = '\'';
break;
case '\'':
dir = -1;
dec = '`';
break;
default:
dir = 0;
break;
}
/* if there is no known paren, return */
if (!dir)
return;
/* we start with level 0. Since we ARE on a paren, this is increased soon */
level = 0;
for (;;)
{
if (line[pos] == inc)
{ /* check for "inc-char" */
level ++;
} else
{
if (line[pos] == dec)
{ /* dito */
level --;
/* if we have reached the start-level, we are through */
if (!level)
break;
}
}
/* next pos */
pos += dir;
if (pos <= 0)
{
do
{
if (!linnr)
{
warn ("match: No matching paren");
return;
}
linnr --;
line = GETTEXT(Ep,linnr);
pos = strlen (line);
if (pos)
{
pos --;
break;
}
} while (!pos);
} else if (!line[pos])
{
linnr ++;
if (linnr >= Ep->lines)
{
warn ("match: No matching paren");
return;
}
line = GETTEXT(Ep,linnr);
pos = 0;
}
}
text_sync ();
if (linnr >= Ep->lines)
linnr = Ep->lines - 1;
Ep->line = linnr;
Ep->column = pos;
text_load ();
text_adjust (FALSE);
} /* do_match */
void do_ping (void)
{
uword num = atoi (av[1]);
if (num >= PINGDEPTH)
{
error ("ping:\n%ld out of range\n(max %ld)", num, PINGDEPTH);
return;
}
marker[num].ep = Ep;
marker[num].column = Ep->column;
marker[num].line = Ep->line;
title ("Position marked");
} /* do_ping */
void do_pong (void)
{
short num = atoi (av[1]);
text_sync ();
if (num < 0 || num >= PINGDEPTH || !marker[num].ep)
{
error ("pong:\nrange error or\nyet nothing marked");
return;
}
text_cursor (1);
switch_ed (marker[num].ep);
text_cursor (0);
if (IntuitionBase->ActiveWindow != Ep->win)
{
WindowToFront (Ep->win);
ActivateWindow (Ep->win);
}
if ((Ep->line = marker[num].line) >= Ep->lines)
{
marker[num].line = Ep->line = Ep->lines - 1;
}
Ep->column = marker[num].column;
text_load ();
text_adjust (FALSE);
} /* do_pong */
int get_pong (int num)
{
if (num < 0 || num >= PINGDEPTH || !marker[num].ep)
{
return (-1);
}
if (marker[num].line >= Ep->lines)
return (marker[num].line = Ep->lines-1);
return (marker[num].line);
} /* get_pong */
/*
* esc, escimm
*/
int Savetopline, Savecolumn, Savetopcolumn;
void do_recall (void)
{
av[0] = "escimm";
/* Copy last Histoline if possible */
if (NumHistoLines)
av[1] = HistoBuff[NumHistoLines - 1];
else
av[1] = "";
do_esc ();
if (NumHistoLines)
HistoLine --;
} /* do_recall */
void do_esc (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
short y;
if (globalflags.Comlinemode)
{
escapecomlinemode ();
return;
} else
{ /* PATCH_NULL added */
esc_partial = Partial; /* PATCH_NULL added */
Partial = NULL; /* PATCH_NULL added */
}
text_sync ();
if (av[0][3] == 'i')
strcpy ((char *)Current, (char *)av[1]);
else
Current[0] = 0;
Clen = strlen ((char *)Current);
globalflags.Comlinemode = 1;
/* returnoveride (1); */ /* PATCH_NULL [25 Jan 1993] : commented out */
Savetopline = ep->topline;
Savecolumn = ep->column;
Savetopcolumn = ep->topcolumn;
ep->column = Clen;
if (ep->column < Lines)
ep->topcolumn = 0;
else
{
ep->topcolumn = Clen - Lines;
}
ep->topline = ep->line - Lines + 1;
y = ROW (Lines-1);
SetAPen (rp, TEXT_BPEN);
SetWrMsk (rp, -1);
RectFill (rp, COL(0), y, Xpixs, Ypixs);
y --;
SetAPen (rp, TEXT_FPEN);
RectFill (rp, COL(0), y, Xpixs, y);
text_displayseg (Lines - 1, 1);
HistoLine = NumHistoLines;
} /* do_esc */
void escapecomlinemode (void)
{
ED * ep = Ep;
RP * rp = ep->win->RPort;
char * ptr;
if (esc_partial)
{ /* PATCH_NULL P -> esc_p */
free(esc_partial); /* PATCH_NULL P -> esc_p */
esc_partial = NULL; /* PATCH_NULL P -> esc_p */
}
if (globalflags.Comlinemode)
{
/* Don't add empty lines */
if (*Current)
{
ptr = Current + strlen (Current) -1;
while (*ptr == ' ' && ptr != (char *)Current)
ptr --;
/* Set string-end after last char. Note that this code
removes histo-lines with length 1 (single chars) */
if (ptr != (char *)Current)
ptr ++;
*ptr = 0;
}
/* If we are somewhere above and we didn't change anything,
we won't add a new history-line */
/* If there is something to add */
if (!(HistoLine != NumHistoLines && !strcmp (Current,
HistoBuff[HistoLine])) && *Current)
{
/* Check if buffer is full */
if (NumHistoLines == MaxHistoLines)
{
/* Free oldest line and shift buffer */
free (HistoBuff[0]);
movmem (HistoBuff + 1, HistoBuff,
sizeof (char *) * (MaxHistoLines - 1));
/* We have now space for one line */
NumHistoLines --;
}
/* Allocate new line */
ptr = malloc (strlen (Current) + 1);
/* Copy new line if possible. Note that even if malloc()
failed we don't loose information. */
if (ptr)
{
strcpy (ptr, (char *)Current);
/* Add line. At this point, NumHistoLines is ALWAYS
less than MaxHistoLines ! */
HistoBuff[NumHistoLines ++] = ptr;
}
}
globalflags.Comlinemode = 0;
/* returnoveride (0); */ /* PATCH_NULL [25 Jan 1993] : commented out */
ep->topline = Savetopline;
ep->column = Savecolumn;
ep->topcolumn = Savetopcolumn;
text_load ();
SetAPen (rp, TEXT_BPEN);
SetWrMsk (rp, -1);
RectFill (rp, COL(0), ROW(Lines-1)-1, Xpixs, Ypixs);
SetAPen (rp, TEXT_FPEN);
text_displayseg (Lines - 2, 2);
}
} /* escapecomlinemode */
void markerkill (ED * ep)
{
short i;
for (i = 0; i < PINGDEPTH; ++i)
{ /* remove ping-pong marks */
if (marker[i].ep == ep)
marker[i].ep = NULL;
}
} /* markerkill */
/******************************************************************************
***** ENDE cursor.c
******************************************************************************/