home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
word
/
text
/
019
/
screen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
24KB
|
1,038 lines
/*
* Copyright (c) 1992 John E. Davis (davis@amy.tch.harvard.edu)
* All Rights Reserved.
*/
#define JED_VERSION "Jed <0.80> "
#include <stdio.h>
#include <string.h>
#ifndef msdos
#ifndef VMS
#include <malloc.h>
#endif
#else
#include <alloc.h>
#include <dos.h>
extern int Cursor_Row;
#endif
#include "buffer.h"
#include "screen.h"
#include "window.h"
#include "paste.h"
#include "ins.h"
#include "ledit.h"
#include "display.h"
#include "sysdep.h"
#include "misc.h"
#include "vterm.h"
#include "slang.h"
Screen_Type Screen[80];
int Screen_Row = 1;
int Screen_Col = 1;
int Cursor_Motion; /* indicates cursor movement only */
int Scroll_Region_1;
int Scroll_Region_2;
int Scroll_Lines;
int Goal_Column;
int Display_Eight_Bit = 0;
void blank_line(int row)
{
int i, n;
char *p;
n = Window->width;
p = Screen[row].old;
i = 0;
while(i++ < n) *p++ = ' ';
*p = 0;
}
void update_screen_txt(int row)
{
char *tmp;
tmp = Screen[row].new;
Screen[row].new = Screen[row].old;
Screen[row].old = tmp;
}
int output(unsigned char *line, int len, int row, int max_col)
{
int i,ii, visible = 0, ok, quit, tabsize = 8, count, tab, mini_flag,
mark, ebit;
unsigned char ch, *out;
out = (unsigned char *) Screen[row - 1].new;
tab = User_Vars.tab;
i = 0;
ii = 0;
quit = 0;
ok = 0; /* 1 if ok to start filling the out line */
count = 0; /* count counts the visible space */
/* deal with mini_buffer prompt */
if (IS_MINIBUFFER && Mini_Info.prompt_len)
{
if (Screen_Width < Mini_Info.prompt_len)
{
len = 0;
count = Screen_Width;
}
else count = Mini_Info.prompt_len;
mini_flag = 1;
}
else mini_flag = 0;
while (ch = line[i], (i < len) && !quit) /* && ch != '\n' */
{
ebit = 0;
if (tab && (ch == '\t'))
{
tabsize = tab * (count / tab + 1) - count;
count += tabsize;
}
else if ((ch < ' ') || (ch == 127)) count += 2;
else if (Display_Eight_Bit || (ch < 127)) count++;
else if (ch < 160) count += 3;
else if (ch < 255) count += 2;
else count += 3;
if (count >= Window->column) ok = 1;
if (count > max_col) break;
i++;
if (!ok) continue;
if (mini_flag)
{
strncpy((char *) out, Mini_Info.prompt, Screen_Width);
out[Screen_Width] = 0;
visible += (Screen_Width > Mini_Info.prompt_len ? Mini_Info.prompt_len : Screen_Width);
ii = visible;
mini_flag = 0;
}
if (!Display_Eight_Bit && (ch & 0x80))
{
out[ii++] = '~';
visible += 1;
ch = ch & 0x7F;
ebit = 1;
}
if (!ebit && (ch == '\t') && tab)
{
while(tabsize--) out[ii++] = ' ';
}
else if ((ch < ' ') || (ch == 127))
{
out[ii++] = '^';
if (ch == 127) out[ii++] = '?'; else out[ii++] = ch + 'A' - 1;
visible += 2;
}
else if (ch == ' ') out[ii++] = ' ';
else
{
out[ii++] = ch;
visible += 1;
}
}
/* we have not inserted the prompt */
if (mini_flag && !len)
{
strncpy((char *) out, Mini_Info.prompt, Screen_Width);
out[Screen_Width] = 0;
ok = 1;
ii = visible = (Screen_Width > Mini_Info.prompt_len ? Mini_Info.prompt_len : Screen_Width);
}
mark = -1;
if (ok && count >= max_col)
{
out[ii - 1] = '$';
visible++;
}
else
{
if (!ii)
{
out[ii++] = '$';
visible += 1;
}
mark = ii;
while(ii < Window->width) out[ii++] = ' ';
}
out[ii] = '\0';
if (visible)
{
#ifdef msdos
(void) mark;
smart_puts((char *) out,Screen[row-1].old, row);
#else
if (mark != -1) out[mark] = 0;
smart_puts((char *)out,Screen[row-1].old, row);
if (mark != -1) out[mark] = ' ';
#endif
Screen[row-1].n = visible;
}
/* else take care of it in calling routine */
return(visible);
}
void display_line(Line *line, int row)
{
int len;
if (line != NULL)
{
len = line->len;
if (len) if (line->data[len - 1] == '\n') len--;
if ((len > 0) || (Window->column > 1)
|| ((row == Screen_Height) && Mini_Info.prompt_len))
{
len = output(line->data, len, row, Window->column + Window->width - 1);
}
}
else len = 0;
if (len <= 0)
{
if (Screen[row-1].n)
{
goto_rc(row,1);
tt_del_eol();
}
blank_line(row - 1);
Screen[row - 1].n = 0;
}
Screen[row - 1].line = line;
Screen[row - 1].flags = 0;
if (len > 0) update_screen_txt(row-1);
}
void open_scroll(void)
{
Scroll_Region_1 = 1;
Scroll_Region_2 = Screen_Height;
Scroll_Lines = 0;
}
void do_scroll_up(int n)
{
goto_rc(1,1);
tt_delete_nlines(n);
}
void do_scroll_down(int n)
{
goto_rc(1,1);
reverse_index(n);
}
void execute_scroll(void)
{
if (Scroll_Lines > 0)
{
set_scroll_region(Scroll_Region_1, Scroll_Region_2);
do_scroll_up(Scroll_Lines);
}
else if (Scroll_Lines < 0)
{
set_scroll_region(Scroll_Region_1, Scroll_Region_2);
do_scroll_down(-Scroll_Lines);
}
Scroll_Lines = 0;
}
void queue_scroll(int n, int r1, int r2)
{
if ((r1 != Scroll_Region_1) || (r2 != Scroll_Region_2))
{
if ((n == -1) && (Scroll_Region_1 == r1 + Scroll_Lines)
&& (Scroll_Region_2 == r2))
Scroll_Lines--;
else
{
execute_scroll();
Scroll_Region_1 = r1;
Scroll_Region_2 = r2;
Scroll_Lines = n;
}
}
else Scroll_Lines += n;
}
void close_scroll(void)
{
if (Scroll_Lines) execute_scroll();
if ((Scroll_Region_1 != 1) | (Scroll_Region_2 != Screen_Height))
reset_scroll_region();
}
/* Here a scrolling region (t,b) is used to scroll line t + n to t. All
that is assumed is that the line at t + n exists! */
int scroll_up(int n, int t, int b)
{
int i, necess;
if (n == 0) return(0);
/* t = Window->top - 1 + t;
b = Window->top - 1 + b; */
/* check to see if this is really necessary */
necess = 0;
for (i = t - 1; i < b; i++)
{
if (Screen[i].n)
{
necess = 1;
break;
}
}
if (!necess) return(0);
queue_scroll(n, t, b);
vscroll_up(t,b,n);
return(necess);
}
/* Here a scrolling region (t,b) is used to scroll line t + n to t. */
void scroll_down(int n, int t, int b)
{
if (n == 0) return;
/* t = Window->top - 1 + t;
b = Window->top - 1 + b; */
set_scroll_region(t,b);
reverse_index(n);
reset_scroll_region();
vscroll_down(t,b,n);
}
int update_insert_line(int r1, Line *line)
{
int i, r2, r, necess;
Line *bot;
/* normalize r1: */
/* r1 = Window->top - 1 + r1; */
/* find the first one that is blank to delimit the region so that the
loss will be minimal */
r = r1; /* not r1 + 1 as obvious (but naive) as it seems */
r2 = Window->rows + Window->top - 1;
while (r < r2)
{
if (Screen[r - 1].line == NULL) break;
r++;
}
if ((r1 != r2) && (r == r2))
/* we may have failed so check the bottom up so we don't push linesoff. */
{
bot = line;
for (r = r1 + 1; r <= r2; r++)
{
bot = bot->next;
if (bot == NULL) break;
if (Screen[r-1].line == bot) break;
}
if ((bot != NULL) && (r <= r2)) r--;
if (r > r2) r = r2;
}
if (r < r1) r = r1;
r2 = r;
/* check to see if we gain by doing this */
necess = 0;
for (i = r1 - 1; i < r2; i++)
{
if (Screen[i].n)
{
necess = 1;
break;
}
}
if (r1 == r2) return(0);
if (!necess) return(0);
queue_scroll(-1, r1, r2);
vscroll_down(r1, r2, 1);
return(1);
}
Line *find_top()
{
int n, i;
Line *line, *next, *prev, *this;